Pod文件常用配置项
# Pod常用yaml配置项
Pod 是 kubernetes 中的最小调度单位。
# 1一个简单的Pod
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1-c
2
3
4
5
6
7
8
9
# 2apiVersion参数
Pod 资源只能是固定的 v1
- 参数类型:字符串
apiVersion: v1
...
2
# 3metadata参数
metadata
定义了 Pod 的各种元数据信息。
metadata:
...
2
# metadatametadata.name(必选)
设置 Pod 名称。
- 参数类型:字符串
metadata:
name: <名称>
2
# metadatametadata.creationTimestamp
metadata.creationTimestamp
是一个时间戳,表示创建此对象时的服务器时间。它以 RFC3339 形式表示,并采用 UTC。
- 参数类型:字符串,格式为
2006-01-02T15:04:05Z07:00
该参数不是必需的,且可以设置为null
。
metadata:
name: <名称>
creationTimestamp: null
2
3
将其设置为2023-01-01T00:00:00Z
:
- 用 T 分隔日期和时间
- 用 Z 表示 UTC 时区
metadata:
name: <名称>
creationTimestamp: 2023-01-01T00:00:00Z
2
3
# metadatametadata.labels
为 Pod 设置标签。
- 参数类型:对象
metadata:
name: <名称>
labels:
<标签1>: <值1>
<标签2>: <值2>
...
2
3
4
5
6
例如:
metadata:
name: <名称>
labels:
node: worker01
group: working
2
3
4
5
# metadatametadata.namespace
指定 Pod 所在命名空间。
- 参数类型:字符串
metadata:
name: <名称>
namespace: <命名空间>
2
3
# 4spec参数
spec
定义了 Pod 中的容器以及各种容器策略。
# spec.securityContext
为 Pod 设置安全上下文策略(Seccomp),该策略将自动应用到当前 Pod 的所有容器中。
如果字段spec.securityContext
和spec.containers.securityContext
同时存在,则containers
中设置的安全策略优先级更高。
# 使用默认的 seccomp 策略
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
2
3
4
5
# 使用主机上的配置文件 profiles/audit.json 来设置 seccomp 策略
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/audit.json
2
3
4
5
6
# spec.containers(必选)
Pod 中至少要有一个容器。
镜像下载策略可选三个值:IfNotPresent
、Always
和Never
。
...
spec
containers:
- image: <镜像名称>
imagePullPolicy: <镜像下载策略>
name: <容器名称>
...
2
3
4
5
6
7
一个 Pod 里可以有多个容器,但是容器名称不能重复:
...
spec
containers:
- image: <镜像名称>
imagePullPolicy: <镜像下载策略>
name: <容器名称-1>
- image: <镜像名称>
imagePullPolicy: <镜像下载策略>
name: <容器名称-2>
...
2
3
4
5
6
7
8
9
10
# spec.containers.args和command
想要在容器中执行命令,可以通过spec.containers.args
或spec.containers.command
参数来实现,这两个参数有不同的写法,但是作用都是一样的。
此处有两个镜像为 alpine 的容器:
- 第一个容器通过
args
执行了命令sh -c echo abcabcabc; sleep 99999
- 第二个容器通过
command
执行了命令sh -c echo xyzxyzxyz; sleep 99999
...
spec:
containers:
- image: alpine
imagePullPolicy: IfNotPresent
name: c1
args:
- sh
- -c
- echo abcabcabc; sleep 99999
- image: alpine
imagePullPolicy: IfNotPresent
name: c2
command: ["sh", "-c", "echo xyzxyzxyz; sleep 99999"]
2
3
4
5
6
7
8
9
10
11
12
13
14
# spec.containers.securityContext
容器安全策略。
以下配置为容器 c1 设置了安全策略privileged: true
,这将会赋予该容器更高的权限,包括访问物理机资源(相当于物理机中的 root)。
...
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
securityContext:
privileged: true
2
3
4
5
6
7
8
# spec.containers.lifecycle
钩子。
# spec.containers.lifecycle.preStop
结束钩子,在容器关闭之前运行,只有当 preStop 运行完毕,容器/Pod 才会被关闭和删除。
preStop 中的任务也必须在延迟删除期(宽限期)之前完成处理,否则 Pod 一样会被强制删除。
...
spec:
containers:
- image: nginx
name: <容器名称>
lifecycle:
preStop:
exec:
command: ['sh', '-c', '/usr/sbin/nginx -s quit']
2
3
4
5
6
7
8
9
以上钩子在容器关闭之前运行命令sh -c /usr/sbin/nginx -s quit
,这里直接通过 nginx 可执行程序执行了 “quit”(退出)指令,是一种优雅关闭 nginx 服务的方式。
# spec.containers.lifecycle.postStart
启动钩子,在容器创建之后,跟随容器主进程一同运行,没有先后顺序之分(两者异步运行)。类似于初始化容器。
Kubernetes 的容器管理逻辑会一直阻塞等待 postStart 处理函数执行完毕。只有 postStart 处理函数执行完毕,容器的状态才会变成 RUNNING。
...
spec:
containers:
- image: nginx
name: <容器名称>
lifecycle:
postStart:
exec:
command: ['sh', '-c', 'echo "Hello k8s, I am postStart" > /opt/hello.txt']
2
3
4
5
6
7
8
9
以上钩子在容器启动的同时,使用echo
命令将字符串 “Hello k8s, I am postStart” 输出到文件/opt/hello.txt
中。
# spec.containers.resources
容器资源限制。
# spec.containers.resources.limits
示例-1,将容器资源使用上限设置为250
个 CPU 微核心以及500MiB
内存。
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
resources:
limits:
cpu: 250m
memory: 500Mi
2
3
4
5
6
7
8
9
10
11
12
13
示例-2,将容器资源使用上限设置为0.7
个 CPU 核心以及2GiB
内存。
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod2
resources:
limits:
cpu: 0.7
memory: 2Gi
2
3
4
5
6
7
8
9
10
11
12
13
# spec.containers.ports
容器端口规范,公开容器的某个端口。
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
ports:
- name: c1 # 端口的唯一识别名称,服务(Service)可以引用该端口
containerPort: 80 # 要公开的容器端口号
protocol: TCP # 容器端口协议
hostIP: x.x.x.x # 物理机 IP
hostPath: 8080 # 映射到物理机的 8080 端口,一般容器不需要该选项,且一般建议 hostPort 和 containerPort 的端口号相同
2
3
4
5
6
7
8
9
10
11
# spec.containers.env
# (1)在容器中设置环境变量
# env.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
env:
- name: abc
value: "123"
- name: xyz
value: "456"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
kubectl apply -f env.yaml
kubectl exec pod1 -- env
kubectl exec -it pod1 -- bash
echo $abc
echo $xyz
2
3
4
5
6
# (2)以变量的形式使用 secret
示例:将 MySQL 的密码设置为密钥mysec
的键abc
。
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- image: mysql:latest
imagePullPolicy: IfNotPresent
name: c1
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysec
key: abc
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# (3)以变量的形式使用 configmap
和 secret 一样,只需要将字段secretKeyRef
修改为configMapKeyRef
即可。
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- image: mysql:latest
imagePullPolicy: IfNotPresent
name: c1
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
configMapKeyRef: # 修改字段
name: mymap
key: abc
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# (4)通过变量的方式使用服务
首先创建一个服务,后续创建的 Pod 将会自动学习到一些变量。
- 变量
<服务名>_SERVICE_HOST
是某个服务的 IP 地址 - 变量
<服务名>_SERVICE_PORT
是某个服务暴露的端口
例如,创建了一个名为svc1
的服务。
kubectl expose pod pod-mysql --name svc1 --port=3306
然后,你可以在 yaml 文件中使用这个服务的环境变量。
spec:
containers:
- image: wordpress
name: c1
env:
- name: WORDPRESS_DB_HOST
value: $(SVC1_SERVICE_HOST) # 自动转换为 svc1 的 IP 地址
2
3
4
5
6
7
注意
该方式有要求限制:
- 服务和 Pod 必须处于同一个命名空间
- 存在创建的先后顺序,必须先创建服务,再创建 Pod,这样 Pod 才能学习到该服务的相关变量
# (5)借助集群的 coreDNS 使用服务
任何命名空间的服务,在创建时都会向集群 DNS 注册自身。
直接指定服务名称即可:
spec:
containers:
- image: wordpress
name: c1
env:
- name: WORDPRESS_DB_HOST
value: svc1 # 去 coreDNS 查询主机名 svc1 并返回其地址
2
3
4
5
6
7
# spec.containers.volumeMounts
# (1)挂载存储卷
<...省略...>
spec:
volumes:
- name: volume1 # 创建第一个存储卷
emptyDir: {} # 使用临时存储
- name: volume2 # 创建第二个存储卷
nfs: # NFS
server: 192.168.80.10
path: /nfsdata
- name: volume3 # 创建第三个存储卷
persistentVolumeClaim: # 持久卷申领
claimName: pvc01
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
volumeMounts:
- name: volume1 # 挂载第一个存储卷
mountPath: /abc # 挂载到容器的 /abc 目录中
- name: volume2 # 挂载第二个存储卷
mountPath: /xyz # ...
- name: volume3 # 挂载第三个存储卷
mountPath: /jkl # ...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# (2)以存储卷的形式使用 secret
将密钥mysec
中的所有密钥挂载到容器目录/etc/test/
下。
<...省略...>
spec:
volumes:
- name: xx
secret:
secretName: mysec
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
volumeMounts:
- name: xx
mountPath: "/etc/test/"
2
3
4
5
6
7
8
9
10
11
12
13
如果你只想挂载 secret 中的单个密钥对,则可以通过subPath
字段实现该功能。
将密钥mysec
中的指定密钥hosts
挂载到指定容器文件/etc/test/hosts
中。
<...省略...>
spec:
volumes:
- name: xx
secret:
secretName: mysec
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
volumeMounts:
- name: xx
mountPath: "/etc/test/hosts"
subPath: hosts
2
3
4
5
6
7
8
9
10
11
12
13
14
# (3)以存储卷的形式使用 configmap
和 secret 基本一致,只需要修改其中一些字段。
<...省略...>
spec:
volumes:
- name: xx
configMap: # 修改 secret 为 configMap
name: mymap # 修改 secretName 为 name
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
volumeMounts:
- name: xx
mountPath: "/etc/test/"
2
3
4
5
6
7
8
9
10
11
12
13
# spec.containers.livenessProbe(探针)
如果探测到容器不健康,则会尝试通过重启 Pod(删除 Pod 然后重新创建)的方式来解决问题。
# spec.containers.livenessProbe.exec.command
在容器中执行命令,如果命令执行成功(返回零)则说明容器正常,如果命令执行失败(返回非零值)则说明容器异常,此时探针会尝试重启 Pod 来解决异常。
示例:
- 容器启动之后会创建
/tmp/healthy
文件,30s
之后删除该文件,然后休眠1000s
。此时如果没有探针的话,则此 Pod 会等待1000s
才会终止。 - 定义了探针,探测
/tmp/healthy
是否存在。如果存在,则认为这个容器是正常的。如果发现不存在,则认为这个容器出问题了,会通过重启 Pod 来解决问题。 - 探测这个文件的方式,通过命令
cat /tmp/healthy
来判断。如果查看成功,则返回值为零,认为此 Pod 没问题。如果这个文件不存在,则命令执行失败,返回值为非零,则认为容器出问题,此时会重启 Pod。
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
spec:
containers:
- image: busybox
imagePullPolicy: IfNotPresent
name: c1
command: ['sh', '-c', 'touch /tmp/healthy ; sleep 30 ; rm -rf /tmp/healthy ; sleep 1000']
livenessProbe:
exec:
command: ['sh', '-c', 'cat /tmp/healthy']
initialDelaySeconds: 5 # 容器启动的 5s 内不进行探测
periodSeconds: 5 # 每 5s 探测一次
successThreshold: 1 # 一次探测失败之后,最少要连续探测成功多少次才被认定为成功(默认为 1,最小值为 1)
failureThreshold: 3 # 探测失败后,探针的重试次数(默认为 3,最小值为 1)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在以上示例中,大概经过75s
之后,Pod 会自动重启,此时 Pod 里又会重新创建/tmp/healthy
文件。
- 第
30s
的时候文件被删除了,然后重试3
次(每次间隔5s
) - 第
45s
的时候就会重启,关闭 Pod 时有默认30s
的宽限期,所以会在75s
时进行重启
# spec.containers.livenessProbe.httpGet
httpGet 向指定的端口发起 HTTP 请求。如果能访问到指定文件,则认为容器是正常的。如果访问不到,则认为容器异常,会尝试重启 Pod 来解决问题。
示例:
- 通过 httpGet 检测是否能通过端口 80 访问到 /usr/share/nginx/html/index.html 文件
- 如果能,则认为此 Pod 是正常工作的
- 如果不能,则认为 Pod 出现了问题,就要重启 Pod 来解决问题(删除 Pod 重新创建)
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
livenessProbe:
httpGet:
scheme: HTTP
port: 80
path: /index.html
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# spec.containers.livenessProbe.tcpSocket
tcpSocket 向指定端口发起 TCP 连接请求。如果能够正常建立 TCP 三次握手,则认为容器是正常的。如果无法建立 TCP 三次握手,则认为容器是异常的,会尝试重启 Pod 来解决问题。(和 httpGet 相比,tcpSocket 只是探测端口,而不会访问文件)
示例:
- 通过 tcpSocket 探测端口 808,但是 nginx 的端口是 80,这自然是要探测失败的
- 大概在第
15s
开始重启 Pod,从第5s
开始探测,每隔5s
探测1
次(探测间隔为五秒),探测3
次(失败重试次数为三次)
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcp
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
livenessProbe:
tcpSocket:
port: 808
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# spec.containers.readinessProbe(探针)
和 livenessProbe 一样是探针,编写的字段格式相同。不同点:
- livenessProbe 探测到容器异常时,会尝试重启 Pod 来解决问题
- readinessProbe 探测到容器异常时,svc 后续接收到的请求将不会转发给该 Pod
# specspec.serviceAccountName
设置 Pod 中的进程要以哪一个服务账户的权限来运行。
spec:
serviceAccountName: <服务账户名称>
2
# specspec.automountServiceAccountToken
默认情况下,Pod 会自动将所引用的 SA 令牌挂载到容器目录/var/run/secrets/kubernetes.io/serviceaccount/
当中。这带来了一定安全风险。
而字段spec.automountServiceAccountToken
设置一个 Pod 是否可以挂载某个 SA 的令牌到容器中。
# 禁止当前 Pod 将任何 SA 令牌挂载到容器中
spec:
automountServiceAccountToken: false
2
3
注意
如果 ServiceAccount 和 Pod 都设置了automountServiceAccountToken
值, 则 Pod 上的设置优先于 SA 的设置。
# 禁止将当前 SA 的令牌挂载到任何 Pod 中
# 在 SA 中该字段与 spec 同级,而不是在其之下
kind: ServiceAccount
automountServiceAccountToken: false
spec:
...省略
2
3
4
5
6
# specspec.restartPolicy(重启策略)
Pod 重启策略可选三个值:Always
(默认)、OnFailure
和Never
。
- Always:当容器异常退出时,总是重启容器
- OnFailure:当容器异常退出(退出状态码非0)时,重启容器
- Never:从不重启容器
...
spec:
containers:
- image: ...
imagePullPolicy: ...
name: ...
restartPolicy: Always
2
3
4
5
6
7
# specspec.initContainers
初始化容器。会在普通容器之前运行。
可选的配置参数与spec.containers
一样。
# specspec.terminationGracePeriodSeconds
指定 Pod 的延迟删除期(宽限期),默认为 30 秒。
...
spec:
terminationGracePeriodSeconds: 120
2
3
# specspec.nodeSelector
手动指定 Pod 运行位置,详情可参阅本站教程。
# 格式
spec:
nodeSelector:
<标签1>: <标签值1>
<标签2>: <标签值2>
...: ...
2
3
4
5
6
# 示例
将名为pod-node
的 Pod 调度到具有标签kubernetes.io/hostname=www.k12.com
的节点上运行。
# pod-node.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-node
spec:
nodeSelector:
kubernetes.io/hostname: www.k12.com
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod-node
2
3
4
5
6
7
8
9
10
11
12
提示
如果没有满足条件的节点,则 Pod 会一直处于 “Pending” 等待状态,直到出现符合条件的节点,或直到用户手动删除它。
如果有多个满足条件的节点,则会回到原始状态,随机选择一个节点并将 Pod 调度到其上运行。
# specspec.tolerations
为 Pod 设置容忍污点,,详情可参阅本站教程。
该字段下的一些参数:
key
:要容忍污点的 “键”effect
:这个 “键” 对应的 “效果”operator
:- 如果被设置为
Exists
,意思是可以匹配任何 “值”,包括空值。适用于没有污点值的情况下。 - 如果被设置为
Equal
,意思是具有该 “键” 具有污点值,需要填写对应的value
参数。
- 如果被设置为
value
:这个 “键” 对应的 “值”
# 示例-1
容忍一个污点notgood:NoSchedule
,这个污点的值为空。
# pod-toler.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-toler
spec:
tolerations:
- key: notgood
effect: NoSchedule
operator: Exists
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod-toler
2
3
4
5
6
7
8
9
10
11
12
13
14
# 示例-2
同时容忍两个污点:
- 第一个污点
notgood:NoSchedule
,这个污点的值为空 - 第二个污点
personality=bad:NoSchedule
,这个污点的值为bad
# pod-bad.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-bad
spec:
tolerations:
- key: "notgood"
effect: "NoSchedule"
operator: "Exists"
- key: "personality"
effect: "NoSchedule"
operator: "Equal"
value: "bad"
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod-bad
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# specspec.volumes
创建存储卷。
# emptyDir(临时存储)
spec:
volumes:
- name: <存储名称>
emptyDir: {}
2
3
4
# hostPath(主机存储)
spec:
volumes:
- name: <存储名称>
hostPath: <物理机路径>
2
3
4
示例:
spec:
volumes:
- name: volume1
hostPath: /opt
2
3
4
# NFS存储(网络存储)
spec:
volumes:
- name: <存储名称>
nfs:
server: <NFS服务器地址>
path: <NFS共享目录>
2
3
4
5
6
示例:
spec:
volumes:
- name: volume1
nfs:
server: 192.168.1.1
path: /nfsdata
2
3
4
5
6
# 持久卷申领(PersistentVolumeClaim,PVC)
spec:
volumes:
- name: <存储名称>
persistentVolumeClaim:
claimName: <pvc名称>
2
3
4
5
# 持久卷动态制备(存储类,StorageClass)
PVC 的创建方式不一样,但是使用起来是一样的。
# 和上一小节相同
spec:
volumes:
- name: <存储名称>
persistentVolumeClaim:
claimName: <pvc名称>
2
3
4
5
6
# 使用 secret 密钥
需要提前创建 secret 集群资源。
spec:
volumes:
- name: ms
secret:
secretName: mysec
2
3
4
5