Kubernetes Pod

本文最后更新于 2025年8月8日 下午

pod 是Kubernetes集群中的最小管理单元,其中包含一个或多个应用容器,可被看作面向应用的“逻辑主机”,是Kubernetes中核心的资源对象

标准格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
apiVersion: v1
kind: Pod
metadata:
name: string
namespace: string
labels:
- name: string
annotations:
- name: string
spec:
containers:
- name: string
image: string
imagePullpolicy: [Always| Never | IfNotPresent]
command: [string]
args: [string]
workingDir: string
volumeMounts:
- name: string
mountPath: string
readOnly: boolean
ports:
- name: string
containerPort: int
hostPort: int
protocol: string
env:
- name: string
value: string
resources:
limits:
cpu: string
memory: string
requests:
cpu: string
memory: string
livenessProbe:
exec:
command: [string]
httpGet:
path: string
port: number
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket:
port: number
initialDelaySeconds: 0
timeoutSeconds: 0
periodSeconds: 0
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure]
nodeSelector: object
imagePullSecrets:
- name: string
hostNetwork: false
volumes:
- name: string
emptyDir: {}
hostPath:
path: string
secret:
secretName: string
items:
- key: string
path: string
configMap:
name: string
items:
- key: string
path: string
字段路径 类型 说明 示例 / 可选值
apiVersion string API版本 v1
kind string Kubernetes 资源类型 Pod
metadata.name string Pod 名称 my-pod
metadata.namespace string 所属命名空间 default
metadata.labels map<string,string> 标签键值对,用于选择器等 app: nginx
metadata.annotations map<string,string> 注解信息,不参与选择器 prometheus.io/scrape: "true"
spec.containers array 容器数组,定义一个或多个容器 -
spec.containers[].name string 容器名称 web
spec.containers[].image string 容器镜像 nginx:1.25
spec.containers[].imagePullPolicy string 镜像拉取策略 Always,IfNotPresent,Never
spec.containers[].command array[string] 容器启动命令(替代 ENTRYPOINT) ["/bin/sh"]
spec.containers[].args array[string] 容器启动参数(替代 CMD) ["-c", "echo Hello"]
spec.containers[].workingDir string 工作目录 /app
spec.containers[].volumeMounts array 挂载卷信息 -
spec.containers[].volumeMounts[].name string 要挂载的卷名称 data-volume
spec.containers[].volumeMounts[].mountPath string 容器内挂载路径 /data
spec.containers[].volumeMounts[].readOnly boolean 是否只读挂载 true/false
spec.containers[].ports array 容器端口暴露 -
spec.containers[].ports[].name string 端口名称(可选) http
spec.containers[].ports[].containerPort int 容器内部监听端口 80
spec.containers[].ports[].hostPort int 宿主机端口映射 8080
spec.containers[].ports[].protocol string 协议类型 TCPUDP
spec.containers[].env array 环境变量列表 -
spec.containers[].env[].name string 变量名 ENV_MODE
spec.containers[].env[].value string 变量值 production
spec.containers[].resources object 资源限制与请求 -
spec.containers[].resources.limits.cpu string 最大 CPU 限制 500m
spec.containers[].resources.limits.memory string 最大内存限制 512Mi
spec.containers[].resources.requests.cpu string 预留 CPU 请求 250m
spec.containers[].resources.requests.memory string 预留内存请求 256Mi
spec.containers[].livenessProbe object 存活探针 -
spec.containers[].livenessProbe.exec.command array 执行命令探针 ["cat", "/tmp/healthy"]
spec.containers[].livenessProbe.httpGet object HTTP 探针 -
spec.containers[].livenessProbe.httpGet.path string 探测路径 /healthz
spec.containers[].livenessProbe.httpGet.port int/string 端口号或端口名 8080
spec.containers[].livenessProbe.httpGet.host string 请求主机 localhost
spec.containers[].livenessProbe.httpGet.scheme string 请求协议 HTTPor HTTPS
spec.containers[].livenessProbe.httpGet.httpHeaders array 头部设置 [{ name: "X-Custom", value: "123" }]
spec.containers[].livenessProbe.tcpSocket.port int TCP 端口探测 3306
spec.containers[].livenessProbe.initialDelaySeconds int 初始延迟秒数 10
spec.containers[].livenessProbe.timeoutSeconds int 超时时间 2
spec.containers[].livenessProbe.periodSeconds int 探测周期 5
spec.containers[].livenessProbe.successThreshold int 成功次数阈值 1
spec.containers[].livenessProbe.failureThreshold int 失败次数阈值 3
spec.containers[].securityContext.privileged bool 是否启用特权模式 true/false
spec.restartPolicy string Pod 重启策略 Always,OnFailure,Never
spec.nodeSelector map<string,string> 节点选择器 { "disktype": "ssd" }
spec.imagePullSecrets array 镜像拉取凭证 [{ name: "my-registry-key" }]
spec.hostNetwork bool 是否使用主机网络 true/false
spec.volumes array 卷定义 -
spec.volumes[].name string 卷名称 data-volume
spec.volumes[].emptyDir object 空目录卷(临时数据) {}
spec.volumes[].hostPath.path string 主机路径挂载 /data/host
spec.volumes[].secret.secretName string 绑定的 secret 名称 my-secret
spec.volumes[].secret.items[] object 指定映射的 key/path { key: "token", path: "token.txt" }
spec.volumes[].configMap.name string 引用的 ConfigMap 名称 app-config
spec.volumes[].configMap.items[] object 指定映射的 key/path { key: "app.properties", path: "conf/app.properties" }

