4.深入掌握Pod

4.1 Pod定义详解

YAML格式的Pod定义文件的内容如下:

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]
  nodeSelector: object
  imagePullSecrets:
  - name: string
  hostNetwork: false
  volumes:
  - name: string
  - key: string
    path: string
  configMap:
    name: string
    items:
    - key: string
      path: string

对Pod定义文件模板中各属性的说明请执行以下命令,查看帮助:

$ kubectl explain pod

4.2 Pod基本用法

在 Kubernetes系统中对长时间运行容器的要求是:其主程序需要一直在前台运行。

4.3 静态Pod

静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod 。
静态Pod总是由kubelet创建的,并且总在kubelet所在的Node上运行 。
创建静态Pod有两种方式:

  1. 配置文件方式
  2. HTTP方式

4.4 Pod容器共享Volume

同一个 Pod 中的多个容器能够共享 Pod 级别的存储卷 Volume 。 Volume 可以被定义为各种类型,多个容器各自进行挂载操作,将一个 Volume 挂载为容器内部需要的目录。
Pod中多个容器共享Volume

$ cat pod-volume-applogs.yaml 
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: {}

查看日志的命令:

$ kubectl logs -f volume-pod -c busybox
$ kubectl exec -it volume-pod -c tomcat -- ls /usr/local/tomcat/logs
$ kubectl exec -it volume-pod -c tomcat -- tail /usr/local/tomcat/logs/catalina.2021-11-20.log

4.5 Pod的配置管理

  • 应用部署的一个最佳实 践是将应用所需的配置信息与程序分离。
  • 将应用打包为容器镜像后,可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入。
4.5.1 ConfigMap概述

ConfigMap 供容器使用的典型用法如下:

  1. 生成容器内的环境变量。
  2. 设置容器启动命令的启动参数。
  3. 以Volume的形式挂载为容器内部的文件或目录。

ConfigMap 以一个或多个 key:value 的形式保存在 Kubernetes 系统中供应用使用。
通过YAML文件或者直接使用 kubectl create configmap 命令行的方式来创建ConfigMap 。

4.5.2 创建ConfigMap资源对象
  1. 通过YAML文件方式创建
  2. 通过kubectl命令行方式创建
  • 指定key的名称,创建包含多个key的ConfigMap
$ kubectl create configmap  NAME  --from-file=[key=]source --from-file=[key=]source

容器应用对ConfigMap的使用有以下两种方法:

  1. 通过环境变量获取ConfigMap中的内容。
  2. 通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录。
4.5.3 在Pod中使用ConfigMap
  1. 通过环境变量方式使用ConfigMap。
  2. 通过volumeMount使用ConfigMap。
4.5.4 使用ConfigMap的限制条件

使用ConfigMap的限制条件如下:

  • ConfigMap必须在Pod之前创建,Pod才能引用它。
  • 如果Pod使用envFrom基于ConfigMap定义环境变量,则无效的环境变量名称将被忽略,并在事件中被记录为InvalidVariableNames。
  • ConfigMap受命名空间限制,只有处于相同命名空间中的Pod才可以引用它。
  • ConfigMap无法用于静态Pod。

4.6 在容器内获取Pod信息(Downward API)

Downward API可以通过以下两种方式将Pod和容器的元数据信息注人容器内部:

  1. 环境变量: 将Pod或Container信息设置为容器内的环境变量。
  2. Volume挂载: 将Pod或Container信息以文件的形式挂载到容器内部。
4.6.1 环境变量方式

通过环境变量的方式可以将Pod信息或Container信息注入容器运行环境中。

  1. 将Pod信息设置为容器内的环境变量
    通过Downward API将Pod的IP、名称和所在命名空间注入容器的环境变量中。

通过对Downward API的设置使用了以下Pod的元数据信息设置环境变量:

  • spec.nodeName: Pod所在Node的名称;
  • metadata.name: Pod名称;
  • metadata.namespace: Pod所在命名空间的名称;
  • status.podIP: Pod的IP地址;
  • spec.serviceAccountName: Pod使用的ServiceAccount名称。
  1. 将Container信息设置为容器内的环境变量
    通过Downward API将Container的资源请求和资源限制信息设置为容器内的环境变量。
# dapi-envars-container.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-resourcefieldref
spec:
  containers:
    - name: test-container
      image: busybox:1.0
      imagePullPolicy: Never
      command: [ "sh","-c"]
      args:
      - while true; do
         echo -en '\n';
         printenv MY_CPU_REQUEST MY_CPU_LIMIT;
         printenv MY_MEM_REQUEST MY_MEM_LIMIT;
         sleep 10;
        done;
      args:
      - while true; do
         echo -en '\n';
         printenv MY_CPU_REQUEST MY_CPU_LIMIT;
         printenv MY_MEM_REQUEST MY_MEM_LIMIT;
         sleep 3600;
        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
        - name: MY_MEM_REQUEST
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: requests.memory
        - name: MY_MEM_LIMIT
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: limits.memory
  restartPolicy: Never

