0. 概述

在 Kubernetes 中运行 Pod 的时候,有时为了识别 Pod,我们需要将 Pod 的元数据传递进 Pod 内部的应用中,本文会介绍两种实现方法,同时比较为什么 Downward API 是比较好的一种方式。

1. Pod 元数据

在 Kubernetes 中,目前可以传递给容器的 Pod 元数据有:

2. 环境变量

第一种传递 Pod 元数据的方式就是通过环境变量,这个跟其他传递参数的方式类似,这里简单给个示例:

[[email protected]]# cat env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: downward-env
spec:
  containers:
  - name: main
    image: busybox
    command: ["sleep", "9999999"]
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name

然后添加到 Kubernetes 中之后,我们再尝试一下查看容器内部的环境变量:

[[email protected]]# kubectl apply -f env.yaml
[[email protected]]# kubectl exec -it downward-env /bin/sh
/ # env | grep POD
POD_NAME=downward-env

可以确认这里真实地将 Pod 的元数据传输进了容器内部。但是这种方法和其他用环境变量的形式有着相同的硬伤,那就是不知道更新操作,例如,你修改了 Pod 的标签,内部是没法感知到的,所以这个方法比较少用。

3. Downward API

另外一种更常用的方法是通过 Downward API 的形式传递,所谓的 Downward API 形式其实就是创建一个 Downward Volume,然后挂载到容器中。这里就来一个例子看一下如何创建这个 Volume:

[[email protected]]# cat volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: downward-volume
  labels:
    foo: bar
spec:
  containers:
  - name: main
    image: busybox
    command: ["sleep", "9999999"]
    volumeMounts:
    - name: downward
      mountPath: /etc/downward
  volumes:
  - name: downward
    downwardAPI:
      items:
      - path: "podName"
        fieldRef:
          fieldPath: metadata.name
      - path: "containerMemoryLimitBytes"
        resourceFieldRef:
          containerName: main
          resource: limits.memory
          divisor: 1

这就是一个简单的使用 Downward Volume 的示例,这里挂载了两个字段,分别是 PodName 和内存使用限制量,然后还是进容器里面看一下:

[[email protected]]# k apply -f volume.yaml
pod/downward-volume created
[[email protected]]# kubectl exec -it downward-volume /bin/sh
/ # cat /etc/downward/podName 
downward-volume
/ # cat /etc/downward/containerMemoryLimitBytes 
7433805824
/ #

可以看到,可以通过读取文件直接地获取到这些元数据的值。如果你足够细心,你可能会发现上面的 Downward Volume 中取值的定义有点不一样,这个在我前面列举可以使用的元数据列表时其实也已经给出了原因了。因为资源用量是容器级别的,而 Pod 名称这些都是 Pod 级别的,这也就意味着:在暴露容器级别的元数据的时候,必须指定容器的名称,对于单容器 Pod 同样适用。

4. 小结

本文介绍了一下如何往容器中传递 Pod 的元数据,并且分别介绍了两种方式:环境变量方式和卷挂载方式,并且指出了大多数元数据(不可变)都可以通过两种方式进行传递,但是,对于 Label 和 Annotation 这种可变的数据,只能通过 Volume 来挂载,不然,将无法在容器中感知到资源的变化。