当存在两个应用紧密耦合,并组合为一个整体进行对外服务时,应将这两个容器应用封装为一个Pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: redis-php
labels:
name: redis-php
spec:
containers:
- name: frontend
image: kubeguide/guestbook-php-frontend:localredis
ports:
- containerPort: 80
- name: redis
image: kubeguide/redis-master
ports:
- containerPort: 6379

应用通过localhost:6379 对redis进行访问

静态Pod

静态Pod是由kubelet管理的仅存在于kubelete所在Node上的Pod,不需要通过Kubernetes的Master管理。kubelet负责监控由它创建的静态Pod,并在失效时重建pod。静态Pod无法被Master管理,以及无法使用普通Pod可以使用的其他资源

1.基于本地配置文件

在kubelet的主配置文件中设置 staticPodPath。kubelet会定期扫描该目录

配置目录为 /etc/kubernetes/manifests 配置参数为staticPodPath:/etc/kubernetes/manifests

在/etc/kubelet.d 目录下设置配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 配置信息
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
name: static-web
spec:
containers:
- name: static-web
image: nginx
ports:
- name: web
containerPort: 80
  1. 网络配置

通过 —manifest-url 获取yaml 文件作为配置信息

Pod容器共享Volume

在tomcal容器中设置将命名为app-logs的volume 挂在到/usr/local/tomcat/logs中

设置volumes ,而在busybox 将该目录挂在为/logs 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containerPort: 8080
volumeMounts:
- name: app-logs
mountPath: /usr/local/tomcat/logs
- name: busybox
image: busybox
command: ["sh", "-c" , "tail -f /logs/catalina*.log"]
volumeMounts:
- name: app-logs
mountPath: /logs
volumes:
- name: app-logs
emptyDir: {}

Pod的配置管理

ConfigMap用于保存应用程序运行时需要的配置数据,通过明文及K:V存储

ConfigMap 一般用于

1.生成容器内的环境变量

2.设置容器启动命令的命令参数

3.以Volume的形式挂在为容器内的文件或目录

1
2
3
4
5
6
7
8
# cm-appvars.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-appvars
data:
apploglevel: info
appdatadir: /var/data

在env 下使用configmap , configmap会以文件进行挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
volumes:
- name: config-volume
configMap:
name: my-config
# 定义存储卷

volumeMounts:
- name: config-volume
mountPath: /etc/config
# 使用config-volume,并挂载到/etc/config路径

