Kubernetes in Action 笔记 —— 使用 ConfigMaps、Secrets 和 Downward API 配置应用

设置命令、参数和环境变量

同普通的应用一样,容器化应用也可以通过命令行参数、环境变量、文件等完成配置。
比如容器启动时执行的命令可以由 Dockerfile 中的 ENTRYPOINT 选项指定;命令参数通常由 CMD 选项指定;环境变量则可以使用 ENV 选项指定;假如应用通过文件进行配置,则这些配置文件可以借助 COPY 选项复制到容器镜像中。

下面是一个名为 kiada 的示例应用。
Dockerfile 配置文件:

FROM node:12
COPY app.js /app.js
COPY html /html

ENV INITIAL_STATUS_MESSAGE="This is the default status message"

ENTRYPOINT ["node", "app.js"]
CMD ["--listen-port", "8080"]

其他文件如 htmlapp.js 可以从作者的 Github 处获取。同时构建好的镜像也被作者放到了 Dockerhub 的 luksa/kiada:0.4 位置。

借助上述 Dockerfile,应用的监听端口可以通过 --listen-port 命令参数配置;同时应用会读取环境变量 INITIAL_STATUS_MESSAGE 来获取初始状态信息。

将配置硬编码进容器的镜像,事实上和将配置硬编码到应用的源代码中一样,都不是理想的情况。因为每当应用需要修改配置,都必须再重新 build 一遍镜像。此外,还必须避免在镜像中包含敏感的配置信息,比如认证数据或密钥等。
将上述配置文件放置在 Volume 中并挂载到容器上,相对而言更安全一点。

配置命令和参数

在创建镜像时,容器启动时执行的命令和参数分别由 Dockerfile 中的 ENTRYPOINTCMD 选项指定。
Kubernetes 提供了两个同样功能的字段:commandsargs。假如在 Pod 的清单文件中指定了 commandsargs,或者其中任何一个字段,则 Dockerfile 中对应的 ENTRYPOINTCMD 配置会被覆盖。

设置命令
假如需要在运行 Kiada 应用时启用 CPU 和 heap 优化,对于 Node.js 而言,可以在执行时传入 --cpu-prof--heap-prof 参数。
相对于修改 Dockerfile 重新 build 镜像,其实可以直接修改 Pod 的清单文件。

apiVersion: v1
kind: Pod
spec:
  containers:
  - name: kiada
    image: luksa/kiada:0.4
    command:
    - node
    - --cpu-prof
    - --heap-prof
    - app.js
    ports:
    - name: http
      containerPort: 8080

设置命令参数
比如需要将 Dockerfile 中的命令参数 --listen-port 8080 改为 --listen-port 9090,可以使用如下配置的 Pod 清单文件:

apiVersion: v1
kind: Pod
metadata:
  name: kiada
spec:
  containers:
  - name: kiada
    image: luksa/kiada
    args:
    - --listen-port
    - "9090"
    ports:
    - containerPort: 9090
      name: http

容器在创建时会自动组合 Dockerfile 中的 ENTRYPOINT 和 Pod 清单文件中的 args

设置环境变量

为环境变量设置字面量值
Kiada 应用在运行时会显示 Pod 的名字,该名称由应用源代码从环境变量 POD_NAME 读取。此外还可以通过修改环境变量 INITIAL_STATUS_MESSAGE 来更改状态信息。

为了修改上述环境变量,可以向 Dockerfile 中添加 ENV 选项并重新构建镜像,但更快速的方式时向 Pod 的清单文件中添加 env 选项。
示例清单文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: kiada
spec:
  containers:
    - name: kiada
      image: luksa/kiada:0.4
      env:
      - name: POD_NAME
        value: kiada
      - name: INITIAL_STATUS_MESSAGE
        value: This status message is set in the pod spec.
      ports:
      - name: http
        containerPort: 8080

应用上述 Pod 清单文件并查看效果:

$ kubectl apply -f kiada-env.yml
pod/kiada unchanged
$ kubectl exec kiada -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kiada
POD_NAME=kiada
INITIAL_STATUS_MESSAGE=This status message is set in the pod spec.
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
NODE_VERSION=16.11.1
YARN_VERSION=1.22.15
HOME=/root

使用变量引用
除了给环境变量设置一个固定值外,还可以采用 $(VAR_NAME) 格式引用其他变量。如:

apiVersion: v1
kind: Pod
metadata:
  name: kiada
