Kubernetes Pod的管理与使用详解

Kubernetes Pod的管理与使用详解

_

Pod的管理与使用

一、Pod基本概念

1. Pod概述

Pod由一个或多个紧密耦合的容器组成,它们之间共享网络、存储等资源。Pod是Kubernetes的最小工作单元,每个Pod包含一个或多个容器。Pod中的容器会作为一个整体被Master调度到一个Node上运行。

1.1 只包含一个应用容器的Pod

“一个pod一个容器”的模式是Kubernetes中主流的使用场景。在这种场景中,pod可以被看做是一个“有外壳”的容器,Kubernetes不能直接管理容器,而是需要通过管理Pod间接管理容器。

1.2 包含多个应用容器的Pod

仅当两种容器紧耦合,且需要共享相同的资源时才使用这一种模式。这些在一个Pod内的容器形成一个统一的服务单元。典型场景:一个容器通过共享卷提供文件资源,另一容器负责资源刷新与更新。Pod可将这类关联容器及存储资源,整合为单一可管理实体统一调度运维。

2. K8s引入Pod的目的

2.1 可管理性

部分业务容器天然需要紧密协作、协同运行,Pod提供了高于单个容器的抽象层级,将关联容器封装为统一部署单元。Kubernetes以Pod为最小调度、扩缩容、资源分配和生命周期管理单位,简化集群编排运维。

2.2 通信和资源共享

Pod中的所有容器使用同一个网络namespace,也就是相同的IP地址和Port空间。它们能够直接使用localhost通信,同时这些容器也可以共享存储。当Kubernetes挂载volume到Pod,本质是将volume挂载到Pod中的每一个容器。

3. 根容器

根容器(Pause容器/Infra容器)是Kubernetes为每个Pod自动创建的特殊容器,不运行业务逻辑,仅负责支撑Pod运行环境。Pause容器的状态代表整个pod的状态,是Pod内所有业务容器的“父容器”。

通俗一点解释,Pause容器是Pod的地基,只负责稳住网络、统一命名空间、管理进程、共享存储,让业务容器稳定协作。

3.1 核心特点

  • 默认镜像:极简镜像,仅几百KB

  • 自动创建:无需在YAML中定义,kubelet会在创建Pod时优先启动Pause容器。

  • 生命周期:与Pod绑定,业务容器重启不会影响Pause容器,Pod IP始终稳定。

[Step1] 可以通过查看kubelet启动参数找到使用根容器镜像。

root@k8s-master:~# ps -ef | grep kubelet | grep pod-infra-container-image

4. Pod生命周期

Pod拥有固定的生命周期流转机制,初始为“Pending”状态。若至少一个主容器成功启动,则进入“Running”状态。运行结束后,根据容器是否异常退出而进入“Succeeded”正常终止状态或“Failed”异常终止状态。此外,如果集群节点发生网络故障、管理端无法正常获取Pod运行状态时,Pod会出现“Unknown”状态。

二、Pod的基本操作

1. 通过YAML声明式创建单容器Pod

[Step1] 本地新建YAML清单,定义Pod资源描述模板。

root@k8s-master:~# vim nginx-pod.yml
​
# 写入下列内容
apiVersion: v1      # 固定配置
kind: Pod           # 资源类型
metadata:
  name: nginx-pod       # Pod的名称
spec:
  containers:
    - name: nginx       # 容器名称
      image: nginx:latest               # 容器镜像名称
      imagePullPolicy: IfNotPresent     # 优先使用本地镜像,不存在则联网拉取

[Step2] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f nginx-pod.yml

[Step3] 验证:获取当前命名空间下所有Pod资源的运行状态与简要信息。

root@k8s-master:~# kubectl get pod

[Step4] 验证:通过添加“-o wide”参数查看更详细信息。

# [-o]是[--output]的缩写形式
root@k8s-master:~# kubectl get pod -o wide
root@k8s-master:~# kubectl get pod --output wide