volumes:
- name: config-volume
configMap:
name: my-config
items:
- key: app.properties
path: my-app.conf
# 在卷中指定configmap中的某个key将对应文件挂载

使用envfrom 配置为环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name: app
image: alpine
command: ["sh", "-c", "env; sleep 3600"]
envFrom:
- configMapRef:
name: my-config
# 将my-config 整个加载为环境变量

env:
- name: ENV_MODE
valueFrom:
configMapKeyRef:
name: my-config
key: ENV_MODE

# 将my-config 中对应的ENV_MODE 中的values设置为环境变量

容器内获取Pod信息

Downward API

通过Downward API 将Pod的信息注入到容器的环境变量中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# dapi-envars-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: tst-container
image: busybox
command: ["sh", "-c"]
args:
- while true ; do
echo -en '\\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
sleep 10 ;
done;
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPCAE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: Never

在文件中不是直接写入而是通过valueFrom指定对应的数据字段获取值

将Container配置信息设置为容器内的环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# dapi-envars-container.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: busybox
imagePullPolicy: Never
command: ["sh","-c"]
args:
- while true ; do
echo -en '\\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
restartPolicy: Never

Volume挂载

将Pod信息挂载为容器内的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# dapi-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: busybox
command: ["sh","-c"]
args:
- while true ; do
if [[ -e /etc/podinfo/labels]]; then
echo -en '\\n\\n'; cat /etc/podinfo/labels ; fi ;
sleep 5;
done;
volumeMounts:
-name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels

将容器的配置信息挂载为容器内的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# dapi-volume-resources.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: busybox
command: ["sh","-c"]
args:
- while true; do
echo -en 'n';
if [[ -e /etc/podinfo/cpu_limit ]] ; then
echo -en '\\n'; cat /etc/podinfo/cpu_limit; fi;
sleep 5s;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resource: limits.cpu
divisor: 1m

支持设置的信息

  1. 由fieldRef设置的字段
    metadata.name: Pod名称
    metadata.namespace: Pod所在的命名空间名称
    metadata.uid: Pod的UID
    metadata.labels[’<KEY>’]: Pod某个Label的值,通过<KEY>引用
    metadata.annotations[‘<KEY>’]: Pod某个Annotations的值,通过<KEY>引用
  2. Pod的以下元数据信息可以被设置为容器内的环境变量,
    spec.serviceAccountName: Pod使用的ServiceAccount名称
    spec.nodeName: Pod所在Node的名称
    status.hostIP: Pod所在Node的IP地址
    status.hostIPs: Pod所在Node的双栈IP地址
    status.IP: Pod的IP地址
    status.IPs: Pod的双栈IP地址
  3. 设置downwardAPI为存储卷类型时,可以在器fieldRef字段设置以下信息
    metadata.labels : Pod的label列表
    metadata.annotations : Pod的annotation列表
  4. 通过resourceFieldRef 设置的字段
    limits.cpu # 容器可使用的最大 CPU 数量(上限),单位为核心(如 1、500m 等),超出会被限制
    requests.cpu # 容器调度时请求的最小 CPU 数量,调度器据此分配节点资源,单位同上
    limits.memory # 容器可使用的最大内存(上限),单位如 Mi、Gi,超出将触发 OOMKilled
    requests.memory # 容器调度时请求的最小内存,调度器据此分配节点资源
    limits.hugepages-* # 容器可使用的最大 HugePages 限额,例如 limits.hugepages-2Mi
    requests.hugepages-* # 容器调度时请求的 HugePages 数量,例如 requests.hugepages-1Gi
    limits.ephemeral-storage # 容器使用的最大临时存储空间(如 emptyDir、写入容器层),超出会被限制
    requests.ephemeral-storage # 容器调度时请求的最小临时存储空间,用于调度决策。

生命周期

Pod的生命周期

Pending 创建Pod的请求已被Master接受,但有一个或多个容器没有创建也没有运行

Running Pod已完成调度到特定Node,其包含的所有容器均已创建,并且至少由一个容器处于正在运行状态

