Pod 是 Kubernetes 集群中的最小管理单元,其中包含一个或多个应用容器,它们在 Pod 内共享网络配置和存储卷配置。可被看作面向应用的“逻辑主机”,是 Kubernetes 中核心的资源对象。
1. Pod 定义详解
yaml 格式的 Pod 配置文件的标准内容如下:
apiVersion: v1
kind: Pod
metadata:
name: string
namespace: strinig
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
YAML上述 yaml 文件中各字段的详细说明见下表:
属性名称 | 取值类型 | 是否必选 | 取值说明 |
version | String | Required | API 版本号,v1 |
kind | String | Required | 资源类型,pod |
metadata | Object | Required | 元数据 |
metadata.name | String | Required | Pod 的名称,命名需要符合 RFC 1035 规范 |
metadata.namespace | String | Required | Pod 所属的命名空间,默认值为 default |
metadata.labels[] | List | 自定义标签列表 | |
metadata.annotations[] | List | 自定义注解列表 | |
spec | Object | Required | Pod 的详细配置定义 |
spec.containers[] | List | Required | Pod 中的容器列表 |
spec.containers[].name | String | Required | 容器的名称,命名需要符合 RFC 1035 规范 |
spec.containers[].image | String | Required | 容器的镜像名称 |
spec.containers[].imagePullPolicy | String | 镜像拉取策略,可选值包括:Always、Never、IfNotPresent,默认值为Always。 (1) Always:表示每次都尝试重新拉取镜像。 (2) IfNotPresent:表示若本地镜像已存在,则使用本地的镜像,否则拉取镜像。 (3) Never:表示仅使用本地镜像。 另外,如果包含以下设置,系统则将默认设置 “imagePullPolicy=Always”: (1) 不设置imagePullPolicy,也未指定镜像的 tag; (2) 不设置imagePullPolicy,镜像 tag 为 latest; (3) 启用了名为“AlwayspPlllmages” 的准入控制器 (Admission Controller) | |
spec.containers[].command | List | 容器的启动命令列表,如果不指定,则使用镜像内置的启动命令 | |
spec.containers[].args | List | 容器的启动命令参数列表 | |
spec.containers[].workingDir | String | 容器的工作目录 | |
spec.containers[].volumeMounts[] | List | 挂载到容器内的存储卷配置 | |
spec.containers[].volumeMounts[].name | String | 引用 Pod 定义的共享存储卷的名称,需要使用volumes[] 部分定义的共享储存卷名称 | |
spec.containers[].volumeMounts[].mountPath | String | 存储卷在容器内挂载的绝对路径,应少于512个字符 | |
spec.containers[].volumeMounts[].readOnly | Boolean | 是否为只读模式,默认为读写模式 | |
spec.containers[].ports[] | List | 容器需要暴露的端口号列表 | |
spec.containers[].ports[].name | String | 端口的名称 | |
spec.containers[].ports[].containerPort | Int | 容器需要监听的端口号 | |
spec.containers[].ports[].hostPort | Int | 容器所在主机需要监听的端口号,默认与containerPort 相同。在设置 hostPort 时,同一台宿主机将无法启动 该容器的第2个副本。 | |
spec.containers[].ports[].protocol | String | 端口协议,支持 TCP 和UDP,默认值为TCP | |
spec.containers[].env[] | List | 在容器运行前需要设置的环境变量列表 | |
spec.containers[].env[].name | String | 环境变量的名称 | |
spec.containers[].env[].value | String | 环境变量的值 | |
spec.containers[].resources | Object | 资源限制和资源请求的设置 | |
spec.containers[].resources.limits | Object | 资源限制的设置 | |
spec.containers[].resources.limits.cpu | String | CPU 限制,单位为 core数,将用于 docker run –cpu-shares 参数 | |
spec.containers[].resources.limits.memory | String | 内存限制,单位可以为MiB、GiB 等,将用于docker run –memory 参数 | |
spec.containers[].resources.requests | Object | 资源请求的设置 | |
spec.containers[].resources.requests.cpu | String | CPU 请求,单位为 core数,即容器启动时的初始可用数量 | |
spec.containers[].resources.requests.memory | String | 内存请求,单位可以为MiB、GiB 等,即容器启动的初始可用数量 | |
spec.containers[].livenessProbe | Object | 对 Pod 内各容器健康检查的设置,在周期性健康检查无响应几次之后,系统将自动重启该容器。可以设置的方法包括:exec、 httpGet和tcpSocket。对一个容器仅需设置一种健康检查方法。 | |
spec.containers[].livenessProbe.exec | Object | 对 Pod 内各容器健康检查的设置,采用exec方式 | |
spec.containers[].livenessProbe.exec.command[] | String | 采用 exec 方式时需要指定的命令或者脚本 | |
spec.containers[].livenessProbe.httpGet | Object | 对 Pod 内各容器健康检查的设置,采用 httpGet 方式,需要指定 path、port | |
spec.containers[].livenessProbe.tcpSocket | Object | 对 Pod 内各容器健康检查的设置,采用 tcpSocket 方式 | |
spec.containers[].livenessProbe.initialDelaySeconds | Number | 容器启动完成后首次探测的时间,单位为 s | |
spec.containers[].livenessProbe.timeoutSeconds | Number | 对容器进行健康检查等特响应的超时时间设置,单位为 s,默认值为 1s 。若超过该超时时间,则认为容器不健康 | |
spec.containers[].livenessProbe.periodSeconds | Number | 对容器健康检查的定期检查时间设置,单位为 s ,默认 10s 检查一次 | |
spec.restartPolicy | String | Pod 的重启策略,可选值为 Always、OnFailure 默认值为 Always。 (1)Always:Pod 一旦终止运行,则无论容器是如何终止的,kubelet都将重启它。 (2)OnFailure:只有Pod 以非零退出码终止时,kubelet 才会重启该容器。如果容器正常结束(退出码为0),kubelet 则不会重启它。 (3) Never:在 Pod 终止后,kubelet 会将退出码报告给 Master,不会再重启该 Pod。 | |
spec.nodeSelector | Object | 设置 Node 的 Label,以key : value 格式指定,Pod 将被调度到具有这些 Label 的Node上。 | |
spec.imagePullSecrets | Object | 拉取镜像时使用的Secret 名称,以name : secretkey 格式指定。 | |
spec.hostNetwork | Boolean | 是否使用主机网络模式,默认值为 false。设置为”true”时,表示容器使用宿主机网络,不再使用 CNI 网络插件 | |
spec.volumes[] | List | 在该 Pod 中定义的存储卷列表 | |
spec.volumes[].name | String | 存储卷的名称,在一个Pod 中,每个存储卷都定义了一个名称,命名应符合 RFC 1035 规范。容器定义部分的 spec.containers[].volumeMounts[].name 将引用该共享存储卷的名称。 Volume 的类型包括: emptyDir、hostPath、 gcePersistentDisk、 awsElasticBlockStore、gitRepo、secret、nfs、 iscsi、glusterfs、persistentVolumeClaim、rbd、flexVolume、 cinder、cephfs、flocker、downwardAPI、fc、azureFile、configMap、 vsphereVolume,可以定义多个 Volume,每个Volume 的 name 都保持唯一。 | |
spec.volumes[].emptyDir | Object | 类型为 emptyDir 的存储卷,表示与 Pod 同生命周期的一个临时目录,其值为一个空对象: emptyDir:{} | |
spec.volumes[].hostPath | Object | 类型为 hostPath 的存储卷,表示 Pod 容器挂载的宿主机目录,通过 spec.volumes[].hostPath.path 指定 | |
spec.volumes[].hostPath.path | String | 类型为 hostPath 的存储卷的宿主机目录 | |
spec.volumes[].secret | Object | 类型为 secret 的存储卷,表示挂载集群预定义的 secret 对象到容器内 | |
spec.volumes[].configMap | Object | 类型为 configMap 的存储卷,表示挂载集群预定义的 configMap 资源对象的数据到容器内 |
2. Pod 的基本用法
Pod 可以由一个或多个容器组成,在下面的示例中,名为“frontend”的 Pod 只由一个容器组成:
# frontend-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
labels:
name: frontend
spec:
containers:
- name: frontend
image: php:8.2-fpm
ports:
- containerPort: 80
YAML另外一种场景是,当 frontend 和 redis 这两个容器应用为紧耦合的关系,并组合为一个整体对外提供服务时,应将这两个容器封装为一个 Pod 。
# frontend-localredis-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-php
labels:
name: redis-php
spec:
containers:
- name: frontend
image: php:8.2-fpm
ports:
- containerPort: 80
- name: redis
image: redis
ports:
- containerPort: 6379
# 属于同一个 Pod 的多个容器应用之间在相互访问时仅需通过 localhost 就可以通信
YAML创建上述两个 pod:
kubectl apply -f frontend-pod.yaml
kubectl apply -f frontend-localredis-pod.yaml
ShellScript查看已创建的 pod:
kubectl get pods
kubectl get pods -o wide
# 查看 pod 详细信息
kubectl describe pod redis-php
ShellScript删除 pod:
kubectl delete pod <pod_name>
ShellScript3. Pod 类型
pod 的类型分为普通 pod 和静态 pod 两大类,其中普通 pod 又分为裸部署 pod 和被控制器管理的 pod。
- 普通 pod:创建 pod 的请求是提交给 Api server 的。
- 裸部署 pod:资源清单里指定的 kind 就是 Pod ,与任何控制器资源都无关,没有自愈等由控制器实现的相关功能。
- 被控制器管理的 pod:可通过控制器实现自愈或者自己定制的相关功能。
- 静态pod:直接通过配置文件或 HTTP 的方式交给 kubelet 创建的 pod ,不通过 API Server 创建。
创建静态 pod 有两种方式:
- 基于本地配置文件
- 基于网络上的配置文件
1、基于本地配置文件
需要在 kubelet 的主配置文件中设置 staticPodPath (在比较旧的 Kubernetes 版本中也可以通过命令行参数 -pod-manifest-pth 进行配置,该命令行参数将被逐渐奔用),指定 kubelet 需要监控的配置文件所在的目录,kubelet 会定期扫描该目录,并根据该目录下的 .yaml 或 json 文件创建静态 Pod。
注意:kubelet 在扫描文件时会忽略以“.”开头的隐藏文件。
kubelet 的默认 staticPodPath 为 /etc/kubernetes/manifests ,如果想修改为其他路径可修改该字段为 staticPodPath: /xxxx。在配置文件中如果该字段不存在,可以手动添加该字段,后重启 kubelet。
2、基于网络上的配置文件
基本同上,只需将 staticPodPath 指向一个 URL 路径,例如:staticPodPath: http://example.com/static-pods。