spec:
  containers:
  - name: kiada
    image: luksa/kiada:0.4
    env:
    - name: POD_NAME
      value: kiada
    - name: INITIAL_STATUS_MESSAGE
      value: My name is $(POD_NAME). I run NodeJS version $(NODE_VERSION).
    ports:
    - name: http
      containerPort: 8080

引用的变量中,POD_NAME 是在同一个 Pod 清单文件中定义的,NODE_VERSION 是在容器镜像中定义的。
最终的状态信息会显示为 My name is kiada. I run NodeJS version $(NODE_VERSION).,因为此方式只支持引用同一个 Pod 清单文件中定义的变量,且该变量必须在引用位置之前定义。

在命令和参数中使用变量引用
还可以在命令和参数中引用清单文件中定义的变量。

apiVersion: v1
kind: Pod
metadata:
  name: kiada
spec:
  containers:
  - name: kiada
    image: luksa/kiada:0.4
    args:
    - --listen-port
    - $(LISTEN_PORT)
    env:
    - name: LISTEN_PORT
      value: "9090"
    ports:
    - name: http
      containerPort: 9090

使用 config map 将配置与 Pod 解耦

在前面的章节中,可以将应用的配置硬编码进 Pod 的 yaml 清单文件中。这种方式比将配置硬编码到容器镜像中要好很多,即不需要每次修改配置后都必须重新构建镜像。
但这种方式也有一定的缺陷,它意味着比如针对不同环境的部署(development、staging、production 等),可能需要多个不同版本的清单文件。
为了在多个环境下重复利用同一个清单文件,最好是将配置与 Pod 的清单文件解耦。

ConfigMaps 介绍

ConfigMap 是一种包含一系列键值对的 Kubernetes API 对象。其中的值可以是短字符串,也可以是一大段结构化的文本。Pod 可以引用一个或多个 ConfigMap 中的值。
一个 Pod 可以引用多个 ConfigMaps,多个 Pods 可以使用同一个 ConfigMap。

如下图所示,ConfigMap 中的键值对通常作为环境变量传递给 Pod,或者通过 ConfigMap Volume 作为文件挂载到容器的文件系统中。


Pods use config maps through environment variables and configMap volumes

将配置保存在一个独立的 ConfigMap 对象中,而不是直接保存在 Pod 里。这使得在不同的环境中能够部署同一个 Pod 清单文件,与此同时应用不同的配置(引用不同的 ConfigMap 对象)。


Deploying the same pod manifest and different config map manifests in different environments
创建 ConfigMap 对象

从 YAML 文件创建 ConfigMap
cm.kiada-config.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: kiada-config
data:
  status-message: This status message is set in the kiada-config config map

运行 kubectl apply -f cm.kiada-config.yml 命令创建清单文件中定义的 ConfigMap 对象。

查看 ConfigMap
可以使用 kubectl get cm 命令列出 ConfigMap 对象:

$ kubectl get cm
NAME               DATA   AGE
kiada-config       1      6s
kube-root-ca.crt   1      55d

可以使用如下命令查看 ConfigMap 的详细信息:

$ kubectl get cm kiada-config -o yaml
apiVersion: v1
data:
  status-message: This status message is set in the kiada-config config map
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"status-message":"This status message is set in the kiada-config config map"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"kiada-config","namespace":"default"}}
  creationTimestamp: "2022-01-10T05:11:35Z"
  name: kiada-config
  namespace: default
  resourceVersion: "99447"
  uid: e39e2676-2183-4582-9922-eac963b81093

若只想精确地查找 ConfigMap 中的配置项,可以使用如下命令:

$ kubectl get cm kiada-config -o json | jq .data
{
  "status-message": "This status message is set in the kiada-config config map"
}
$ kubectl get cm kiada-config -o json | jq '.data["status-message"]'
"This status message is set in the kiada-config config map"
将 ConfigMap 中的值注入到环境变量

pod.kiada.env-valueFrom.yml

apiVersion: v1
kind: Pod
metadata:
  name: kiada
spec:
  containers:
    - name: kiada
      image: luksa/kiada:0.4
      env:
      - name: INITIAL_STATUS_MESSAGE
        valueFrom:
          configMapKeyRef:
            name: kiada-config
            key: status-message
            optional: true
      ports:
        - containerPort: 8080
          name: http

创建 Pod 并查看环境变量:

$ kubectl apply -f pod.kiada.env-valueFrom.yml
pod/kiada created
$ kubectl exec kiada -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kiada
INITIAL_STATUS_MESSAGE=This status message is set in the kiada-config config map
...

注入整个 ConfigMap
容器定义中的 env 字段接收的是由值组成的列表,因此可以同时设置多个环境变量。实际上可以使用 envFrom 注入整个 ConfigMap 中定义的多个值,而无需像 valueFrom 那样分别指定每一个键。
唯一需要注意的是,ConfigMap 中的键必须与实际的环境变量名称保持一致。即之前使用的键 status-message 必须改成 INITIAL_STATUS_MESSAGE

cm.kiada-config.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: kiada-config
data:
  INITIAL_STATUS_MESSAGE: This status message is set in the kiada-config config map

使用 kubectl replace 命令更新 ConfigMap:

$ kubectl replace -f cm.kiada-config.yml
configmap/kiada-config replaced

创建 Pod 清单文件 pod.kiada.envFrom.yml

apiVersion: v1
kind: Pod
metadata:
  name: kiada
spec:
  containers:
  - name: kiada
    image: luksa/kiada:0.4
    envFrom:
    - configMapRef:
        name: kiada-config
        optional: true
    ports:
    - name: http
      containerPort: 8080

应用 Pod 清单文件并查看效果:

kubectl delete -f pod.kiada.env-valueFrom.yml
pod "kiada" deleted
$ kubectl apply -f pod.kiada.envFrom.yml
pod/kiada created
$ kubectl exec kiada -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kiada
INITIAL_STATUS_MESSAGE=This status message is set in the kiada-config config map
...
将 ConfigMap 中的配置项作为文件嵌入到容器

环境变量通常用于向应用传递较小的单行的值,而多行的数据通常作为文件传递。
ConfigMap 中的配置项可以包含大块的数据,通过特殊的 ConfigMap volume 类型将这些数据以文件的形式注入到容器中。

从文件创建 ConfigMaps
除了直接在集群中创建 ConfigMap 对象之外,还可以先创建一个用于描述 ConfigMap 的 YAML 清单文件,从而可以将其保存到版本控制系统中。

$ kubectl create configmap kiada-envoy-config \
--from-file=envoy.yaml \
--from-file=dummy.bin \
--dry-run=client -o yaml > cm.kiada-envoy-config.yml

其中 dummy.bin 和 envoy.yaml 两个文件可以从作者的 Github 下载。
上述命令会创建一个名为 kiada-envoy-config 的 ConfigMap 的 YAML 描述文件。当命令中使用了 --dry-run 选项时,该命令并不会在 API server 创建新对象,而是只生成对象的定义。后续可继续运行 kubectl apply -f xxx.yml 命令创建对象。

生成的 cm.kiada-envoy-config.yml 文件的具体内容如下:

apiVersion: v1
binaryData:
  dummy.bin: n2VW39IEkyQ6Jxo+rdo5J06Vi7cz5XxZzkPOtN7MOGyXxVzWv07vUz8bxY5h4njJfZixwhPwoGepLnGZdRGw1qgpFB9HpyLsqVZ6jAwjjHD0afxxwEjb6+wofmgGmS1E3U9BZScMPZGWJK7RGzZmQOeJeDPIt/1tBvQYwzMc8wu6owky4Ri3rOY9PlFnp5VOTzvBZadW8scbqtntJeWCtJFoS0AH2y4ZFyJPJ0l0V3JpY1qunnz60CyAMO9v1DgB2PUQUG/1HH89bpzf2OyMvHUJmOTIDZOh3D7aAEuYQ/6hU0uQsQ/K7Xx/nM9TA0RzEzuh8RBoXdkAvQPP5jk7yM2DqxG/CiHVp+7CDRFWgEN2GFd76RfO+pIoOFbD1Xm4yE/JBljOA9ztwm865m3A4l2ToT2p7ZWHKmdZe8pXz4ZwIGBYDUHHNVQW5UUnf0Jbd9UR8GJ//gmbxLfVxjC/lMSWGUqCpYO4YdBPjXQGM1xdxE+YP3Pzso6Z4rw27RJu5KEc2yPMxFY9dpFyVufP81kS19glNiQq+LM4B9EFPrNW1hqi+1Tb8ni+aFkriH1YuvHepIH0Px/ifFLgn+yDgwDs4UfMru2j4t5zAftUa0i6m3sH5adKcx4aCXYN9ijvEvjRmkcB/VJU6Zbd65UZVgD1Nwt2ZCrkoEdqO3Oe1/o=