Succeeded Pod内的所有容器君子成功执行后终止,不会重启

Failed Pod内的所有容器均已终止,但至少有一个容器未退出失败状态,即退出码不是0

Unknown 由于某种原因无法获得Pod的状态

Pod的状况

PodScheduled 已将Pod调度到某个Node

PodReadyToStartContainers Pod已创建,并完成网络配置,可以启动容器。

ContainersReady Pod中的全部容器都达到Ready状态

Initialized Pod中的全部初始化容器都成功运行

Ready Pod达到Ready状态,可以被加入相应Service的负载均衡后端列表中

容器状态

Waiting :Kubernetes在能够运行该容器之前通常需要执行某些操作,例如下载容器镜像,为容器设置存储卷,等待依赖资源达到就绪状态,因此系统设置容器的状态为等待运行

Running :表示容器处于正常的运行过程中,并没有发生错误

Terminated : 运行结束,可能是正常运行结束,也可能是因为失败结束

Pod的重启策略

  • Always : 当容器启动失败后总是由kubelet尝试自动重启容器
  • OnFailure : 当容器终止运行且退出码不为0时,由kubelet自动重启容器
  • Never: 不论容器处于哪种运行状态,kubelet不会重启该容器

控制权与重启策略

Deployoment/StatuefulSet/DaemonSet/RC : 必须设置为Always

Job : OnFailure或Never

kubelet : 在静态Pod失效时自动重启它

Pod的终止过程

  1. 通过kubectl delete pod 命令手动删除一个Pod,优雅终止的宽限期默认为30s
  2. 控制平面会更新Pod的状态,通过kubectl get 或describe命令可以看到Pod状态为”Terminating”。在Pod运行的Node上,kubelet一旦探测到Pod状态为”Terminating”就开始对Pod进行以下终止操作
    如果容器配置了preStop回调钩子,并且配置了非0的终止宽限期,kubelet就调用preStop回调钩子。如果preStop回调钩子在终止宽限期之后还未完成,会向宽限期增加时间(默认2s)
    如果容器没配置preStop,或者终止宽限期已过,kubelet就调用容器运行时给容器的主进程发送TERM信息,也可能发送容器镜像中STOPSIGNAL变量配置的信号
  3. 在kubelet启动Pod的优雅终止过程的同时,控制平面会评估是否将正在终止的Pod从对应服务的后端列表中移除。
  4. 超过优雅终止宽限期之后,kubelet首先会启动强制终止容器进程的操作,通过容器运行时向剩余的进程发送KILL信号,kubelet也会删除Pod的基础Pause容器。然后kubelet将Pod的阶段设置为Succeeded或Failed。并设置宽限期为0,表示立刻删除。最后控制平面从etcd中彻底删除该Pod资源对象

Pod的垃圾清理机制

Kubernetes的控制平面提供了一个Pod垃圾清理器PodGC(Garbage Collector),在监控到Pod数量超过阈值时,会进行删除已终止Pod的操作。GC会清理以下条件的Pod

  • 孤儿Pod : 已完成调度,但Node 不再存在
  • 在计划外终止的Pod
  • 终止过程中的Pod

探针和健康检查机制

  1. LivenessProbe 探针

用于判断容器是否存活,如果LivenesProbe探针探测到容器不健康,则杀掉该容器,并根据容器的重启策略做相应的处理,如果容器未设置LivenessProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是Success

  1. ReadinessProbe探针

用于判断容器服务是否处于Ready状态,处于Ready状态的Pod才可以接收请求。ReadinessProbe定期触发,存在于Pod的整个生命周期内

  1. StartupProbe探针

某些应用会遇到一些情况,例如应用程序在启动时需要与远程服务器建立网络连接,或者网络访问较慢等,导致容器启动缓慢,可以由StartupProbe持续检查Pods状态,在此期间LivenessProbe探针和ReadinessProbe探针均被禁用,直到StartupProbe 返回成功