通过Downward API将以下Container的资源限制信息设置为环境变量:

  • requests.cpu : 容器的CPU请求值;
  • limits.cpu : 容器的CPU限制值;
  • requests.memory : 容器的内存请求值;
  • limits.memory : 容器的内存限制值。
4.6.2 Volume挂载方式

通过Volume挂载方式可以将Pod信息或Container信息挂载为容器内的文件。

  1. 将Pod信息挂载为容器内的文件。
    通过Downward API将Pod的Label、Annotation信息通过Volume挂载为容器中的文件。
  2. 将Container信息挂载为容器内的文件
    • requests.cpu: 容器的CPU请求值;
    • limits.cpu: 容器的CPU限制值;
    • requests.memory: 容器的内存请求值;
    • limits.memory: 容器的内存限制值。
4.6.3 Downward API支持设置的Pod和Container信息

Downward API支持设置的Pod和Container信息如下:

  1. 可以通过fieldRef设置的元数据如下:
    metadata.name: Pod名称;
    metadata.namespace: Pod所在的命名空间名称;
    metadata.uid: Pod的UID;
    metadata.labels['<KEY>']: Pod某个Label的值,通过进行引用。
  2. 可以通过resourceFieldRef设置的数据如下:
    Container级别的CPU Limit.
    Container级别的CPU Request.
    Container级别的Memory Limit.
    Container级别的Memory Request.
    Container级别的临时存储空间.
    Container级别的临时存储空间.
  3. 对以下信息通过fieldRef字段进行设置
    metadata.labels: Pod的Label列表,每个Label都以key为文件名,value为文件内容,每个Label各占一行。
    metadata.namannotations: Pod的Annotation列表,每个Annotation都以key为文件名,value为文件内容,每个Annotation各占一行。
  4. 以下Pod的元数据信息可以被设置为容器内的环境变量
    status.podIP: Pod的IP地址;
    spec.serviceAccountName: Pod使用的ServiceAccount名称;
    spec.nodeName: Pod所在Node的名称;
    status.hostIP: Pod所在Node的IP地址。

4.7 Pod生命周期和重启策略

Pod状态
Pod状态
Pod 的 重启策略包括 AlwaysOnfailureNever, 默认值为 Always

  • Always: 当容器失效时,由kubelet自动重启该容器。
  • OnFailure: 当容器终止运行且退出码不为0时,由kubelet自动重启该容器。
  • Never: 不论容器运行状态如何,kubelet都不会重启该容器。

当前可用于管理Pod的控制器包括Deployment(ReplicaSet),Job,DaemonSet, 还可以通过kubelet管理(静态Pod)。
每种控制器对Pod的重启策略要求:

  • RC和DaemonSet: 必须设置为Always,需要保证该容器持续运行。
  • Job: OnFailureNever, 确保容器执行完成后不再重启。
  • kubelet: 在Pod失效时自动重启它,不论将RestartPolicy设置为什么值,也不会对Pod进行健康检查。

4.8 Pod健康检查和服务可用性检查

Kubemetes对Pod的健康状态可以通过三类探针来检查 : LivenessProbe
ReadinessProbeStartupProbe , 其中最主要的探针为LivenessProbeReadinessProbe

kubelet 会定期执行这两类探针来诊断容器的健康状况。

  1. LivenessProbe探针
    用于判断容器是否存活,如果LivenessProbe探针探测到容器不健康,则kubelet将"杀掉"该容器,并根据容器的重启策略做相应的处理. 如果一个容器不包含LivenessProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是Success.
  2. ReadinessProbe探针:
    用于判断容器服务是否可用(Ready状态),达到Ready状态的Pod才可以接收请求。对于被 Service 管理的 Pod, Service 与 Pod Endpoint 的关联关系也将基于 Pod 是否 Ready 进行设置 。 如果在运行过程中 Ready 状态变为 False, 则系统自动将其从 Service 的后端 Endpoint 列表中隔离出去,后续再把恢复到 Ready 状态的 Pod加回后端 Endpoint 列表 。 这样就能保证客户端在访问 Service 时不会被转发到服务不可用的 Pod 实例上. 需要注意的是,ReadinessProbe是定期触发执行,存在于Pod的整个生命周期中。
  3. ·StartupProbe·探针:
    容器启动缓慢,这属于 "有且仅有一次"的超长延时,可以通过StartupProbe探针解决该问题。

以上探针均可配置以下 三 种实现方式:

  • ExecAction: 在容器内部运行一个命令,如果该命令的返回码为0,则表明容器健康。
  • TCPSocketAction: 通过容器的IP地址和端口号执行TCP检查,如果能够建立TCP连接,则表明容器健康。
  • HTTPGetAction: 通过容器的IP地址,端口号及路径调用HTTP Get方法,如果响应的状态码大于等于200且小于400, 则认为容器健康。

新增的自定义Condition的状态(status)将由用户自定义的外部控制器设置,默认值为False。Kubernetes将在判断全部readinessGates条件都为True时,才设置Pod为服务可用状态(Ready 为True)。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