data:
  envoy.yaml: |
    admin:
      access_log_path: /tmp/envoy.admin.log
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 9901
...
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: kiada-envoy-config

在 Pod 中使用 ConfigMap
为了令 ConfigMap 能够作为文件呈现在容器的文件系统中,需要在 Pod 中定义一个 ConfigMap Volume 并将其挂载到容器里。
参考下面的 pod.kiada-ssl.configmap-volume.yml

apiVersion: v1
kind: Pod
metadata:
  name: kiada-ssl
spec:
  volumes:
  - name: envoy-config
    configMap:
      name: kiada-envoy-config
  containers:
  - name: kiada
    image: luksa/kiada:0.4
    ports:
    - name: http
      containerPort: 8080
  - name: envoy
    image: luksa/kiada-ssl-proxy:0.1
    volumeMounts:
    - name: envoy-config
      mountPath: /etc/envoy
      readOnly: true
    ports:
    - name: https
      containerPort: 8443
    - name: admin
      containerPort: 9901

创建 kiada-envoy-config ConfigMap:

$ kubectl apply -f cm.kiada-envoy-config.yml
configmap/kiada-envoy-config created
$ kubectl get cm
NAME                 DATA   AGE
kiada-config         1      46h
kiada-envoy-config   2      13s
kube-root-ca.crt     1      57d

创建 Pod 并查看文件挂载情况:

$ kubectl apply -f pod.kiada-ssl.configmap-volume.yml
pod/kiada-ssl created
$ kubectl exec kiada-ssl -c envoy -- ls /etc/envoy
dummy.bin
envoy.yaml
理解 ConfigMap Volume 是如何工作的

挂载 Volume 会隐藏文件系统中本来就存在的文件
当挂载任意 volume 到容器的文件系统中时,挂载的路径下原本存在的文件就无法被访问。比如把某个 ConfigMap volume 挂载到容器的 /etc 路径下,则本来位于 /etc 下面的配置文件都会被隐藏掉。
如果你还是想将 ConfigMap volume 挂载到 /etc 目录,又不影响原来存在的文件,可以结合使用 mountPathsubPath

spec:
  containers:
  - name: my-container
    volumeMounts:
    - name: my-volume
      subPath: my-app.conf
      mountPath: /etc/my-app.conf
Using subPath to mount a single file from the volume

ConfigMap volumes 使用符号链接来实现原子化更新
有些应用会监控其配置文件的变化来决定是否重新加载配置。但是,假如应用的配置文件很大或者涉及到很多文件,应用可能会在所有更新全部完成之前检查到变化并加载更新。若应用最终读取了未全部更新的文件,可能导致出现不正常的行为。
为了防止上述情况发生,Kubernetes 会确保 ConfigMap volume 中所有文件的更新操作是原子的,即所有更新都会立即完成。
上述机制是通过文件的符号链接实现的。

$ kubectl exec kiada-ssl -c envoy -- ls -lA /etc/envoy
total 4
drwxr-xr-x 2 root root 4096 Jan 12 03:33 ..2022_01_12_03_33_58.815959464
lrwxrwxrwx 1 root root   31 Jan 12 03:33 ..data -> ..2022_01_12_03_33_58.815959464
lrwxrwxrwx 1 root root   16 Jan 12 03:33 dummy.bin -> ..data/dummy.bin
lrwxrwxrwx 1 root root   17 Jan 12 03:33 envoy.yaml -> ..data/envoy.yaml

每次用户修改 ConfigMap,Kubernetes 都会新建一个以当前时间戳命名的目录,将新的配置文件放到该目录中。再修改符号链接的指向,立即同时替换所有文件。

更新和删除 ConfigMaps

和大多数 Kubernetes API 对象一样,ConfigMaps 也支持手动修改其清单文件,再使用 kubectl apply 命令将最新版本重新应用到集群环境。
此外还可以使用下面这种更快捷的方式。

使用 kubectl edit 就地修改 API 对象
kubectl edit cm kiada-config

kubectl edit

上面的命令会使用系统默认的编辑器(比如 Vim)打开 ConfigMap kiada-config 的清单文件,允许用户直接修改该 ConfigMap 对象。当关闭编辑器时,最新的改动会自动应用到 Kubernetes API server。

