设置命令、参数和环境变量
同普通的应用一样,容器化应用也可以通过命令行参数、环境变量、文件等完成配置。
比如容器启动时执行的命令可以由 Dockerfile 中的 ENTRYPOINT
选项指定;命令参数通常由 CMD
选项指定;环境变量则可以使用 ENV
选项指定;假如应用通过文件进行配置,则这些配置文件可以借助 COPY
选项复制到容器镜像中。
下面是一个名为 kiada
的示例应用。Dockerfile
配置文件:1
2
3
4
5
6
7
8FROM 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"]
其他文件如 html
、app.js
可以从作者的 Github 处获取。同时构建好的镜像也被作者放到了 Dockerhub 的 luksa/kiada:0.4
位置。
借助上述 Dockerfile,应用的监听端口可以通过 --listen-port
命令参数配置;同时应用会读取环境变量 INITIAL_STATUS_MESSAGE
来获取初始状态信息。
将配置硬编码进容器的镜像,事实上和将配置硬编码到应用的源代码中一样,都不是理想的情况。因为每当应用需要修改配置,都必须再重新 build 一遍镜像。此外,还必须避免在镜像中包含敏感的配置信息,比如认证数据或密钥等。
将上述配置文件放置在 Volume 中并挂载到容器上,相对而言更安全一点。
配置命令和参数
在创建镜像时,容器启动时执行的命令和参数分别由 Dockerfile 中的 ENTRYPOINT
和 CMD
选项指定。
Kubernetes 提供了两个同样功能的字段:commands
和 args
。假如在 Pod 的清单文件中指定了 commands
和 args
,或者其中任何一个字段,则 Dockerfile 中对应的 ENTRYPOINT
和 CMD
配置会被覆盖。
设置命令
假如需要在运行 Kiada 应用时启用 CPU 和 heap 优化,对于 Node.js 而言,可以在执行时传入 --cpu-prof
和 --heap-prof
参数。
相对于修改 Dockerfile 重新 build 镜像,其实可以直接修改 Pod 的清单文件。1
2
3
4
5
6
7
8
9
10
11
12
13
14apiVersion: 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 清单文件:1
2
3
4
5
6
7
8
9
10
11
12
13
14apiVersion: 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
选项。
示例清单文件如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16apiVersion: 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 清单文件并查看效果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 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)
格式引用其他变量。如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16apiVersion: 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 清单文件中定义的变量,且该变量必须在引用位置之前定义。
在命令和参数中使用变量引用
还可以在命令和参数中引用清单文件中定义的变量。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17apiVersion: 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 作为文件挂载到容器的文件系统中。
将配置保存在一个独立的 ConfigMap 对象中,而不是直接保存在 Pod 里。这使得在不同的环境中能够部署同一个 Pod 清单文件,与此同时应用不同的配置(引用不同的 ConfigMap 对象)。
创建 ConfigMap 对象
从 YAML 文件创建 ConfigMapcm.kiada-config.yml
:1
2
3
4
5
6apiVersion: 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 对象:1
2
3
4 kubectl get cm
NAME DATA AGE
kiada-config 1 6s
kube-root-ca.crt 1 55d
可以使用如下命令查看 ConfigMap 的详细信息:1
2
3
4
5
6
7
8
9
10
11
12
13
14 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 中的配置项,可以使用如下命令:1
2
3
4
5
6 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18apiVersion: 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 并查看环境变量:1
2
3
4
5
6
7 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
:1
2
3
4
5
6apiVersion: 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:1
2$ kubectl replace -f cm.kiada-config.yml
configmap/kiada-config replaced
创建 Pod 清单文件 pod.kiada.envFrom.yml
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15apiVersion: 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 清单文件并查看效果:1
2
3
4
5
6
7
8
9kubectl 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 清单文件,从而可以将其保存到版本控制系统中。1
2
3
4 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
文件的具体内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17apiVersion: 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
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26apiVersion: 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:1
2
3
4
5
6
7 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 并查看文件挂载情况:1
2
3
4
5 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
目录,又不影响原来存在的文件,可以结合使用 mountPath
和 subPath
。1
2
3
4
5
6
7spec:
containers:
- name: my-container
volumeMounts:
- name: my-volume
subPath: my-app.conf
mountPath: /etc/my-app.conf
ConfigMap volumes 使用符号链接来实现原子化更新
有些应用会监控其配置文件的变化来决定是否重新加载配置。但是,假如应用的配置文件很大或者涉及到很多文件,应用可能会在所有更新全部完成之前检查到变化并加载更新。若应用最终读取了未全部更新的文件,可能导致出现不正常的行为。
为了防止上述情况发生,Kubernetes 会确保 ConfigMap volume 中所有文件的更新操作是原子的,即所有更新都会立即完成。
上述机制是通过文件的符号链接实现的。1
2
3
4
5
6 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
上面的命令会使用系统默认的编辑器(比如 Vim
)打开 ConfigMap kiada-config
的清单文件,允许用户直接修改该 ConfigMap 对象。当关闭编辑器时,最新的改动会自动应用到 Kubernetes API server。
修改 ConfigMap 的影响
当更新某个 ConfigMap 后,若 ConfigMap 是以存储卷的形式作为配置文件挂载到容器中,则其中的文件会自动进行更新。
但是不同于文件,环境变量在容器运行时不会自动进行更新。然而当容器因为某些特殊原因重启后,Kubernetes 会使用最新版本的 ConfigMap 值来初始化新容器的环境变量。
容器最重要的属性之一就是其不变性,即用户可以肯定同一个容器的多个实例一定是相同的。
假如应用通过 ConfigMap 以环境变量的方式注入配置,当 ConfigMap 修改后,实际上并不会影响正在运行的应用实例。但是当应用的某一部分实例因为故障重新启动,或者需要添加新的实例副本,就会导致只有这一部分实例在使用最新的配置。
类似的场景甚至发生在应用自动重新加载其配置文件的时候。Kubernetes 对于 ConfigMap volumes 采用异步的更新方式,这导致某些实例可能会比其他实例更早地看到配置的变化。上述更新操作有可能会持续几十秒的时间,则在这部分时间内,各应用实例上的配置文件之间实际上是不同步的。
从而也会导致应用的各个容器实例之间正使用着不同的配置。
阻止 ConfigMap 被修改1
2
3
4
5
6
7
8apiVersion: 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 secret1
2 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
选项。1
2
3
4
5
6
7
8
9
10
11
12 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 中的文本数据。1
2
3
4
5
6
7
8apiVersion: 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
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41apiVersion: 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
通过 Downward API 向应用传递 Pod 的元数据
前面介绍了如何向容器中的应用传递配置信息。但数据并不总是静态的,假如某些数据只有在 Pod 创建之后才能被知晓,比如 Pod 的 IP 地址、工作节点的名称、容器分配到的 CPU 和内存等。
这些需求可以通过 Downward API 实现。
Downward API 介绍
Downward API 并不是一个需要应用去访问的 REST 端点,它实际上是一种将 Pod 的 metadata、spec 和 status 字段注入到容器中的方式。
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
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28apiVersion: 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
清单文件并查看其日志输出:1
2
3
4
5
6
7
8
9
10
11
12
13 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
注入容器的资源数据
示例配置如下:1
2
3
4
5
6
7
8
9
10env:
- name: MAX_CPU_CORES
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: MAX_MEMORY_KB
valueFrom:
resourceFieldRef:
resource: limits.memory
divisor: 1k