探测策略

  • exec : 在容器内运行指定的命令,如果该命令运行的返回码未0,则说明探测成功
  • tcpSocket : 通过容器的IP地址和端口号执行TCP检查,如果能够建立TCP连接,则说明探测成功
  • httpGet:通过容器的IP地址,端口号及路径调用HTTP Get方法,如果响应的状态码大于等于200且小于400 说明探测成功。
  • grpc:通过gRPC执行一个Health Check的远程调用,要求应用程序实现gRPC健康检查协议,如果响应的status为SERVING

字段配置

  • initalDelaySecondes: 启动容器后进行首次探测的等待时间,单位为s,默认值为0,最小值为0.
  • periodSecondes: 周期性执行探测的时间间隔,单位为s,默认为10,最小值为1
  • timeoutSeconds: 发出探测请求后等待结果的超时时间,单位为s。当超时发生时,kubelet认为探测失败
  • successThreshold: 探测失败后,判定为探测成功的最小连续探测成功的次数,默认值为1
  • failureThreshold: 判定为探测失败的连续探测失败的次数,达到整个数量后,kubelet会认为容器不健康或者服务未就绪,并将基于重启策略对容器进行重启操作
  • terminationGracePeriodSecondes: 探测失败后,kubelet触发终止容器命令之后等待容器自行结束的宽限期,单位为s,默认值为30,最小值为1

HTTP类型探针的配置

  • host: 主机名,默认为Pod的IP地址
  • scheme: 连接协议
  • path: 访问路径,默认为“/”
  • httpHeaders: 自定义HTTP头,允许重复
  • port: 容器的端口号或端口名称

探测结果

  • Success 探测成功
  • Failure 探测失败
  • Unknown 探测失败

exec机制配置LivenessProbe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- echo ok > /tmp/health; sleep 10 ; rm -rf /tmp/health; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/health
initialDelaySeconds: 15
timeoutSeconds: 1

tcpSocket机制配置LivenessProbe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
livenessProbe:
tcpSocket:
port: 80
initialDelaySecondes: 30
timeoutSeconds: 1

httpGet机制配置LivenessProbe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /_status/healthz
port: 80
initialDelaySecondes: 30
timeoutSecondes: 1

gRPC机制配置LivenessProbe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
name: etcd-with-grpc
spec:
containers:
- name: etcd
image: etcd:3.5.1
command: ["/usr/local/bin/etcd","--data-dir","/var/lib/etcd",
"--listen-client-urls","<http://0.0.0.0:2379>","--advertise-client-urls",
"<http://127.0.0.1:2379>"]
ports:
- containerPort: 2379
livenessProbe:
grpc:
port: 2379
initialDelaySeconds: 10

设置startupProbe保护探针保护需要启动很长时间的容器

1
2
3
4
5
6
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10

如果300s后仍未成功启动,kubelet会尝试重启策略

设置ReadinessProbe探针保护暂时无法提供服务的容器

1
2
3
4
5
6
readinessProbe
httpGet:
path: /healthz
port: 8080
initialDelaySecondes: 10
periodSeconds: 3

kubelet 在探测到容器服务不在就绪时,会通知控制平面,以调整对应的Service,将不健康的后端Pod暂时隔离,不再将请求转发到这个Pod,从而避免出现大量的失败状况

初始化容器

初始化容器是一种特殊的容器

初始化容器的运作方式与应用容器不同:初始化容器必须先于应用容器运行成功,在设置了多个初始化容器时,将按顺序逐个运行初始化容器,并且只有前一个初始化容器运行成功,才能运行其之后的一个初始化容器。在所有初始化容器运行成功后,才会初始化Pod的各种信息,并开始创建和运用容器