2. 通过命令创建单容器Pod

[Step1] 通过命令直接创建Pod。

root@k8s-master:~# kubectl run nginx-pod2 --image=nginx:latest --image-pull-policy=IfNotPresent

[Step2] 验证:获取当前命名空间下所有Pod资源的运行状态与简要信息。

root@k8s-master:~# kubectl get pod

3. 通过YAML声明式创建多容器Pod

[Step1] 本地手动编写YAML文件时,可以通过“-”清晰区分多个容器。YAML中以“-”作为起始标记,从当前“-”开始,到下一个“-”出现之前的所有配置参数,都属于同一个容器。每出现一个“-”,代表定义了一个新容器。

root@k8s-master:~# vim more-web-pod.yml
​
# 写入下列内容
apiVersion: v1      # 固定配置
kind: Pod           # 资源类型
metadata:
  name: more-web-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 8080       # 指定端口号,避免出现冲突
    - name: php
      image: php:latest
      imagePullPolicy: IfNotPresent
      command: ["sleep","infinity"]

[Step2] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f more-web-pod.yml

[Step3] 验证:获取当前命名空间下所有Pod资源的运行状态与简要信息。

root@k8s-master:~# kubectl get pod

4. 删除Pod

[Step1] 通过子命令“delete”删除指定Pod。

root@k8s-master:~# kubectl delete pod nginx-pod2

5. 查看Pod完整信息

[Step1] 可以通过子命令“describe”查看Pod的详细信息,特别是Pod状态出现异常时,可以重点关注“Event”字段。

root@k8s-master:~# kubectl describe pod nginx-pod

6. 进入单容器Pod

[Step1] 单容器Pod内部仅运行一个业务容器,因此无需额外指定容器名称,可以直接通过Pod名称进入容器。

root@k8s-master:~# kubectl exec -it nginx-pod -- /bin/sh
  • kubectl exec:进入容器执行命令

  • -it:交互式进入容器

  • --:分隔符,后面的内容不被当作kubectl的参数,直接在容器中运行

  • /bin/sh:启动shell命令行

7. 进入多容器Pod

[Step1] 当一个Pod中存在多个业务容器时,需要使用“--container”指定容器名称,从而进入目标容器。

# "--container"可以简写为"-c"
root@k8s-master:~# kubectl exec -it more-web-pod --container nginx -- /bin/sh
root@k8s-master:~# kubectl exec -it more-web-pod --container php -- /bin/sh

8. Pod容器定位

[Step1] 通过添加“-o wide”参数可以查看Pod详细部署信息,精准定位节点位置。根据输出可以看到,“more-web-pod”运行在“k8s-worker2”节点,“nginx-pod”运行在“k8s-worker1”节点。

root@k8s-master:~# kubectl get pod -o wide

[Step2] 登录到k8s-worker1上列出当前正在运行的容器,能够看到nginx。

root@k8s-worker1:~# crictl ps

9. 临时创建Pod

[Step1] 使用busybox镜像临时创建一个名为demopod的容器,直接进入容器交互终端,退出后自动删除这个Pod。

root@k8s-master:~# kubectl run --rm --image busybox:latest --image-pull-policy IfNotPresent -it demopod
  • kubectl run:快速创建并运行一个Pod

  • --rm:退出后自动删除Pod

  • --image:指定容器使用的镜像

  • --image-pull-policy IfNotPresent:如果本地节点已经有这个镜像,就不再去网上拉取

三、特殊类型

1. Init类型容器

