2.Pod的配置管理
2.1 ConfigMap的產(chǎn)生背景
-
外置化配置映射到容器內(nèi)
應(yīng)用部署的一個最佳實踐是將應(yīng)用所需的配置信息與程序進(jìn)行分離,這樣可以使應(yīng)用程序被更好地復(fù)用,通過不同的配置也能實現(xiàn)更靈活的功能。將應(yīng)用打包為容器鏡像后,
可以通過環(huán)境變量或者外掛文件的方式在創(chuàng)建容器時進(jìn)行配置注入。
-
但在大規(guī)模容器集群的環(huán)境中,對多個容器進(jìn)行不同的配置將變得非常復(fù)雜
- 從Kubernetes 1.2開始提供了一種統(tǒng)一的應(yīng)用配置管理方案—ConfigMap。本節(jié)對ConfigMap的概念和用法進(jìn)行詳細(xì)描述。
2.2 ConfigMap概述
ConfigMap供容器使用的典型用法如下
1. 生成為容器內(nèi)的環(huán)境變量。
2. 設(shè)置容器啟動命令的啟動參數(shù)(需設(shè)置為環(huán)境變量)。
3. 以Volume的形式掛載為容器內(nèi)部的文件或目錄。
? ConfigMap以一個或多個key:value的形式保存在Kubernetes系統(tǒng)中供應(yīng)用使用,既可以用于表示一個變量的值(例如apploglevel=info),也可以用于表示一個完整配置文件的內(nèi)容(例如server.xml=<?xml...>...)
? 可以通過YAML配置文件或者直接使用kubectl create configmap命令行的方式來創(chuàng)建ConfigMap。
2.3 創(chuàng)建ConfigMap資源對象
1.通過YAML配置文件方式創(chuàng)建
例子1
? 下面的例子cm-appvars.yaml描述了將幾個應(yīng)用所需的變量定義為ConfigMap的用法:


執(zhí)行kubectl create命令創(chuàng)建該ConfigMap:

查看創(chuàng)建好的ConfigMap:

例子2
? 下面的例子cm-appconfigfiles.yaml描述了將兩個配置文件server.xml和logging.properties定義為ConfigMap的用法,設(shè)置key為配置文件的別名,value則是配置文件的全部文本內(nèi)容:


執(zhí)行kubectl create命令創(chuàng)建該ConfigMap:

查看創(chuàng)建好的ConfigMap:

查看已創(chuàng)建的ConfigMap的詳細(xì)內(nèi)容,可以看到兩個配置文件的全文:



2.通過kubectl命令行方式創(chuàng)建
?如果 <font color=green>不使用YAML文件</font>,<font color=apple green>也可以直接通過kubectl create configmap也可以創(chuàng)建ConfigMap</font>,可以使用參數(shù)--from-file或-from-literal指定內(nèi)容,并且可以在一行命令中指定多個參數(shù)。
(1)基于文件創(chuàng)建
? 通過--from-file參數(shù)從<font color=red>文件</font>中進(jìn)行創(chuàng)建,可以指定key的名稱,也可以在一個命令行中創(chuàng)建包含多個key的ConfigMap,語法為:
# kubeectl create configmap NAME --from-file=[key=]source --from-file=[key=]source
[key=]source 可以指定,默認(rèn)為文件名
例子
例子1:基于1個文件
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties
將產(chǎn)生以下 ConfigMap:
kubectl describe configmaps game-config-2
輸出類似以下內(nèi)容:
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties: #key是文件名
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
例子2.基于多個文件
# kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties
#kubectl describe configmaps game-config-2
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:#key是文件名
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties: #key是文件名
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
例子3:指定key
# kubectl create configmap game-config-3 --from-file=game-special-key=configure-pod-container/configmap/game.properties
# kubectl get configmaps game-config-3 -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:54:22Z
name: game-config-3
namespace: default
resourceVersion: "530"
selfLink: /api/v1/namespaces/default/configmaps/game-config-3
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
data:
game-special-key: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
(2)基于目錄創(chuàng)建
? 通過--from-file參數(shù)從<font color=red>目錄</font>中進(jìn)行創(chuàng)建,該目錄下的每個配置文件名都被設(shè)置為key,文件的內(nèi)容被設(shè)置為value,語法為:
# kubectl create configmap NAME --from-file=config-files-dir
例子
# 創(chuàng)建本地目錄
mkdir -p configure-pod-container/configmap/
# 將實例文件下載到 `configure-pod-container/configmap/` 目錄
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties
# 創(chuàng)建 configmap
kubectl create configmap game-config --from-file=configure-pod-container/configmap/
以上命令將 configure-pod-container/configmap 目錄下的所有文件,也就是 game.properties 和 ui.properties 打包到 game-config ConfigMap 中。你可以使用下面的命令顯示 ConfigMap 的詳細(xì)信息:
#kubectl describe configmaps game-config
Name: game-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:#key是文件名
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties:#key是文件名
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
configure-pod-container/configmap/ 目錄中的 game.properties 和 ui.properties 文件出現(xiàn)在 ConfigMap 的 data 部分。
# kubectl get configmaps game-config -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:52:05Z
name: game-config
namespace: default
resourceVersion: "516"
selfLink: /api/v1/namespaces/default/configmaps/game-config
uid: b4952dc3-d670-11e5-8cd0-68f728db1985
data:
game.properties: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
(3)基于字面值創(chuàng)建
? 使用--from-literal時會從<font color=red>字面值</font>中進(jìn)行創(chuàng)建,直接將指定的key#=value#創(chuàng)建為ConfigMap的內(nèi)容,語法為:
# kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2
例子
# kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
# kubectl get configmaps special-config -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T19:14:38Z
name: special-config
namespace: default
resourceVersion: "651"
selfLink: /api/v1/namespaces/default/configmaps/special-config
uid: dadce046-d673-11e5-8cd0-68f728db1985
data:
special.how: very
special.type: charm
2.4 在Pod中使用ConfigMap
在Pod中的使用方式:
(1)通過環(huán)境變量獲取ConfigMap中的內(nèi)容。
(2)通過Volume掛載的方式將ConfigMap中的內(nèi)容掛載為容器內(nèi)部的文件或目錄。
1.通過環(huán)境變量(env)方式使用ConfigMap
(1)使用單個 ConfigMap 中的數(shù)據(jù)定義容器環(huán)境變量
kubectl create configmap special-config --from-literal=special.how=very
將 ConfigMap 中定義的 special.how 值分配給 Pod 規(guī)范中的 SPECIAL_LEVEL_KEY 環(huán)境變量。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
#定義環(huán)境變量名
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# 環(huán)境變量的值取自special-config
name: special-config
# key為special.how
key: special.how
restartPolicy: Never #重啟策略
創(chuàng)建Pod
kubectl create -f pod-single-configmap-env-variable.yaml
使用kubectl create -f命令創(chuàng)建該Pod,由于是測試Pod,所以該Pod在執(zhí)行完啟動命令后將會退出,并且不會被系統(tǒng)自動重啟(restartPolicy=Never)。
查看該Pod的日志,可以看到啟動命令“env | grep special.how”的執(zhí)行結(jié)果如下:
# kubectl logs pod-single-configmap-env-variable
special.how = very
(2)使用多個ConfigMap的數(shù)據(jù)定義容器的環(huán)境變量
首先創(chuàng)建ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
創(chuàng)建ConfigMap
kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml
在 Pod 規(guī)范中定義環(huán)境變量
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: env-config
key: log_level
restartPolicy: Never
創(chuàng)建Pod
kubectl create -f pod-multiple-configmap-env-variable.yaml
(3)將ConfigMap中的所有鍵值對配置為容器的環(huán)境變量
? 上面都是使用了configMap中的部分key,在<font color=red>Kubernetes v1.6 和更高版本</font>中支持將所有鍵設(shè)置成容器環(huán)境變量。
例子:
創(chuàng)建一個包含多個鍵值對的 ConfigMap。
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config #該configMap名字
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
創(chuàng)建 ConfigMap:
kubectl create -f configmap-multikeys.yaml
使用 envFrom 將所有 ConfigMap 的數(shù)據(jù)定義為容器環(huán)境變量,ConfigMap 中的鍵成為 Pod 中的環(huán)境變量名稱。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
創(chuàng)建 Pod:
kubectl create -f pod-configmap-envFrom.yaml
環(huán)境變量的命名規(guī)則
? 需要說明的是,環(huán)境變量的名稱受POSIX命名規(guī)范([a-zA-Z_][a-zA-Z0-9_]*)約束,不能以數(shù)字開頭。如果包含非法字符,則系統(tǒng)將跳過該條環(huán)境變量的創(chuàng)建,并記錄一個Event來提示環(huán)境變量無法生成,但并不阻止Pod的啟動。
2.通過volumeMount使用ConfigMap
例子
本節(jié)中的示例引用了一個名為 special-config 的 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
創(chuàng)建 ConfigMap:
kubectl create -f configmap-multikeys.yaml
例1.使用存儲在 ConfigMap 中的數(shù)據(jù)填充數(shù)據(jù)卷
在 Pod 規(guī)約的 volumes 部分下添加 ConfigMap 名稱。 這會將 ConfigMap 數(shù)據(jù)添加到指定為 volumeMounts.mountPath 的目錄(在本例中為 /etc/config)。 command 部分引用存儲在 ConfigMap 中的 special.level。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts: #卷掛載
- name: config-volume #引用volume名字
mountPath: /etc/config #掛載到容器內(nèi)的目錄
volumes:
- name: config-volume # 定義volume名字
configMap:
# 引用的configMap名字,不指定items,則使用volumeMount方式在容器內(nèi)的目錄下為每個item都生成一個文件名為key的文件
name: special-config
restartPolicy: Never
創(chuàng)建 Pod:
kubectl create -f pod-configmap-volume.yaml
Pod 運行時,命令 ls /etc/config/ 產(chǎn)生下面的輸出:
SPECIAL_LEVEL #基于文件創(chuàng)建configMap, 如果不指定key,key默認(rèn)是文件名
SPECIAL_TYPE
注意:
? 如果在 /etc/config/ 目錄中有一些文件,它們將被刪除。
說明:
? 文本數(shù)據(jù)會使用 UTF-8 字符編碼的形式展現(xiàn)為文件。如果使用其他字符編碼, 可以使用 binaryData。
例2.將 ConfigMap 數(shù)據(jù)添加到數(shù)據(jù)卷中的特定路徑
? 使用 path 字段為特定的 ConfigMap 項目指定預(yù)期的文件路徑。 在這里,ConfigMap中,鍵值 SPECIAL_LEVEL 的內(nèi)容將掛載在 config-volume 數(shù)據(jù)卷中 /etc/config/keys.properties 文件下。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh","-c","cat /etc/config/keys" ] #子命令,可直接通過kubectl + command操作k8s資源
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
items:
- key: SPECIAL_LEVEL #key=SPECIAL_LEVEL
path: keys.properties # value將以keys.properties 文件名進(jìn)行掛載
restartPolicy: Never
創(chuàng)建Pod:
kubectl create -f pod-configmap-volume-specific-key.yaml
當(dāng) pod 運行時,命令 cat /etc/config/keys 產(chǎn)生以下輸出
very
注意:
/etc/config/ 目錄中所有先前的文件都將被刪除。
3.掛載的 ConfigMap 將自動更新
? 更新已經(jīng)在數(shù)據(jù)卷中使用的 ConfigMap 時,已映射的鍵最終也會被更新。 kubelet 在每次定期同步時都會檢查已掛載的 ConfigMap 是否是最新的。 但是,它使用其本地的基于 TTL 的緩存來獲取 ConfigMap 的當(dāng)前值。 因此,從更新 ConfigMap 到將新鍵映射到 Pod 的總延遲可能與 kubelet 同步周期 + ConfigMap 在 kubelet 中緩存的 TTL 一樣長。
注意:
使用 ConfigMap 作為subPath的數(shù)據(jù)卷將不會收到ConfigMap更新。
4.使用ConfigMap的限制條件
-
在 Pod 規(guī)范中引用之前,必須先創(chuàng)建一個 ConfigMap(除非將 ConfigMap 標(biāo)記為"可選")。
如果引用的 ConfigMap 不存在,則 Pod 將不會啟動。
同樣,引用 ConfigMap 中不存在的鍵也會阻止 Pod 啟動。
-
如果通過環(huán)境變量使用ConfigMap,那么無效的鍵將被忽略,可以啟動pod。
- 在事件日志中(
InvalidVariableNames)。 日志消息列出了每個跳過的鍵。例如:
- 在事件日志中(
# kubectl get events
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames {kubelet, 127.0.0.1} Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
ConfigMap受Namespace限制,只有處于相同Namespace中的Pod才可以引用它。
ConfigMap中的配額管理還未能實現(xiàn)。
-
靜態(tài)Pod不支持ConfigMap
- kubelet只支持可以被API Server管理的Pod使用ConfigMap。kubelet在本Node上通過 --manifest-url或--config自動創(chuàng)建的靜態(tài)Pod將無法引用ConfigMap。
-
在通過volumeMount使用ConfigMap時,在容器內(nèi)部只能掛載為“目錄”,無法掛載為“文件”。
在掛載到容器內(nèi)部后,在目錄下將包含ConfigMap定義的每個item,如果在該目錄下原來還有其他文件,則容器內(nèi)的該目錄將被掛載的ConfigMap覆蓋
如果應(yīng)用程序需要保留原來的其他文件,則需要進(jìn)行額外的處理。可以將ConfigMap掛載到容器內(nèi)部的臨時目錄,再通過啟動腳本將配置文件復(fù)制或者鏈接到(cp或link命令)應(yīng)用所用的實際配置目錄下。
3.在容器內(nèi)獲取Pod信息(Downward API)
? 我們知道,每個Pod在被成功創(chuàng)建出來之后,都會被系統(tǒng)分配唯一的名字、IP地址,并且處于某個Namespace中,那么我們?nèi)绾卧赑od的容器內(nèi)獲取Pod的這些重要信息呢?答案就是使用Downward API。
Downward API可以通過以下兩種方式將Pod信息注入容器內(nèi)部。
(1)環(huán)境變量:用于單個變量,可以將Pod信息和Container信息注入容器內(nèi)部。
(2)Volume掛載:將數(shù)組類信息生成為文件并掛載到容器內(nèi)部。
這兩種呈現(xiàn) Pod 和 Container 字段的方式統(tǒng)稱為 Downward API。
3.1 通過環(huán)境變量方式獲取Pod信息
<font color=green>因為可以通過將Pod的信息(Pod中的字段值)或Container的信息(容器中的字段值)注入到Pod的環(huán)境變量中</font>,所以這個環(huán)境變量的值可能取自兩個地方:
-
pod中的字段
- pod中的字段獲取的范圍大于容器中的字段。
容器中的字段
以上兩種方式只是獲取的范圍不同。
文檔地址:
https://kubernetes.io/zh/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/
3.1.1 獲取用Pod字段作為環(huán)境變量的值
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
sleep 10;
done;
env: #環(huán)境數(shù)組
- name: MY_NODE_NAME #第一個環(huán)境變量
valueFrom:
fieldRef:
fieldPath: spec.nodeName #從 Pod 的 spec.nodeName 字段獲取變量值,本集群是通過minikube工具創(chuàng)建,nodeName=minikube
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
restartPolicy: Never
注意到上面valueFrom這種特殊的語法是Downward API的寫法。目前Downward API提供了以下變量。
metadata.name:Pod的名稱,當(dāng)Pod通過RC生成時,其名稱是RC隨機產(chǎn)生的唯一名稱。
status.podIP:Pod的IP地址,之所以叫作status.podIP而非metadata.IP,是因為Pod的IP屬于狀態(tài)數(shù)據(jù),而非元數(shù)據(jù)。
metadata.namespace:Pod所在的Namespace。
創(chuàng)建pod
kubectl apply -f dapi-envars-pod.yaml
查看容器日志:
# kubectl logs dapi-envars-fieldref
minikube
dapi-envars-fieldref
default
172.17.0.4
default
注意:
當(dāng)容器啟動時,它將五個環(huán)境變量的值寫入 stdout。每十秒重復(fù)執(zhí)行一次。
接下來,通過打開一個 Shell 進(jìn)入 Pod 中運行的容器:
# kubectl exec -it dapi-envars-fieldref -- sh
在 Shell 中,查看環(huán)境變量:
/# printenv
MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref
3.1.2 獲取用Container字段作為環(huán)境變量的值
將容器資源信息注入為環(huán)境變量
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox:1.24
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never
注意valueFrom這種特殊的Downward API語法,目前resourceFieldRef可以將容器的資源請求和資源限制等配置設(shè)置為容器內(nèi)部的環(huán)境變量。
requests.cpu:容器的CPU請求值。
limits.cpu:容器的CPU限制值。
requests.memory:容器的內(nèi)存請求值。
limits.memory:容器的內(nèi)存限制值。
創(chuàng)建Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-container.yaml
查看容器日志
# kubectl logs dapi-envars-resourcefieldref
1
1
33554432
67108864
3.2 通過volumeCount方式獲取Pod信息
當(dāng)然Pod的環(huán)境變量的取值可以通過Pod字段或Container字段指定,下面例子演示一個通過Pod字段演示。
例子:
Pod的配置信息
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
注意:
本示例中的字段是Pod字段,不是Pod中容器的字段。
創(chuàng)建 Pod:
kubectl apply -f dapi-volume.yaml
查看容器的日志:
# kubectl logs kubernetes-downwardapi-volume-example
輸出顯示 labels 和 annotations 文件的內(nèi)容:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
進(jìn)入 Pod 中運行的容器,打開一個 Shell:
# kubectl exec -it kubernetes-downwardapi-volume-example -- sh
在該 Shell中,查看 labels 文件:
/# cat /etc/podinfo/labels
輸出顯示 Pod 的所有標(biāo)簽都已寫入 labels 文件。
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
查看annotations文件同理。
在輸出中可以看到,labels 和 annotations 文件都在一個臨時子目錄中。 在這個例子,..2982_06_02_21_47_53.299460680。 在 /etc/podinfo 目錄中,..data 是一個指向臨時子目錄 的符號鏈接。/etc/podinfo 目錄中,labels 和 annotations 也是符號鏈接。
drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels
/etc/podinfo/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r-- ... Feb 6 21:47 annotations
-rw-r--r-- ... Feb 6 21:47 labels
3.3 Downward API的價值
-
通過環(huán)境變量或文件方式獲取Pod自身的名稱、IP地址等信息,然后將這些信息寫入主程序的配置文件中然后發(fā)布息發(fā)布到某個類似服務(wù)注冊中心的地方,以實現(xiàn)集群節(jié)點的自動發(fā)現(xiàn)功能
在某些集群中,集群中的每個節(jié)點都需要將自身的標(biāo)識(ID)及進(jìn)程綁定的IP地址等信息事先寫入配置文件中,進(jìn)程在啟動時會讀取這些信息,然后將這些信息發(fā)布到某個類似服務(wù)注冊中心的地方,以實現(xiàn)集群節(jié)點的自動發(fā)現(xiàn)功能。
此時Downward API就可以派上用場了,具體做法是先編寫一個預(yù)啟動腳本或Init Container,通過環(huán)境變量或文件方式獲取Pod自身的名稱、IP地址等信息,然后將這些信息寫入主程序的配置文件中,最后啟動主程序。