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

我们知道,Pod的逻辑概念在容器之上,Kubernetes在成功创建Pod之后,会为Pod和容器设置一些额外的信息,例如Pod级别的Pod名称、Pod IP、Node IP、Label、Annotation、容器级别的资源限制等。在很多应用场景中,这些信息对容器内的应用来说都很有用,例如使用Pod名称作为日志记录的一个字段用于标识日志来源。为了在容器内获取Pod级别的这些信息,Kubernetes提供了Downward API机制来将Pod和容器的某些元数据信息注入容器环境内,供容器应用方便地使用。

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

(1)环境变量:将Pod或Container信息设置为容器内的环境变量。

(2)Volume挂载:将Pod或Container信息以文件的形式挂载到容器内部。

下面通过几个例子对Downward API的用法进行说明。

3.6.1 环境变量方式

通过环境变量的方式可以将Pod信息或Container信息注入容器运行环境中,下面通过两个例子进行说明。

1)将Pod信息设置为容器内的环境变量

下面的例子通过Downward API将Pod的IP、名称和所在命名空间注入容器的环境变量中,Pod的YAML文件内容如下:

注意,环境变量不直接设置value,而是设置valueFrom对Pod的元数据进行引用。

在本例中通过对Downward API的设置使用了以下Pod的元数据信息设置环境变量。

◎ spec.nodeName:Pod所在Node的名称。

◎ metadata.name:Pod名称。

◎ metadata.namespace:Pod所在命名空间的名称。

◎ status.podIP:Pod的IP地址。

◎ spec.serviceAccountName:Pod使用的ServiceAccount名称。

运行kubectl create命令创建这个Pod:

查看Pod的日志,可以看到容器启动命令将环境变量的值打印出来:

我们从日志中可以看到Pod的Node IP、Pod名称、命名空间名称、Pod IP、ServiceAccount名称等信息都被正确设置到了容器的环境变量中。

也可以通过kubectl exec命令登录容器查看环境变量的设置:

2)将Container信息设置为容器内的环境变量

下面的例子通过Downward API将Container的资源请求和资源限制信息设置为容器内的环境变量,Pod的YAML文件内容如下:

在本例中通过Downward API将以下Container的资源限制信息设置为环境变量。

◎ requests.cpu:容器的CPU请求值。

◎ limits.cpu:容器的CPU限制值。

◎ requests.memory:容器的内存请求值。

◎ limits.memory:容器的内存限制值。

运行kubectl create命令创建Pod:

查看Pod的日志:

我们从日志中可以看到Container的requests.cpu、limits.cpu、requests.memory、limits.memory等信息都被正确保存到了容器内的环境变量中。

3.6.2 Volume挂载方式

通过Volume挂载方式可以将Pod信息或Container信息挂载为容器内的文件,下面通过两个例子进行说明。

1)将Pod信息挂载为容器内的文件

下面的例子通过Downward API将Pod的Label、Annotation信息通过Volume挂载为容器中的文件:

在Pod的volumes字段中使用Downward API的方法:通过fieldRef字段设置需要引用Pod的元数据信息,将其设置到volume的items中。在本例中使用了以下Pod元数据信息。

◎ metadata.labels:Pod的Label列表。

◎ metadata.namannotations:Pod的Annotation列表。

然后,通过容器级别volumeMounts的设置,系统会基于volume中各item的path名称生成文件。根据上面的设置,系统将在容器内的/etc/podinfo目录下生成labels和annotations两个文件,在labels文件中将包含Pod的全部Label列表,在annotations文件中将包含Pod的全部Annotation列表。

运行kubectl create命令创建Pod:

查看Pod的日志,可以看到容器启动命令将挂载文件的内容打印出来:

进入容器,查看挂载的文件:

查看文件labels的内容:

2)将Container信息挂载为容器内的文件

下面的例子通过Downward API将Container的资源限制信息通过Volume挂载为容器中的文件:

在本例中通过Downward API设置将以下Container的资源限制信息设置到Volume中。

◎ requests.cpu:容器的CPU请求值。

◎ limits.cpu:容器的CPU限制值。

◎ requests.memory:容器的内存请求值。

◎ limits.memory:容器的内存限制值。

运行kubectl create命令创建Pod:

查看Pod的日志,可以看到容器启动命令将挂载文件的内容打印出来:

进入容器,查看挂载的文件:

查看文件cpu_limit的内容:

3.6.3 Downward API支持设置的Pod和Container信息

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

1)可以通过fieldRef设置的元数据如下。

◎ metadata.name:Pod名称。

◎ metadata.namespace:Pod所在的命名空间名称。

◎ metadata.uid:Pod的UID,从Kubernetes 1.8.0-alpha.2版本开始支持。

◎ metadata.labels['<KEY>']:Pod某个Label的值,通过<KEY>进行引用,从Kubernetes 1.9版本开始支持。

◎ metadata.annotations['<KEY>']:Pod某个Annotation的值,通过<KEY>进行引用,从Kubernetes 1.9版本开始支持。

2)可以通过resourceFieldRef设置的数据如下。

◎ Container级别的CPU Limit。

◎ Container级别的CPU Request。

◎ Container级别的Memory Limit。

◎ Container级别的Memory Request。

◎ Container级别的临时存储空间(ephemeral-storage)Limit,从Kubernetes 1.8.0-beta.0版本开始支持。

◎ Container级别的临时存储空间(ephemeral-storage)Request,从Kubernetes 1.8.0-beta.0版本开始支持。

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的名称,从Kubernetes 1.4.0-alpha.3版本开始支持。

◎ status.hostIP:Pod所在Node的IP地址,从Kubernetes 1.7.0-alpha.1版本开始支持。

Downward API在volume subPath中的应用

有时,容器内挂载目录的子路径(volumeMounts.subPath)也需要使用Pod或Container的元数据信息,Kubernetes从1.11版本开始支持通过Downward API对子路径的名称进行设置,引入了一个新的subPathExpr字段,到1.17版本达到Stable阶段。用户可以将Pod或Container信息先使用Downward API设置到环境变量上,再通过subPathExpr将其设置为subPath的名称。

通过Kubernetes提供的Downward API机制,只需经过一些简单配置,容器内的应用就可以直接使用Pod和容器的某些元数据信息了。