7.5. 允许容器消耗 API 对象

Downward API 是一种允许容器消耗 API 对象的相关信息且不与 OpenShift Container Platform 耦合的机制。此类信息包括 pod 的名称、命名空间和资源值。容器可以使用环境变量或卷插件来消耗来自 Downward API 的信息。

7.5.1. 使用 Downward API 向容器公开 Pod 信息

Downward API 包含 pod 的名称、项目和资源值等信息。容器可以使用环境变量或卷插件来消耗来自 Downward API 的信息。

pod 中的字段通过 FieldRef API 类型来选择。FieldRef 有两个字段:

字段描述

fieldPath

要选择的字段的路径,这相对于 pod。

apiVersion

要在其中解释 fieldPath 选择器的 API 版本。

目前,v1 API 中的有效选择器包括:

选择器描述

metadata.name

pod 的名称。在环境变量和卷中均受支持。

metadata.namespace

pod 的命名空间。在环境变量和卷中均受支持。

metadata.labels

pod 的标签。仅在卷中支持,环境变量中不支持。

metadata.annotations

pod 的注解。仅在卷中支持,环境变量中不支持。

status.podIP

pod 的 IP。仅在环境变量中支持,卷中不支持。

若未指定 apiVersion 字段,则默认为所属 pod 模板的 API 版本。

7.5.2. 了解如何通过 Downward API 消耗容器值

容器可以使用环境变量或卷插件来消耗 API 值。根据您选择的方法,容器可以消耗:

  • Pod 名称
  • Pod 项目/命名空间
  • Pod 注解
  • Pod 标签

注解和标签只能通过卷插件来使用。

7.5.2.1. 使用环境变量消耗容器值

在使用容器的环境变量时,请使用 EnvVar 类型的 valueFrom 字段(类型为 EnvVarSource)来指定变量的值应来自 FieldRef 源,而非 value 字段指定的字面值。

只有 pod 常量属性可以这种方式消耗,因为一旦进程启动并且将变量值已更改的通知发送给进程,就无法更新环境变量。使用环境变量支持的字段包括:

  • Pod 名称
  • Pod 项目/命名空间

流程

  1. 创建一个新的 pod spec,其中包含您希望容器使用的环境变量:

    1. 创建类似以下示例的 pod.yaml 文件:

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: MY_POD_NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
        restartPolicy: Never
      # ...
    2. pod.yaml 文件创建 pod:

      $ oc create -f pod.yaml

验证

  • 检查容器的日志,以查看 MY_POD_NAMEMY_POD_NAMESPACE 值:

    $ oc logs -p dapi-env-test-pod

7.5.2.2. 使用卷插件消耗容器值

容器可以使用卷插件来消耗 API 值。

容器可以消耗:

  • Pod 名称
  • Pod 项目/命名空间
  • Pod 注解
  • Pod 标签

流程

使用卷插件:

  1. 创建一个新的 pod spec,其中包含您希望容器使用的环境变量:

    1. 创建一个类似如下的 volume-pod.yaml 文件:

      kind: Pod
      apiVersion: v1
      metadata:
        labels:
          zone: us-east-coast
          cluster: downward-api-test-cluster1
          rack: rack-123
        name: dapi-volume-test-pod
        annotations:
          annotation1: "345"
          annotation2: "456"
      spec:
        containers:
          - name: volume-test-container
            image: gcr.io/google_containers/busybox
            command: ["sh", "-c", "cat /tmp/etc/pod_labels /tmp/etc/pod_annotations"]
            volumeMounts:
              - name: podinfo
                mountPath: /tmp/etc
                readOnly: false
        volumes:
        - name: podinfo
          downwardAPI:
            defaultMode: 420
            items:
            - fieldRef:
                fieldPath: metadata.name
              path: pod_name
            - fieldRef:
                fieldPath: metadata.namespace
              path: pod_namespace
            - fieldRef:
                fieldPath: metadata.labels
              path: pod_labels
            - fieldRef:
                fieldPath: metadata.annotations
              path: pod_annotations
        restartPolicy: Never
      # ...
    2. volume-pod.yaml 文件创建 pod:

      $ oc create -f volume-pod.yaml