在Pod中存在一类特殊容器,Init容器是在业务容器启动前先执行的临时容器,执行完成后就退出,不会常驻运行,主要用来完成前置初始化准备工作。

  • 环境预处理:配置时区、初始化目录、修改文件权限、生成配置文件等

  • 等待依赖:等待数据库、Redis、后端服务、第三方组件就绪后,再启动业务容器

  • 前置资源准备:从配置中心、Git、对象存储拉取配置、脚本、静态资源到本地目录,以供业务容器使用。

  • 安全隔离:初始化操作需要独立权限、独立工具栈,可以放在Init容器单独实现,不需要给业务容器高权限

  • 多阶段串行控制:多个Init容器按顺序依次执行,前一个成功后才运行下一个,全部完成后才运行业务容器。

如果Init容器启动失败,kubelet会持续重启Init容器,直至运行成功。如果Pod重启策略“restartPolicy”设置为“Never”,且Init容器启动失败,Kubernetes会将整个Pod标记为失败状态。

Init容器与普通容器用法基本一致,仅存在两点核心区别:

  • 执行完成后,状态均固定为“completed”

  • 多个Init容器按顺序串行执行,前一个必须执行成功,后一个才会启动

[Step1] 本地新建YAML清单。

root@k8s-master:~# vim init-demo-pod.yml
​
# 写入下列内容
apiVersion: v1      # 固定配置
kind: Pod           # 资源类型
metadata:
  name: init-demo-pod
  namespace: default    # 指定命名空间
spec:
  initContainers:       # 定义Init容器
    - name: wait-busybox
      image: busybox:latest
      command: ['sh','-c','echo busybox && sleep 20']
      imagePullPolicy: IfNotPresent
  containers:
    - name: nginx-app
      image: nginx:latest
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 9090

[Step2] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f init-demo-pod.yml

[Step3] 验证:获取当前命名空间下所有Pod资源的运行状态与简要信息,可以看到当前“STATUS”字段显示为“Init:0/1”这是因为我们只定义了一个Init容器,且该容器还未运行结束。“READY”显示“0/1”是因为我们定义了一个业务容器,但是Init容器还未运行结束,因此显示Ready状态数为0。

root@k8s-master:~# kubectl get pod

[Step4] 验证:等待“sleep”时间结束后,业务容器正常启动。

root@k8s-master:~# kubectl get pod

2. Sidecar类型容器

Sidecar(边车)是在同一Pod中与业务主容器共生的辅助容器,共享网络和存储、生命周期保持一致,无需修改业务代码,能够以外挂的形式统一提供日志采集、流量代理、服务治理、监控追踪、配置下发等通用基础能力,实现业务逻辑与运维管控能力的解耦复用。Init容器要优于Sidecar容器运行,但是Init执行完后会退出,Sidecar容器则是和业务主容器长期运行。Sidecar容器典型用途如下:

  • 日志代理/转发:主容器写日志到共享卷,Sidecar(如Fluentd/Filebeat)采集并发送到ELK

  • Service Mesh与网络代理:用Envoy做Sidecar,接管进出流量,实现限流、熔断、mTLS、灰度测试(Istio核心模式)

  • 探活:检查某些组件是否正常工作

  • 其它辅助性工作,例如拷贝文件、下载文件等

[Step1] 本地新建YAML清单。由于Sidecar容器与业务容器以并行共生的方式运行在同一个Pod中,因此k8s并未给Sidecar容器设定专属字段。在实际使用中,只能依据容器自身的业务职责与运行作用来判断出哪一个是Sidecar容器。根据业务职责能够看到httpd容器为主业务容器,busybox为Sidecar容器,用于生成网页内容。

root@k8s-master:~# vim sidecar-demo-pod.yml
​
# 写入下列内容
apiVersion: v1      # 固定配置
kind: Pod           # 资源类型
metadata:
  name: sidecar-demo-pod