初始化容器的定义中可以设置资源限制,Volume的使用和安全策略,等待。

  • 如果多个初始化容器定义了资源请求或者资源限制,则取最大的值为所有初始化容器的资源请求值或资源限制值
  • Pod的有效资源请求值或资源限制取值以下二者的较大值
    • 所有应用容器的资源请求值或资源限制值之和
    • 初始化容器的有效资源请求或资源限制值
  • 调度算法将基于Pod的有效资源请求致或资源限制值进行计算,也就是说,初始化容器可以为初始化操作预留系统资源,即使后续的应用容器 无须使用这些资源
  • Pod的有效QoS等级适用于初始化容器和应用容器
  • 资源配额和限制将根据Pod的有效资源请求值或者资源限制值计算且生效
  • Pod级别的Cgroup将基于Pod的有效资源请求或限制,与调度机制一致

初始化容器不支持对生命周期和健康检查机制进行配置

可能重启的场景

  • Pod的infrastructure容器更新,此时Pod会重启
  • Pod中的所有应用容器都终止,此时Pod会重启

初始化容器的实现原理

通过initContainers字段配置初始化容器,以实现在启动应用容器之前运行初始化容器,并且允许配置一个或多个初始化容器,已完成应用容器所需的预置条件。系统会在Pod的状态信息的initContainerStatuses字段中显示初始化容器的运行信息

通过初始化容器为应用容器准备数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# pod-with-init.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-init
labels:
app: nginx
space:
initContainers:
- name: install
image: busybox
imagePullPolicy: IfNotPresent
command: ["sh","-c","echo Hello World! > /web-root/index.html" ]
volumeMounts:
- name: webroot
mountPath: "/web-root"
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: webroot
mountPath: /usr/share/nginx/html
volumes:
- name: webroot
emptyDir: {}

通过初始化容器等待应用容器依赖的一个服务处于Ready状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# pod-with-init-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-init-2
spec:
initContainers:
- name: wait-for-service-a
image: busybox
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- until wget -q service-a:8080; do echo -e "waiting for service-a"; sleep 5;
done; echo -e "service-a ready , starting service-b now";
containers:
- name: service-b
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

通过初始化容器将Pod作为一个服务实例注册到外部的某个服务中心

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# pod-with-init-3.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-init-3
spec:
initContainers:
- name: register-to-svc-center
image: busybox
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- until curl -X POST -d 'svc_name=$POD_NAME&svc_ip=$POD_IP'
http://$SERVICE_REGISTRY_HOST:$SERVICE_REGISTRY_PORT/register;do echo -e
"register to service center"; sleep 5; done ; echo -e "register successfully, starting
service now";
env:
- name: SERVICE_REGISTRY_HOST
value: 192.168.0.1
- name: SERVICE_REGISTRY_PORT
value: 8080
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
containers:
- name: service

设置两个初始化容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# pod-with-2-init.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-2-init
labels:
app: nginx
spec:
initContainers:
- name: init-myservice
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh','-c', "until nslookup myservice.$(cat /var/run/sercets/kubernetes.io
/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting
for myservice; sleep 2; done"]
- name: init-mydb
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh','-c', "until nslookup mydb.$(cat /var/run/sercets/kubernetes.io
/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting
for mydb; sleep 2; done"]
containers:
- name: myapp-container
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh','-c','echo The app is running! && sleep 3600']

注意事项

  • 如果初始化容器运行失败,系统会根据Pod的重启策略进行重启。
  • 在所有初始化容器都进入运行完毕之前,Pod不会进入Ready状态
  • 在重启Pod时会重启所有初始化容器
  • 在创建之后,如果需要修改初始化容器的定义,则只允许修改image字段
  • Kubernetes在创建Pod时,会强制检查在初始化容器的定义中是否存在ReadinessProbe,如果存在,则将拒绝创建
  • 如果Pod设置了activeDeadlineSeconds , 则可以避免初始化容器持续运行失败并且无限重启
  • 在Pod中,每个容器的名称都必须唯一

pod 是Kubernetes集群中的最小管理单元,其中包含一个或多个应用容器,可被看作面向应用的“逻辑主机”,是Kubernetes中核心的资源对象


Kubernetes Pod
http://gadoid.io/2025/08/08/Kubernetes-Pod/
作者
Codfish
发布于
2025年8月8日
许可协议