验证

  • 检查容器的日志,并验证配置的字段是否存在:

    $ oc logs -p dapi-volume-test-pod

    输出示例

    cluster=downward-api-test-cluster1
    rack=rack-123
    zone=us-east-coast
    annotation1=345
    annotation2=456
    kubernetes.io/config.source=api

7.5.3. 了解如何使用 Downward API 消耗容器资源

在创建 pod 时,您可以使用 Downward API 注入关于计算资源请求和限制的信息,以便镜像和应用程序作者能够正确地为特定环境创建镜像。

您可以使用环境变量或卷插件进行此操作。

7.5.3.1. 使用环境变量消耗容器资源

在创建 pod 时,您可以利用环境变量来使用 Downward API 注入有关计算资源请求和限制的信息。

在创建 pod 配置时,在 spec.container 字段中指定与 resources 字段的内容对应的环境变量。

注意

如果容器配置中没有包含资源限制,Downward API 会默认使用节点的 CPU 和内存可分配量。

流程

  1. 创建一个新的 pod 规格,其中包含您要注入的资源:

    1. 创建类似以下示例的 pod.yaml 文件:

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: test-container
            image: gcr.io/google_containers/busybox:1.24
            command: [ "/bin/sh", "-c", "env" ]
            resources:
              requests:
                memory: "32Mi"
                cpu: "125m"
              limits:
                memory: "64Mi"
                cpu: "250m"
            env:
              - name: MY_CPU_REQUEST
                valueFrom:
                  resourceFieldRef:
                    resource: requests.cpu
              - name: MY_CPU_LIMIT
                valueFrom:
                  resourceFieldRef:
                    resource: limits.cpu
              - name: MY_MEM_REQUEST
                valueFrom:
                  resourceFieldRef:
                    resource: requests.memory
              - name: MY_MEM_LIMIT
                valueFrom:
                  resourceFieldRef:
                    resource: limits.memory
      # ...
    2. pod.yaml 文件创建 pod:

      $ oc create -f pod.yaml

7.5.3.2. 使用卷插件消耗容器资源

在创建 pod 时,您可以利用卷插件来使用 Downward API 注入有关计算资源请求和限制的信息。

在创建 pod 配置时,使用 spec.volumes.downwardAPI.items 字段来描述与 spec.resources 字段对应的所需资源:

注意

如果容器配置中没有包含资源限制,Downward API 会默认使用节点的 CPU 和内存可分配量。

流程

  1. 创建一个新的 pod 规格,其中包含您要注入的资源:

    1. 创建类似以下示例的 pod.yaml 文件:

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: client-container
            image: gcr.io/google_containers/busybox:1.24
            command: ["sh", "-c", "while true; do echo; if [[ -e /etc/cpu_limit ]]; then cat /etc/cpu_limit; fi; if [[ -e /etc/cpu_request ]]; then cat /etc/cpu_request; fi; if [[ -e /etc/mem_limit ]]; then cat /etc/mem_limit; fi; if [[ -e /etc/mem_request ]]; then cat /etc/mem_request; fi; sleep 5; done"]
            resources:
              requests:
                memory: "32Mi"
                cpu: "125m"
              limits:
                memory: "64Mi"
                cpu: "250m"
            volumeMounts:
              - name: podinfo
                mountPath: /etc
                readOnly: false
        volumes:
          - name: podinfo
            downwardAPI:
              items:
                - path: "cpu_limit"
                  resourceFieldRef:
                    containerName: client-container
                    resource: limits.cpu
                - path: "cpu_request"
                  resourceFieldRef:
                    containerName: client-container
                    resource: requests.cpu
                - path: "mem_limit"
                  resourceFieldRef:
                    containerName: client-container
                    resource: limits.memory
                - path: "mem_request"
                  resourceFieldRef:
                    containerName: client-container
                    resource: requests.memory
      # ...
    2. volume-pod.yaml 文件创建 pod:

      $ oc create -f volume-pod.yaml

