downward API卷

以downward API卷的形式将元数据以文件的形式挂载至Pod中的容器中,与其他两种方式相比,其缺点主要体现在:仅可以暴露本Pod的元数据,可使用的元数据有限(比环境变量的方式多了标签和注解)。

相对于环境变量的方式,多了两种元数据,是因为Pod的标签注解是支持更新的,因此若以环境变量的方式导入,是无法实时更新的,而使用卷的方式就可以,其更新原理与ConfigMap的同步更新一样

Pod在生成后,会有自己的定义(配置文件),这种方式就是通过从定义(配置文件)和状态中取得相关数据,并将其存放至downward API卷中,进而将该卷挂载至容器中,从而被容器中的应用读取和使用。

可用元数据

该方式下,可暴露的元数据如下:

  • 本Pod的名称(metadata.name);

  • 本Pod的IP地址;(status.podIP

  • 本Pod所在的命名空间(metadata.namespace);

  • 本Pod运行的Node的名称(spec.nodeName);

  • 本Pod运行所归属的ServiceAccount名称(spec.serviceAccountName);

  • 本Pod的标签(metadata.labels);

  • 本Pod的注解(metadata.annotations);

  • 本Pod中每个容器的CPU和内存的请求量(spec.containers.resources.requests.cpu);

  • 本Pod中每个容器可使用的CPU和内存的上限(spec.containers.resources.limits.cpu);

前七种(非资源相关):pod.spec.volumes.items.fieldRef中指定(从字段名可以看出,引用的是配置文件中的相关字段);

后两种(资源相关):pod.spec.volumes.items.resourceFieldRef中指定,其中引用的是spec.containers.resources中资源请求量与使用上限等相关字段;

使用案例

由于是将元数据以downward API卷的方式传递至容器中,因此需要两步:

  1. 定义卷:在spec.volumes.downwardAPI.items中加载各元数据;

  2. 挂载卷:在Pod的spec.containers.volumeMounts中指定挂载点和挂载的卷名;

在上面介绍可用元数据时,已经提到,针对非资源相关的元数据是在pod.spec.volumes.items.fieldRef中指定的,而针对资源相关的元数据则是在pod.spec.volumes.items.resourceFieldRef中指定的。

并且在上面也介绍了各元数据所对应的Pod的配置文件中的字段。

这里展示一个案例,创建一个仅包含一个容器的Pod,并且定义downward API卷,并且将该方式支持的所有元数据都传入容器中:

apiVersion: v1
kind: Pod
metadata:
  name: downward
  labels:    # 定义Pod的标签
    foo: bar
  annotations:    # 定义Pod的注解
    key1: value1
    key2: |
      multi
      line
      value
spec:
  containers:
  - name: main
    image: busybox
    command: ["sleep", "9999999"]
    resources:    # 容器资源相关配置
      requests:    # 资源请求量
        cpu: 1m
        memory: 100Ki
      limits:    # 资源使用上限
        cpu: 2m
        memory: 100Mi
    volumeMounts: # 挂载点
    - name: downward    # 卷名
      mountPath: /etc/downward
  volumes:
  - name: downward
    downwardAPI:  # 定义downward API卷
      items:
      - path: "podName"    # 相对路径,可以理解为创建的文件名为podName
        fieldRef:    # 非资源相关元数据,使用fieldRef
          fieldPath: metadata.name    # 元数据:本Pod的名称;Pod配置文件中的字段
      - path: "podIP"
        fieldRef:
          fieldPath: status.podIP    # 元数据:本Pod的IP地址
      - path: "podNamespace"
        fieldRef:
          fieldPath: metadata.namespace    # 元数据:本Pod所在命名空间名称
      - path: "nodeName"
        fieldRef:
          fieldPath: spec.nodeName    # 元数据:本Pod所在Node名称
      - path: "serviceAccountName"
        fieldRef:
          fieldPath: spec.serviceAccountName    # 元数据:本Pod所属的ServiceAccount名称
      - path: "labels"
        fieldRef:
          fieldPath: metadata.labels    # 元数据:本Pod的标签
      - path: "annotations"
        fieldRef:
          fieldPath: metadata.annotations    # 元数据:本Pod的注解
      - path: "containerCpuRequestMilliCores"
        resourceFieldRef:    # 资源相关元数据,使用resourceFieldRef
          containerName: main    # 由于volumes与容器同级别,因此这里需指定容器名
          resource: requests.cpu    # Pod配置文件中pod.spec.containers.resources中的字段;元数据:本Pod中名为main的容器的CPU请求量
          divisor: 1m    # 基数,例如本容器requests.cpu=1m,因此这里显示为1(1m/1m=1)
      - path: "containerMemoryRequestBytes"
        resourceFieldRef:
          containerName: main
          resource: requests.memory    # 元数据:本Pod中名为main的容器的内存请求量
          divisor: 1    # 基数,不写单位则为Bytes,因此这里显示为102400(1Ki/1Bytes=102400Bytes)
      - path: "containerCpuLimitMilliCores"
        resourceFieldRef:
          containerName: main
          resource: limits.cpu    # 元数据:本Pod中名为main的容器的可使用CPU上限
          divisor: 1m
      - path: "containerMemoryLimitBytes"
        resourceFieldRef:
          containerName: main
          resource: limits.memory    # 元数据:本Pod中名为main的容器的可使用内存上限
          divisor: 1

Last updated

Was this helpful?