修改 ConfigMap 的影响
当更新某个 ConfigMap 后,若 ConfigMap 是以存储卷的形式作为配置文件挂载到容器中,则其中的文件会自动进行更新。
但是不同于文件,环境变量在容器运行时不会自动进行更新。然而当容器因为某些特殊原因重启后,Kubernetes 会使用最新版本的 ConfigMap 值来初始化新容器的环境变量。

容器最重要的属性之一就是其不变性,即用户可以肯定同一个容器的多个实例一定是相同的。
假如应用通过 ConfigMap 以环境变量的方式注入配置,当 ConfigMap 修改后,实际上并不会影响正在运行的应用实例。但是当应用的某一部分实例因为故障重新启动,或者需要添加新的实例副本,就会导致只有这一部分实例在使用最新的配置。
类似的场景甚至发生在应用自动重新加载其配置文件的时候。Kubernetes 对于 ConfigMap volumes 采用异步的更新方式,这导致某些实例可能会比其他实例更早地看到配置的变化。上述更新操作有可能会持续几十秒的时间,则在这部分时间内,各应用实例上的配置文件之间实际上是不同步的。
从而也会导致应用的各个容器实例之间正使用着不同的配置。

阻止 ConfigMap 被修改

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-immutable-configmap
data:
  mykey: myvalue
  another-key: another-value
immutable: true

不可变 ConfigMap 可以阻止用户意外地修改应用配置,同时也会提高 Kubernetes 集群的性能。因为工作节点上的 Kubelets 无需再接收 ConfigMap 对象变化的通知。
假如需要添加一系列使用不同配置的 Pods,就创建一个新的 ConfigMap。

删除 ConfigMap
ConfigMap 对象可以使用 kubectl delete 命令删除。删除某个 ConfigMap 后,引用它的正在运行的应用不会受到任何影响,直到容器重新启动。
若 ConfigMap 没有被标记成可选的,则容器会在重启时失败。

使用 Secrets 向容器嵌入敏感信息

Secrets 介绍

Secrets 和 ConfigMaps 非常相似。它们也是包含一系列键值对且能够作为环境变量或文件注入到容器中。
事实上 Secrets 比 ConfigMap 更早出现。但是 Secrets 在存储普通的明文文本时友好性较差,因而引入了 ConfigMaps。
对于 Secrets 对象,Kubernetes 在处理它们时会特别注意安全性。比如 Kubernetes 会确保 Secret 中的数据在分发时只传给有需要的节点;工作节点上的 Secrets 只保存在内存中,从来不会写入到物理存储。
因此,必须将敏感数据保存到 Secrets 而不是 ConfigMaps 中。

创建 Secret

创建一个 TLS secret

$ kubectl create secret tls kiada-tls --cert example-com.crt --key example-com.key
secret/kiada-tls created

其中 crt 文件和 key 文件可以从作者的 Github 下载。
上述命令会创建一个名为 kiada-tls 的 Secret。

从 YAML 清单文件创建 Secrets
显而易见,从 YAML 文件创建 Secrets 并不是一个好主意。
假如你只是需要在本地创建一个 YAML 清单文件而不是直接通过 API server 创建 Secret 对象,可以使用 kubectl create 加上 --dry-run=client -o yaml 选项。

$ kubectl create secret generic my-credentials \
--from-literal user=my-username \
--from-literal pass=my-password \
--dry-run=client -o yaml
apiVersion: v1
data:
  pass: bXktcGFzc3dvcmQ=
  user: bXktdXNlcm5hbWU=
kind: Secret
metadata:
  creationTimestamp: null
  name: my-credentials

使用 stringData 字段
因为并不是所有敏感数据都是二进制形式,Kubernetes 允许用户通过 stringData 字段指定 Secret 中的文本数据。

apiVersion: v1
kind: Secret
stringData:
  user: my-username
  pass: my-password
metadata:
  creationTimestamp: null
  name: my-credentials
在容器中使用 Secrets

借助 Secret Volume 注入 Secret 配置
Secret volume 和前面提到的 ConfigMap volume 用法基本相同。参考如下 YAML 配置文件 pod.kiada-ssl.secret-volume.yml

apiVersion: v1
kind: Pod
metadata:
  name: kiada-ssl
