ConfigMap 與 Secret¶
原文: k8s入门教程十一:ConfigMap与secrets
ConfigMap¶
ConfigMap 允許您將配置文件與容器鏡像分離,以使容器化的應用程序具有可移植性。本教程提供了一系列使用示例,這些示例演示如何使用存儲在 ConfigMap 中的數據創建和配置 Pod。 ConfigMap API給我們提供了向容器中註入配置信息的機制,ConfigMap 可以被用來保存單個屬性,也可以用來保存整個配置文件或者 JSON 二進制對象。
配置數據可以通過很多種方式在 Pods 裡被使用。 ConfigMaps 可以被用來:
- 生成為容器內的環境變量
- 設置容器啟動命令的參數
- 掛載為容器內部的文件或目錄
向容器傳遞參數:
如果需要向容器傳遞參數
,可以在 Yaml 文件中通過 command
和 args
或者環境變量
的方式實現。
kind: Pod
spec:
containers:
- image: docker.io/nginx
command: ["/bin/command"]
args: ["arg1", "arg2", "arg3"]
env:
- name: INTERVAL
value: "30"
- name: FIRST_VAR
value: "foo"
- name: SECOND_VAR
value: "$(FIRST_VAR)bar"
可以看到,我們可以利用 env 標籤向容器中傳遞環境變量,環境變量還可以相互引用。這種方式的問題在於配置文件和部署是綁定的,那麼對於同樣的應用,測試環境的參數和生產環境是不一樣的,這樣就要求寫兩個部署文件,管理起來不是很方便。
上面提到的例子,利用 ConfigMap可 以解耦部署與配置的關係,對於同一個應用部署文件,可以利用valueFrom字段引用一個在測試環境和生產環境都有的ConfigMap(當然配置內容不相同,只是名字相同),就可以降低環境管理和部署的複雜度。
掛載為容器內部的文件或目錄:
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
spec:
containers:
- image: nginx
name: web-server
volumeMounts:
- name: config
mountPath: /etc/someconfig.conf
subPath: myconfig.conf
volumes:
- name: config
configMap:
name: <map-name>
ConfigMap的注意事項:
- ConfigMap 必須在 Pod 之前創建
- ConfigMap 屬於某個 NameSpace,只有處於相同 NameSpace 的 Pod 才可以應用它
- ConfigMap 中的 size 不能超過 1 MiB
- 如果是 volume 的形式掛載到容器內部,當設定掛載到某個目錄下時,該目錄下原有的文件會被覆蓋掉(可搭配使用 subPath 來解決)
創建¶
ConfigMap 的創建手法有很多種:
# 使用 yaml 的聲明方式
$ kubectl apply -f <configmap-file.yaml>
# 使用命令創建
$ kubectl create configmap <map-name> --from-literal=<parameter-name>=<parameter-value>
$ kubectl create configmap <map-name> --from-literal=<parameter1>=<parameter1-value> --from-literal=<parameter2>=<parameter2-value> --from-literal=<parameter3>=<parameter3-value>
# 使用文件創建 configmap
$ kubectl create configmap <map-name> --from-file=<file-path>
# 還可以從一個文件夾創建 configmap
$ kubectl create configmap <map-name> --from-file=/path/to/dir
1. 使用 yaml 的聲明方式¶
可把相關的設定檔案內容直接使用 yaml 來進行宣告:
apiVersion: v1
data:
my-nginx-config.conf: |
server {
listen 80;
server_name www.kubia-example.com;
gzip on;
gzip_types text/plain application/xml;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
sleep-interval: |
25
kind: ConfigMap
metadata:
name: my-nginx-config
使用 kubectl 來創建 configmap:
讓我們來檢查一下執行後的結果:
$ kubectl describe cm/my-nginx-config
Name: my-nginx-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
my-nginx-config.conf:
----
server {
listen 80;
server_name www.kubia-example.com;
gzip on;
gzip_types text/plain application/xml;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
sleep-interval:
----
25
BinaryData
====
Events: <none>
2. 使用目錄或文件創建¶
你可以使用 kubectl create configmap name --from-file=
從同一目錄中的多個文件創建 ConfigMap。
將樣本文件下載到 configure-pod-container/configmap/
目錄:
wget https://kubernetes.io/examples/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties
讓我們看一下這兩個樣本設定檔文件的內容:
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
使用 kubectl create configmap <map-name> <data-source>
命令來創建 configmap:
# --from-file可以接單個文件,也可以接單個目錄
kubectl create cm game-config --from-file=./
kubectl create cm game-config-2 --from-file=game.properties --from-file=ui.properties
檢查運行結果:
檢視 configmap:
$ kubectl describe cm/game-config
Name: game-config
Namespace: default
Labels: <none>
Annotations: <none>
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
BinaryData
====
Events: <none>
也可把 configmap 用 yaml 的格式來展現:
$ kubectl get cm/game-config -o yaml
apiVersion: v1
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
kind: ConfigMap
metadata:
creationTimestamp: "2022-08-11T12:31:16Z"
name: game-config
namespace: default
resourceVersion: "6231"
uid: 0de5e556-6809-482c-afab-1a696d27873a
3. 從 env 文件創建¶
當使用多個 --from-env-file
來從多個數據源創建 ConfigMap 時,僅僅最後一個 env 文件有效:
# 環境文件包含環境變量列表。
# 語法規則:
# env 文件中的每一行必須為 VAR = VAL 格式。
# 以#開頭的行(即註釋)將被忽略。
# 空行將被忽略。
# 引號沒有特殊處理(即它們將成為 ConfigMap 值的一部分)。
# 將樣本文件下載到 `configure-pod-container/configmap/` 目錄
wget https://kubernetes.io/examples/configmap/game-env-file.properties
enemies=aliens
lives=3
allowed="true"
# This comment and the empty line above it are ignored
使用 kubectl create configmap name --from-env-file=
從文件檔來創建 ConfigMap。
檢視 configmap 內容:
$ kubectl get cm game-config-env-file -o yaml
apiVersion: v1
data:
allowed: '"true"'
enemies: aliens
lives: "3"
kind: ConfigMap
metadata:
creationTimestamp: "2020-02-09T02:38:37Z"
name: game-config-env-file
namespace: default
resourceVersion: "1690565"
selfLink: /api/v1/namespaces/default/configmaps/game-config-env-file
uid: 9594fa13-5b2c-4848-a88a-77e3d0fd0646
4. 使用命令創建¶
可以將 kubectl create configmap
與 --from-literal
參數一起使用,從命令行定義文字值:
$ kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
configmap/special-config created
檢視 configmap 內容:
$ kubectl get configmaps special-config -o yaml
apiVersion: v1
data:
special.how: very
special.type: charm
kind: ConfigMap
metadata:
creationTimestamp: "2022-08-11T13:01:09Z"
name: special-config
namespace: default
resourceVersion: "6596"
uid: fdc77599-685f-4caa-8fd8-3a3f8026b5c9
5. 使用生成器創建¶
使用 kustomize 的 configMapGenerator
生成器來創建 ConfigMap 對象。
創建 kustomization.yaml
設定檔:
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-4
files:
- game.properties
EOF
使用下列命令來檢視 kustomize
生成的 configmap:
$ kustomize build ./
apiVersion: v1
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
kind: ConfigMap
metadata:
name: game-config-4-tbg7c4gc77
直接生成 configmap:
或者也可以使用生成器來實現。
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: special-config-2
literals:
- special.how=very
- special.type=charm
EOF
Tip
參考:使用 Kustomize 對 Kubernetes 對象進行聲明式管理 來了解如何使用 kubectl 與 kustomize 來生成相關的 kubernetes object 對象。
使用¶
ConfigMap有三種用法:
- 生成為容器內的環境變量
- 設置容器啟動命令的參數
- 掛載為容器內部的文件或目錄
1. 曝露成環境變量¶
使用 configMapKeyRef 指定要從某一個 configmap 中曝露那一個特定的鍵值成環境變量:
創建 cfmap-env-test01.yaml
檔案:
apiVersion: v1
data:
special.how: very
special.type: charm
kind: ConfigMap
metadata:
name: special-config
---
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
# Define the environment variable
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
name: special-config
# Specify the key associated with the value
key: special.how
restartPolicy: Never
上述 yaml 表示,新建一個名為 SPECIAL_LEVEL_KEY
的環境變量,其值源於 configMap 裡面的 special.how
。
讓我們來檢查一下 Pod 執行後的結果:
$ kubectl logs pods/dapi-test-pod
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.43.0.1:443
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
SPECIAL_LEVEL_KEY=very
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.43.0.1
PWD=/
上一個例子是有指定一個具體的KEY,如果沒有指定呢?
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod2
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
讓我們來檢查一下 Pod 執行後的結果:
$ kubectl logs pods/dapi-test-pod2
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.43.0.1:443
HOSTNAME=dapi-test-pod2
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
special.type=charm
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
special.how=very
KUBERNETES_SERVICE_HOST=10.43.0.1
PWD=/
注意看 KEY 與 VALUE 的關係。
2. 掛載文件目錄法¶
可以使用 volumeMounts 方法進行掛載。
讓我們先看一下 special-config 這個 configmap 的內容:
$ kubectl get configmaps special-config -o yaml
apiVersion: v1
data:
special.how: very
special.type: charm
kind: ConfigMap
metadata:
creationTimestamp: "2022-08-11T13:01:09Z"
name: special-config
namespace: default
resourceVersion: "6596"
uid: fdc77599-685f-4caa-8fd8-3a3f8026b5c9
把 special-config 掛載至 /etc/config
目錄下。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "ls /etc/config/;cat /etc/config/special.how;cat /etc/config/special.type" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
# Provide the name of the ConfigMap containing the files you want
# to add to the container
name: special-config
restartPolicy: Never
執行命令與檢查成果:
# 創建 pod
$ kubectl create -f pod-configmap-volume.yaml
pod/dapi-test-pod created
# 檢查 pod 狀態
$ kubectl get pod/dapi-test-pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 119s
# 檢視 configmap 內容
$ kubectl describe cm special-config
Name: special-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
special.how:
----
very
special.type:
----
charm
BinaryData
====
Events: <none>
# 檢查 Pod 執行完成後的日誌
$ kubectl logs pod/dapi-test-pod
special.how
special.type
verycharm
可以看到,其每一個 KEY 都是會生成一個文件,文件的內容為 value 的值。
也可以掛載 configmap 裡頭單獨的 KEY:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod2
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh","-c","cat /etc/config/keys;sleep 600" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
items:
- key: special.how
path: keys
restartPolicy: Never
將 KEY special.how
掛載到 /etc/config
目錄下,其文件名使用 path
變成了 keys
:
$ kubectl apply -f pod-configmap-volume-specific-key.yaml
pod/dapi-test-pod2 created
$ kubectl exec -it pod/dapi-test-pod2 -- /bin/sh
/ # cat /etc/config/keys
very/ # exit
熱更新的問題¶
confgimap 更新後,如果是以 文件夾 方式掛載的,會自動將掛載的 Volume 更新。如果是以 文件形式 掛載的,則不會自動更新。
但是對多數情況的應用來說,配置文件更新後,最簡單的辦法就是重啟Pod(殺掉再重新拉起)。
如果是以文件夾形式掛載的,可以通過在容器內重啟應用的方式實現配置文件更新生效。即便是重啟容器內的應用,也要注意 configmap 的更新和容器內掛載文件的更新不是同步的,可能會有延時,因此一定要確保容器內的配置也已經更新為最新版本後再重新加載應用。
使用 volumes 掛載的方式是可以更新 configMap 的,但是使用 env方 式導給 POD 是更新不了的。
Secret¶
Secret 解決了更新密碼、令牌、密鑰等敏感數據的配置問題,而不是需要將這些敏感數據洩露到或 Pod Spec 中。Secret 可以以 Volume 或環境變量使用。
Kubernetes 為一些常見的使用場景提供了幾種內置 Secret 類型。這些類型在執行的驗證和 Kubernetes 對它們施加的約束方面有所不同。
Secret 的類型:
類型 | 用例 |
---|---|
Opaque | 預設的的類型。Base64 編碼格式的 Secret,用來存儲密碼、密鑰等;數據可通過 base64 –decode 解碼得到原始數據,所以加密性很弱。 |
kubernetes.io/service-account-token | 用於被 serviceaccount 引用。 serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。 Pod 如果使用了serviceaccount,對應的 secret 會自動掛載到 Pod 目錄 /run/secrets/kubernetes.io/serviceaccount 中。 |
kubernetes.io/dockercfg | ~/.dockercfg 文件的序列化形式,用來存儲私有 docker registry 的認證信息 |
kubernetes.io/dockerconfigjson | ~/.docker/config.json 文件的序列化形式,用來存儲私有 docker registry 的認證信息 |
kubernetes.io/basic-auth | 用於基本身份認證 (Basic Auth)的憑據 |
kubernetes.io/ssh-auth | 用於 SSH 身份認證的憑據 |
kubernetes.io/tls | 用於 TLS 客戶端或者服務器端的數據 |
bootstrap.kubernetes.io/token | K8s 節點 bootstrap 令牌數據 |
Opaque 類型¶
Opaque 類型的數據是一個 map 類型,要求 value 是 base64 編碼格式,如果您使用的密碼具有特殊字符,則需要使用 \\
字符對其進行轉義。
文件創建¶
讓我們查找一下使用 kubectl create secret
的相關命令:
$ kubectl create secret generic --help
Create a secret based on a file, directory, or specified literal value.
A single secret may package one or more key/value pairs.
When creating a secret based on a file, the key will default to the basename of the file, and the value will default to
the file content. If the basename is an invalid key or you wish to chose your own, you may specify an alternate key.
When creating a secret based on a directory, each file whose basename is a valid key in the directory will be packaged
into the secret. Any directory entries except regular files are ignored (e.g. subdirectories, symlinks, devices, pipes,
etc).
Examples:
# Create a new secret named my-secret with keys for each file in folder bar
kubectl create secret generic my-secret --from-file=path/to/bar
# Create a new secret named my-secret with specified keys instead of names on disk
kubectl create secret generic my-secret --from-file=ssh-privatekey=path/to/id_rsa --from-file=ssh-publickey=path/to/id_rsa.pub
# Create a new secret named my-secret with key1=supersecret and key2=topsecret
kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret
# Create a new secret named my-secret using a combination of a file and a literal
kubectl create secret generic my-secret --from-file=ssh-privatekey=path/to/id_rsa --from-literal=passphrase=topsecret
# Create a new secret named my-secret from env files
kubectl create secret generic my-secret --from-env-file=path/to/foo.env --from-env-file=path/to/bar.env
創建範例的帳密檔案:
使用 kubectl create secret generic--from-file
命令來創建 secret 對象:
$ kubectl create secret generic db-user-pass --from-file=username --from-file=password
secret/db-user-pass created
檢視 secret 對象:
# 檢索 secret
$ kubectl get secret
NAME TYPE DATA AGE
default-token-dz4cv kubernetes.io/service-account-token 3 5h27m
db-user-pass Opaque 2 71s
# 檢視 secret 對象
$ kubectl get secret/db-user-pass -o yaml
apiVersion: v1
data:
password: MTIzNDU=
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2022-08-12T07:54:19Z"
name: db-user-pass
namespace: default
resourceVersion: "4763"
uid: edc0ca3d-4462-4419-93c3-1c6951b6b70b
type: Opaque
使用 kubectl create secret generic--from-literal
命令來創建 secret 對象:
$ kubectl create secret generic db-user-pass --from-literal=username=admin --from-literal=password=12345
secret/db-user-pass created
檢視 secret 對象:
# 檢索 secret
$ kubectl get secret
NAME TYPE DATA AGE
default-token-dz4cv kubernetes.io/service-account-token 3 5h27m
db-user-pass Opaque 2 71s
# 檢視 secret 對象
$ kubectl get secret/db-user-pass -o yaml
apiVersion: v1
data:
password: MTIzNDU=
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2022-08-12T07:54:19Z"
name: db-user-pass
namespace: default
resourceVersion: "4763"
uid: edc0ca3d-4462-4419-93c3-1c6951b6b70b
type: Opaque
默認情況下,kubectl get 和 kubectl describe 是不會顯示密碼的內容。這是為了防止機密被意外地暴露給旁觀者或存儲在終端日誌中。
手工創建¶
Secret 對象也可以使用手工來創建,如下:
現在可以像這樣寫一個 secret 對象:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU=
docker-registry secret¶
Kubernetes 從私有容器鏡象倉庫拉取鏡象的時候需要相關的配置相關的帳密配置。
可以直接用 kubectl 命令來創建用於 docker registry 認證的 secret:
$ kubectl create secret docker-registry myregistrykey
--docker-server=DOCKER_REGISTRY_SERVER
--docker-username='*******'
--docker-password='*******'
--docker-email=DOCKER_EMAIL
````
- docker-server 私有容器鏡象倉庫完全限定域名(FQDN)
- docker-username 賬號用戶名,需要用單引號括起來。
- docker-password 賬號 token 或密碼,需要用單引號括起來。
- docker-email 用戶電郵 (not required)。
例如:
```bash
$ kubectl create secret docker-registry loginharbor \
--docker-email=tiger@acme.example \ #可以不填写
--docker-username=admin \
--docker-password=Harbor12345 \
--docker-server=harbor.demo.com:5667 #harbor的地址要加端口
service-account-token¶
用於被 serviceaccount 引用。 serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。 Pod 如果使用了 serviceaccount,對應的 secret 會自動掛載到 Pod 目錄 /run/secrets/kubernetes.io/serviceaccount
中。
Secret 是一種包含少量敏感信息例如密碼、token 或 key 的對象。這樣的信息可能會被放在 Pod spec 中或者鏡像中;將其放在一個 secret 對象中可以更好地控制它的用途,並降低意外暴露的風險。
在 Kubernetes 中的每一個 Pod 都會歸屬於某一個 SA,比如:
$ kubectl get sa -n default -o yaml
apiVersion: v1
items:
- apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2022-08-12T02:27:55Z"
name: default
namespace: default
resourceVersion: "435"
uid: fe177ee4-6af5-44de-a5c2-96baea7c83f6
secrets:
- name: default-token-dz4cv
kind: List
metadata:
resourceVersion: ""
查看 Service account 的 secret:
$ kubectl get secret default-token-dz4cv -o yaml
apiVersion: v1
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUyTmpBeU56RXlOVGd3SGhjTk1qSXdPREV5TURJeU56TTRXaGNOTXpJd09EQTVNREl5TnpNNApXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUyTmpBeU56RXlOVGd3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFTbFd1Q0RHcEt5N09ya0JuUUFHK21ZcUtVTU9TeVJqZGlnUGxoRWZnZGEKYS9CT05BUW1SZjFjczJ1MUtUWDI4Q2JGc1VtSmlmRityS2xWS1pYVERpbVRvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUpUT1Bxd1FTSUh4eWpoUWpJWnpECjJzbTlrMHd3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUloQUlWTVlCanpJZ2hGYjVqSjVZUGlVVW5NR2pNelhSSlgKLzdNbjFqUGRDU2xPQWlBWEt0S3VNYXcvSUZ6TFhFYXVlbnJLTWJlZDhPNFluV3ZkbGRRTzN0WE5tQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
namespace: ZGVmYXVsdA==
token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltazBhR0owUWtndFZUUlhURmx2V2tOdGNYUXdNbHBoVUhaZlZrVTBMVzlsY0hNd2JGOHhSWEZtU1djaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbVJsWm1GMWJIUXRkRzlyWlc0dFpIbzBZM1lpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pWkdWbVlYVnNkQ0lzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG5WcFpDSTZJbVpsTVRjM1pXVTBMVFpoWmpVdE5EUmtaUzFoTldNeUxUazJZbUZsWVRkak9ETm1OaUlzSW5OMVlpSTZJbk41YzNSbGJUcHpaWEoyYVdObFlXTmpiM1Z1ZERwa1pXWmhkV3gwT21SbFptRjFiSFFpZlEudXJOR1ZvX2lzQnJSd3I2WTlnYkoxaGpqM29kTFpBbm9ZRVBtVG41eWRJSnZpWDNIYmxZSU9OazgzYTl3WjFZbjdzb1JlSHdrN3VSbzBrel90YkVua0tudGlzVHNheHZsOU1rMjVsTDk3bVpLTWF1dlFXZTBZWTU2NVhLb3FDSnFtVVRaVmRMTTNMNkxOMkFQRURhMEtZNW96djVfanFVZkdvTWlzdTVFRVloQ0JGMXBJbUtla1RUS3cwN3hhTmpzQ3dER3BlZXJPV1d5cmd1elFZdjU1OFM2WWw4dHozLVdYVHVMcFBIQ1R1S1E1OUtZUHltSkFXLVhZOHpCQmo2cV9kT3NYWEtrQjVLNk5GLUlJMWZRZUl4UXpyeGxhZjdYazk5OW1BSi0yQmE1eFAxaWp6SXJmTTMxb21qWldIcnBkNFIzSlhTQVdCUVJRV3lQSDNfTWJ3
kind: Secret
metadata:
annotations:
kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: fe177ee4-6af5-44de-a5c2-96baea7c83f6
creationTimestamp: "2022-08-12T02:27:55Z"
name: default-token-dz4cv
namespace: default
resourceVersion: "433"
uid: 0900cbfe-e27c-4d19-b6aa-3a368415f16f
type: kubernetes.io/service-account-token
使用¶
Secret 可以作為數據卷被掛載,或作為環境變量暴露出來以供 pod 中的容器使用。它們也可以被系統的其他部分使用,而不直接暴露在 pod 內。例如,它們可以保存憑據,系統的其他部分應該用它來代表您與外部系統進行交互。
1. 曝露成環境變量¶
使用 secretKeyRef 指定要從某一個 secret 中曝露那一個特定的鍵值成環境變量:
先檢視 secret 對象:
# 檢視 secret 對象
$ kubectl get secret/db-user-pass -o yaml
apiVersion: v1
data:
password: MTIzNDU=
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2022-08-12T07:54:19Z"
name: db-user-pass
namespace: default
resourceVersion: "4763"
uid: edc0ca3d-4462-4419-93c3-1c6951b6b70b
type: Opaque
創建 pod-env-secrets.yaml
檔案:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod3
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh","-c","env;echo ${SECRET_USERNAME} ${SECRET_PASSWORD}" ]
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: db-user-pass
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: db-user-pass
key: password
restartPolicy: Never
執行命令:
檢查結果:
$ kubectl get pod dapi-test-pod3
NAME READY STATUS RESTARTS AGE
dapi-test-pod3 0/1 Completed 0 21s
$ kubectl logs dapi-test-pod3
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.43.0.1:443
HOSTNAME=dapi-test-pod3
SHLVL=1
HOME=/root
SECRET_PASSWORD=12345
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
SECRET_USERNAME=admin
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
KUBERNETES_SERVICE_HOST=10.43.0.1
PWD=/
admin 12345
2. 掛載文件目錄法¶
可以使用 volumeMounts 方法進行掛載。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod4
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh","-c","ls /etc/config;sleep 600" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
secret:
secretName: db-user-pass
restartPolicy: Never
執行命令與檢查成果:
# 創建 pod
$ kubectl create -f pod-volume-secrets.yaml
pod/dapi-test-pod4 created
# 檢查 pod 狀態
$ kubectl get pod/dapi-test-pod4
NAME READY STATUS RESTARTS AGE
dapi-test-pod4 1/1 Running 0 7s
# 檢查 Pod 的日誌
$ kubectl logs pod/dapi-test-pod4
password
username
# 進到 Pod 中去檢查
$ kubectl exec -it dapi-test-pod4 -- /bin/sh
也可以掛載 secret 裡頭單獨的 KEY 到指定的目錄下。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod5
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh","-c","ls /etc/config;sleep 600" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
secret:
secretName: db-user-pass
items:
- key: username
path: my-group/my-username
restartPolicy: Never
執行命令與檢查成果:
# 創建 pod
$ kubectl apply -f pod-volume-secrets2.yaml
pod/dapi-test-pod5 created
# 檢查 pod 狀態
$ kubectl get pod/dapi-test-pod5
NAME READY STATUS RESTARTS AGE
dapi-test-pod5 1/1 Running 0 7s
# 檢查 Pod 的日誌
$ kubectl logs pod/dapi-test-pod5
my-group
# 進到 Pod 中去檢查
$ kubectl exec -it dapi-test-pod5 -- /bin/sh
Tip
Secrets 的用法是跟 ConfigMap 基本上是一致,區別不同是 ConfigMap 是明文,而 Secrets 是經過 base64 編碼過的。