7.5.4. 使用 Downward API 消耗 secret

在创建 pod 时,您可以使用 Downward API 注入 Secret,以便镜像和应用程序作者能够为特定环境创建镜像。

流程

  1. 创建要注入的 secret:

    1. 创建一个类似如下的 secret.yaml 文件:

      apiVersion: v1
      kind: Secret
      metadata:
        name: mysecret
      data:
        password: <password>
        username: <username>
      type: kubernetes.io/basic-auth
    2. secret.yaml 文件创建 secret 对象:

      $ oc create -f secret.yaml
  2. 创建引用上述 Secret 对象中的 username 字段的 pod:

    1. 创建类似以下示例的 pod.yaml 文件:

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_SECRET_USERNAME
                valueFrom:
                  secretKeyRef:
                    name: mysecret
                    key: username
        restartPolicy: Never
      # ...
    2. pod.yaml 文件创建 pod:

      $ oc create -f pod.yaml

验证

  • 检查容器日志中的 MY_SECRET_USERNAME 值:

    $ oc logs -p dapi-env-test-pod

7.5.5. 使用 Downward API 消耗配置映射

在创建 pod 时,您可以使用 Downward API 注入配置映射值,以便镜像和应用程序作者能够为特定环境创建镜像。

流程

  1. 使用要注入的值创建配置映射:

    1. 创建类似如下的 configmap.yaml 文件:

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: myconfigmap
      data:
        mykey: myvalue
    2. configmap.yaml 文件创建配置映射:

      $ oc create -f configmap.yaml
  2. 创建引用上述配置映射的 pod:

    1. 创建类似以下示例的 pod.yaml 文件:

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_CONFIGMAP_VALUE
                valueFrom:
                  configMapKeyRef:
                    name: myconfigmap
                    key: mykey
        restartPolicy: Always
      # ...
    2. pod.yaml 文件创建 pod:

      $ oc create -f pod.yaml

验证

  • 检查容器日志中的 MY_CONFIGMAP_VALUE 值:

    $ oc logs -p dapi-env-test-pod

7.5.6. 引用环境变量

在创建 pod 时,您可以使用 $() 语法引用之前定义的环境变量的值。如果无法解析环境变量引用,则该值将保留为提供的字符串。

流程

  1. 创建引用现有环境变量的 pod:

    1. 创建类似以下示例的 pod.yaml 文件:

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_EXISTING_ENV
                value: my_value
              - name: MY_ENV_VAR_REF_ENV
                value: $(MY_EXISTING_ENV)
        restartPolicy: Never
      # ...
    2. pod.yaml 文件创建 pod:

      $ oc create -f pod.yaml

验证

  • 检查容器日志中的 MY_ENV_VAR_REF_ENV 值:

    $ oc logs -p dapi-env-test-pod

7.5.7. 转义环境变量引用

在创建 pod 时,您可以使用双美元符号来转义环境变量引用。然后,其值将设为所提供值的单美元符号版本。

流程

  1. 创建引用现有环境变量的 pod:

    1. 创建类似以下示例的 pod.yaml 文件:

      apiVersion: v1
      kind: Pod
      metadata:
        name: dapi-env-test-pod
      spec:
        containers:
          - name: env-test-container
            image: gcr.io/google_containers/busybox
            command: [ "/bin/sh", "-c", "env" ]
            env:
              - name: MY_NEW_ENV
                value: $$(SOME_OTHER_ENV)
        restartPolicy: Never
      # ...
    2. pod.yaml 文件创建 pod:

      $ oc create -f pod.yaml

验证

  • 检查容器日志中的 MY_NEW_ENV 值:

    $ oc logs -p dapi-env-test-pod