spec:
  volumes:
  - name: cert-and-key
    secret:
      secretName: kiada-tls
      items:
      - key: tls.crt
        path: example-com.crt
      - key: tls.key
        path: example-com.key
        mode: 0600
  - name: envoy-config
    configMap:
      name: kiada-envoy-config
      items:
      - key: envoy.yaml
        path: envoy.yaml
  containers:
  - name: kiada
    image: luksa/kiada:0.4
    ports:
    - name: http
      containerPort: 8080
  - name: envoy
    image: envoyproxy/envoy:v1.14.1
    volumeMounts:
    - name: cert-and-key
      mountPath: /etc/certs
      readOnly: true
    - name: envoy-config
      mountPath: /etc/envoy
      readOnly: true
    ports:
    - name: https
      containerPort: 8443
    - name: admin
      containerPort: 9901
Secret Volume

通过 Downward API 向应用传递 Pod 的元数据

前面介绍了如何向容器中的应用传递配置信息。但数据并不总是静态的,假如某些数据只有在 Pod 创建之后才能被知晓,比如 Pod 的 IP 地址、工作节点的名称、容器分配到的 CPU 和内存等。
这些需求可以通过 Downward API 实现。

Downward API 介绍

Downward API 并不是一个需要应用去访问的 REST 端点,它实际上是一种将 Pod 的 metadata、spec 和 status 字段注入到容器中的方式。


The Downward API exposes pod metadata through environment variables or files
Downward API 支持哪些元数据

用户并不能通过 Downward API 注入 Pod 对象中的所有字段。实际上只有一部分数据被支持,其列表如下。

通过 fieldRef 字段注入的数据

Field Description Allowed in env Allowed in volume
metadata.name Pod 的名称 Yes Yes
metadata.namespace Pod 的命名空间 Yes Yes
metadata.uid Pod 的 UID Yes Yes
metadata.labels Pod 的所有标签 No Yes
metadata.labels['key'] 某个标签的值 Yes Yes
metadata.annotations Pod 的所有注释 No Yes
metadata.annotations['key'] 某个注释的值 Yes Yes
spec.nodeName Pod 运行的工作节点的名称 Yes No
spec.serviceAccountName Pod 的服务账户 Yes No
status.podIP Pod 的 IP 地址 Yes No
status.hostIP 工作节点的 IP 地址 Yes No

通过 resourceFieldRef 字段注入的数据

Resource Field Description Allowed in env Allowed in volume
requests.cpu 容器的 CPU 请求 Yes Yes
requests.memory 容器的内存请求 Yes Yes
requests.ephemeral-storage 容器的临时存储请求 Yes Yes
limits.cpu 容器的 CPU 限制 Yes Yes
limits.memory 容器的内存限制 Yes Yes
limits.ephemeral-storage 容器的临时存储限制 Yes Yes
将 Pod 的元数据注入到环境变量中

注入 Pod 对象中的字段
kiada.yml

apiVersion: v1
kind: Pod
metadata:
  name: kiada
spec:
  containers:
  - name: kiada
    image: luksa/kiada:0.4
    env:
      - name: POD_NAME
        valueFrom:
          fieldRef:
            fieldPath: metadata.name
      - name: POD_IP
        valueFrom:
          fieldRef:
            fieldPath: status.podIP
      - name: NODE_NAME
        valueFrom:
          fieldRef:
            fieldPath: spec.nodeName
      - name: NODE_IP
        valueFrom:
          fieldRef:
            fieldPath: status.hostIP
    ports:
    - name: http
      containerPort: 8080

应用 kiada.yml 清单文件并查看其日志输出:

$ kubectl apply -f kiada.yml
pod/kiada created
$ kubectl logs -f kiada
Kiada - Kubernetes in Action Demo Application
---------------------------------------------
Kiada 0.4 starting...
Pod name is kiada
Local hostname is kiada
Local IP is 172.17.0.6
Running on node minikube
Node IP is 192.168.49.2
Status message is This is the default status message
Listening on port 8080

注入容器的资源数据
示例配置如下:

env:
  - name: MAX_CPU_CORES
    valueFrom:
      resourceFieldRef:
        resource: limits.cpu
  - name: MAX_MEMORY_KB
    valueFrom:
      resourceFieldRef:
        resource: limits.memory
        divisor: 1k

参考资料

Kubernetes in Action, Second Edition

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,601评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,367评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,249评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,539评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,967评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,929评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,098评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,825评论 0 207
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,609评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,796评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,282评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,603评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,277评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,159评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,959评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,079评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,874评论 2 277

推荐阅读更多精彩内容