spec:
  containers:
    # --------------- 第一个容器:httpd(主容器,Web 服务)---------------
    - name: httpd
      image: httpd:latest
      imagePullPolicy: IfNotPresent
      volumeMounts: 
        - mountPath: /usr/local/apache2/html/       # 容器内挂载目录
          name: apachevolume        # 挂载卷名称
     # --------------- 第二个容器:busybox(Sidecar 辅助容器)---------------
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ['sh','-c','echo "sidecar apache"> /usr/local/apache2/html/index.html && sleep 3600']
      volumeMounts:
        - mountPath: /usr/local/apache2/html        # 与httpd挂载到同一个目录
          name: apachevolume
  restartPolicy: OnFailure          # 重启策略:只有当容器异常退出时才重启
  volumes:              # 定义Pod中的共享存储卷
    - name: apachevolume            # 存储卷名称
      emptyDir: {}      # 临时空目录卷,Pod生命周期内存活,删除则消失

[Step2] 基于YAML清单向Kubernetes集群声明式地创建Pod资源。

root@k8s-master:~# kubectl create -f sidecar-demo-pod.yml

[Step3] 验证:获取当前命名空间下所有Pod资源的运行状态与简要信息,能够看到容器状态为“Running”。

root@k8s-master:~# kubectl get pod

3. 静态Pod

静态Pod由节点kubelet守护进程直接管理,无需Kubernetes API Server参与管控,区别于Deployment等控制面调度管理的普通Pod。kubelet会持续监控静态Pod的运行状态,一旦Pod异常崩溃,将自动进行重启恢复。

静态Pod固定绑定在指定节点上,仅由该节点的kubelet全权负责生命周期管理。同时,kubelet会通过Kubernetes API Server为每个静态Pod自动创建镜像Pod(Mirror Pod)。

这使节点上的静态Pod可以在集群API中被查询看见,但是无法通过API Server进行任何调度、编辑和删除操作。静态Pod名称会默认追加带连字符的节点主机名作为后缀。

[Step1] 在Master节点上查看所有命名空间下的Pod,能够看到几个以“k8s-master”主机名作为后缀的,就是静态Pod。

root@k8s-master:~# kubectl get pod -A

[Step2] 上述这种查看方法其实也不准确,携带主机名作为后缀的Pod可能也是管理员自定义创建的,因此在Kubernetes也提供了其他的查询方式。首先查询kubelet服务文件,找到“Drop-In”字段指向的配置文件。“Drop-In”的作用就是不修改原systemd服务文件,在单独配置目录里追加或覆盖服务配置,实现无改动原生文件的灵活配置扩展。

root@k8s-master:~# systemctl status kubelet.service

[Step3] 查看该文件内容,找到“Environment”字段。该字段的意思是给kubelet设置一个环境变量,指定它的核心配置文件路径。

root@k8s-master:~# cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

[Step4] 查看该文件内容,过滤出“staticPodPath”字段。该字段指定了一个目录,目录是kubelet静态Pod的监听目录。只需要将Pod的YAML文件放置到该目录,kubelet会自动创建、运行这个静态Pod。

root@k8s-master:~# cat /var/lib/kubelet/config.yaml | grep staticPodPath

[Step5] 查看所有命名空间下携带主机名的Pod,与静态Pod监听目录内容对比,能够对应上。

root@k8s-master:~# kubectl get pod -A | grep k8s-master
root@k8s-master:~# ls /etc/kubernetes/manifests/

[Step6] 在静态Pod监听目录下创建一个YAML文件。

root@k8s-master:~# vim /etc/kubernetes/manifests/static-nginx.yml
​
# 写入下列内容
apiVersion: v1      # 固定配置
kind: Pod           # 资源类型
metadata:
  name: static-nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 8082

[Step7] 运行中的kubelet会定期扫描目录中的变化,并根据文件中增加/减少的Pod来添加/删除Pod。等待片刻后所有命名空间下的Pod,能够看到新增的静态Pod。

root@k8s-master:~# kubectl get pod -A

Vim 编辑只读文件忘记加 sudo?三种提权保存完整解决方案 2026-06-16
Kubernetes Pod调度:Label、亲和性、污点容忍与优先级 2026-08-25

评论区