Pod 类型与配置

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 文件中各字段的详细说明见下表:

属性名称取值类型是否必选取值说明
versionStringRequiredAPI 版本号,v1
kindStringRequired资源类型,pod
metadataObjectRequired元数据
metadata.nameStringRequiredPod 的名称,命名需要符合 RFC 1035 规范
metadata.namespaceStringRequiredPod 所属的命名空间,默认值为 default
metadata.labels[]List自定义标签列表
metadata.annotations[]List自定义注解列表
specObjectRequiredPod 的详细配置定义
spec.containers[]ListRequiredPod 中的容器列表
spec.containers[].nameStringRequired容器的名称,命名需要符合 RFC 1035 规范
spec.containers[].imageStringRequired容器的镜像名称
spec.containers[].imagePullPolicyString镜像拉取策略,可选值包括: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[].commandList容器的启动命令列表,如果不指定,则使用镜像内置的启动命令
spec.containers[].argsList容器的启动命令参数列表
spec.containers[].workingDirString容器的工作目录
spec.containers[].volumeMounts[]List挂载到容器内的存储卷配置
spec.containers[].volumeMounts[].nameString引用 Pod 定义的共享存储卷的名称,需要使用volumes[] 部分定义的共享储存卷名称
spec.containers[].volumeMounts[].mountPathString存储卷在容器内挂载的绝对路径,应少于512个字符
spec.containers[].volumeMounts[].readOnlyBoolean是否为只读模式,默认为读写模式
spec.containers[].ports[]List容器需要暴露的端口号列表
spec.containers[].ports[].nameString端口的名称
spec.containers[].ports[].containerPortInt容器需要监听的端口号
spec.containers[].ports[].hostPortInt容器所在主机需要监听的端口号,默认与containerPort 相同。在设置 hostPort 时,同一台宿主机将无法启动
该容器的第2个副本。
spec.containers[].ports[].protocolString端口协议,支持 TCP 和UDP,默认值为TCP
spec.containers[].env[]List在容器运行前需要设置的环境变量列表
spec.containers[].env[].nameString环境变量的名称
spec.containers[].env[].valueString环境变量的值
spec.containers[].resourcesObject资源限制和资源请求的设置
spec.containers[].resources.limitsObject资源限制的设置
spec.containers[].resources.limits.cpuStringCPU 限制,单位为 core数,将用于 docker run –cpu-shares 参数
spec.containers[].resources.limits.memoryString内存限制,单位可以为MiB、GiB 等,将用于docker run –memory 参数
spec.containers[].resources.requestsObject资源请求的设置
spec.containers[].resources.requests.cpuStringCPU 请求,单位为 core数,即容器启动时的初始可用数量
spec.containers[].resources.requests.memoryString内存请求,单位可以为MiB、GiB 等,即容器启动的初始可用数量
spec.containers[].livenessProbeObject对 Pod 内各容器健康检查的设置,在周期性健康检查无响应几次之后,系统将自动重启该容器。可以设置的方法包括:exec、 httpGet和tcpSocket。对一个容器仅需设置一种健康检查方法。
spec.containers[].livenessProbe.execObject对 Pod 内各容器健康检查的设置,采用exec方式
spec.containers[].livenessProbe.exec.command[]String采用 exec 方式时需要指定的命令或者脚本
spec.containers[].livenessProbe.httpGetObject对 Pod 内各容器健康检查的设置,采用 httpGet 方式,需要指定 path、port
spec.containers[].livenessProbe.tcpSocketObject对 Pod 内各容器健康检查的设置,采用 tcpSocket 方式
spec.containers[].livenessProbe.initialDelaySecondsNumber容器启动完成后首次探测的时间,单位为 s
spec.containers[].livenessProbe.timeoutSecondsNumber对容器进行健康检查等特响应的超时时间设置,单位为 s,默认值为 1s 。若超过该超时时间,则认为容器不健康
spec.containers[].livenessProbe.periodSecondsNumber对容器健康检查的定期检查时间设置,单位为 s ,默认 10s 检查一次
spec.restartPolicyStringPod 的重启策略,可选值为 Always、OnFailure
默认值为 Always。
(1)Always:Pod 一旦终止运行,则无论容器是如何终止的,kubelet都将重启它。
(2)OnFailure:只有Pod 以非零退出码终止时,kubelet 才会重启该容器。如果容器正常结束(退出码为0),kubelet 则不会重启它。
(3) Never:在 Pod 终止后,kubelet 会将退出码报告给 Master,不会再重启该 Pod。
spec.nodeSelectorObject设置 Node 的 Label,以key : value 格式指定,Pod 将被调度到具有这些 Label 的Node上。
spec.imagePullSecretsObject拉取镜像时使用的Secret 名称,以name : secretkey 格式指定。
spec.hostNetworkBoolean是否使用主机网络模式,默认值为 false。设置为”true”时,表示容器使用宿主机网络,不再使用 CNI 网络插件
spec.volumes[]List在该 Pod 中定义的存储卷列表
spec.volumes[].nameString存储卷的名称,在一个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[].emptyDirObject类型为 emptyDir 的存储卷,表示与 Pod 同生命周期的一个临时目录,其值为一个空对象: emptyDir:{}
spec.volumes[].hostPathObject类型为 hostPath 的存储卷,表示 Pod 容器挂载的宿主机目录,通过 spec.volumes[].hostPath.path 指定
spec.volumes[].hostPath.pathString类型为 hostPath 的存储卷的宿主机目录
spec.volumes[].secretObject类型为 secret 的存储卷,表示挂载集群预定义的 secret 对象到容器内
spec.volumes[].configMapObject类型为 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>
ShellScript

3. 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。