5.5. 允许容器消耗 API 对象

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

5.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 版本。

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

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

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

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

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

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

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

  • Pod 名称
  • 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_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
  3. 检查容器的日志,以查看 MY_POD_NAMEMY_POD_NAMESPACE 值:

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

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

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

容器可以消耗:

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

流程

使用卷插件:

  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
  3. 检查容器的日志,并验证配置的字段是否存在:

    $ 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

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

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

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

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

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

流程

使用环境变量:

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

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

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

  2. pod.yaml 文件创建 pod:

    $ oc create -f pod.yaml

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

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

流程

使用卷插件:

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

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

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

  2. volume-pod.yaml 文件创建 pod:

    $ oc create -f volume-pod.yaml

5.5.4. 使用 Downward API 消耗 secret

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

流程

  1. 创建 secret.yaml 文件:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    data:
      password: cGFzc3dvcmQ=
      username: ZGV2ZWxvcGVy
    type: kubernetes.io/basic-auth
  2. 从 secret.yaml 文件创建 Secret

    $ oc create -f secret.yaml
  3. 创建 pod.yaml 文件来引用上述 Secret 中的 username 字段:

    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
  4. pod.yaml 文件创建 pod:

    $ oc create -f pod.yaml
  5. 检查容器日志中的 MY_SECRET_USERNAME 值:

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

5.5.5. 使用 downward API 消耗配置映射

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

流程

  1. 创建 configmap.yaml 文件:

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

    $ oc create -f configmap.yaml
  3. 创建 pod.yaml 文件来引用上述 ConfigMap

    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
  4. pod.yaml 文件创建 pod:

    $ oc create -f pod.yaml
  5. 检查容器日志中的 MY_CONFIGMAP_VALUE 值:

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

5.5.6. 引用环境变量

在创建 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
  3. 检查容器日志中的 MY_ENV_VAR_REF_ENV 值:

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

5.5.7. 转义环境变量引用

在创建 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
  3. 检查容器日志中的 MY_NEW_ENV 值:

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