第十章 Secret&Configmap
應用啟動過程中可能需要一些敏感信息休讳,比如訪問數(shù)據(jù)庫的用戶名密碼或者秘鑰主届。將這些信息直接保存在容器鏡像中顯然不妥赵哲,Kubernetes 提供的解決方案是 Secret。
Secret 會以密文的方式存儲數(shù)據(jù)君丁,避免了直接在配置文件中保存敏感信息枫夺。Secret 會以 Volume 的形式被 mount 到 Pod,容器可通過文件的方式使用 Secret 中的敏感數(shù)據(jù)绘闷;此外橡庞,容器也可以環(huán)境變量的方式使用這些數(shù)據(jù)。
Secret 可通過命令行或 YAML 創(chuàng)建印蔗。比如希望 Secret 中包含如下信息:
用戶名 admin 密碼 123456
10.1 創(chuàng)建 Secret方式
有四種方法創(chuàng)建 Secret:
- 通過 --from-literal:
$ kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
secret/mysecret created
#查看
kubectl get secrets
NAME TYPE DATA AGE
default-token-mvhfz kubernetes.io/service-account-token 3 11d
mysecret Opaque 2 3m30s
#刪除
kubectl delete secret mysecret
每個 --from-literal 對應一個信息條目扒最。
- 通過 --from-file:
echo -n admin > ./username
echo -n 123456 > ./password
kubectl create secret generic mysecret --from-file=./username --from-file=./password
3.通過 --from-env-file:
cat << EOF > env.txt
username=admin
password=123456
EOF
#
$kubectl create secret generic mysecret --from-env-file=env.txt
文件 env.txt 中每行 Key=Value 對應一個信息條目。
4.通過 YAML 配置文件:
vim mysecret.yml
apiVersion: v1
kind: Secret
metadata:
name: mysecret4
data:
username: YWRtaW4=
password: MTIzNDU2
#應用
$ kubectl apply -f mysecrete.yml
#文件中的敏感數(shù)據(jù)必須是通過 base64 編碼后的結果华嘹。
$echo -n admin |base64
YWRtaW4=
$echo -n 123456 |base64
MTIzNDU2
文件中的敏感數(shù)據(jù)必須是通過 base64 編碼后的結果吧趣。
10.2 查看Secret:
1通過 kubectl get secret 查看存在的 secret
$kubectl get secret
NAME TYPE DATA AGE
mysecret Opaque 2 15m
#其中2表示有2條數(shù)據(jù)。
2通過kubectl describe secret 查看條目的 Key
$kubectl edit secret mysecret
apiVersion: v1
data:
password: MTIzNDU2
username: YWRtaW4=
kind: Secret
反編碼查看結果
$echo -n YWRtaW4= | base64 --decode
admin
$echo -n MTIzNDU2 | base64 --decode
123456
10.3 vloume方式secret的使用
Pod 可以通過 Volume 或者環(huán)境變量的方式使用 Secret除呵,先學習 Volume 方式再菊。
10.3.1 Volume方式
Pod 的配置文件如下所示:
vim mysecret_pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
volumes:
- name: foo
secret:
secretName: mysecret
containers:
- image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
name: mypod
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
# 創(chuàng)建 Pod 并在容器中讀取 Secret:
$ kubectl apply -f mysecret_pod.yml
pod/mypod created
① 定義 volume foo爪喘,來源為 secret mysecret颜曾。
② 將 foo mount 到容器路徑 /etc/foo,可指定讀寫權限為 readOnly秉剑。
查看
$kubectl exec -it mypod sh
/ # ls /etc/foo/
password username
/ # cat /etc/foo/password
/ # cat /etc/foo/username
admin/ #
可以看到泛豪,Kubernetes 會在指定的路徑 /etc/foo 下為每條敏感數(shù)據(jù)創(chuàng)建一個文件,文件名就是數(shù)據(jù)條目的 Key侦鹏,這里是 /etc/foo/username 和 /etc/foo/password诡曙,Value 則以明文存放在文件中。
我們也可以自定義存放數(shù)據(jù)的文件名略水,比如將配置文件改為:
vim mysecret_pod2.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod2
spec:
containers:
- name: mypod2
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 60000
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
- key: password
path: my-group/my-password
這時數(shù)據(jù)將分別存放在 /etc/foo/my-group/my-username 和 /etc/foo/my-group/my-password 中价卤。
以 Volume 方式使用的 Secret 支持動態(tài)更新:Secret 更新后,容器中的數(shù)據(jù)也會更新渊涝。
將 password 更新為 abcdef慎璧,base64 編碼為 YWJjZGVm
查看
kubectl exec -it mypod2 sh
cat /etc/foo/my-group/my-password
123456
#修改secret password =YWJjZGVm
# echo -n "abcdef" | base64
YWJjZGVm
kubectl apply -f mysecret.yml
$cat /etc/foo/my-group/my-password
abcdef
10.3.2 環(huán)境變量中使用secret
通過 Volume 使用 Secret,容器必須從文件讀取數(shù)據(jù)跨释,會稍顯麻煩胸私,Kubernetes 還支持通過環(huán)境變量使用 Secret。
cat mysecret_pod3.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod3
spec:
containers:
- name: mypod3
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 60000
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
#
$kubectl apply -f mysecret_pod3.yml
$kubectl get pods mypod3
NAME READY STATUS RESTARTS AGE
mypod3 1/1 Running 0 2m16s
查看環(huán)境變量
#
$kubectl exec -it mypod3 sh
#
$echo $SECRET_USERNAME
admin
/
$ echo $SECRET_PASSWORD
abcdef
通過環(huán)境變量 SECRET_USERNAME 和 SECRET_PASSWORD 成功讀取到 Secret 的數(shù)據(jù)鳖谈。
需要注意的是岁疼,環(huán)境變量讀取 Secret 很方便,但無法支撐 Secret 動態(tài)更新缆娃。
10.4 ConfigMap
Secret 可以為 Pod 提供密碼捷绒、Token瑰排、私鑰等敏感數(shù)據(jù);對于一些非敏感數(shù)據(jù)暖侨,比如應用的配置信息凶伙,則可以用 ConfigMap。
10.4.1 configMap創(chuàng)建
與 Secret 一樣它碎,ConfigMap 也支持四種創(chuàng)建方式:
1.1通過 --from-literal:
kubectl create configmap myconfigmap --from-literal=config1=xxx --from-literal=config2=yyy
1.2通過 --from-file:
echo -n xxx > ./config1
echo -n yyy > ./config2
kubectl create configmap myconfigmap --from-file=./config1 --from-file=./config2
1.3通過 --from-env-file:
cat << EOF > env.txt
config1=xxx
config2=yyy
EOF
kubectl create configmap myconfigmap --from-env-file=env.txt
1.4通過 YAML 配置文件:
vim myconfigmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
data:
config1: xxx
config2: yyy
$kubectl apply -f myconfigmap.yml
configmap/myconfigmap created
$ kubectl get configmap
NAME DATA AGE
myconfigmap 2 42s
10.4.2 configMap使用
1. volum方式
vim myconfigmap_pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 60000
name: mypod
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
configMap:
name: myconfigmap
$kubectl apply -f myconfigmap_pod.yml
pod/mypod created
查看config
#進入pod
$exec -it mypod sh
/ # cat /etc/foo/config1
/ # cat /etc/foo/config2
yyy/ #
2. 環(huán)境變量方式
大多數(shù)情況下函荣,配置信息都以文件形式提供,所以在創(chuàng)建 ConfigMap 時通常采用 --from-file 或 YAML 方式扳肛,讀取 ConfigMap 時通常采用 Volume 方式傻挂。
比如給 Pod 傳遞如何記錄日志的配置信息:
可以采用 --from-file 形式,則將其保存在文件 logging.conf 中挖息,然后執(zhí)行命令:
$kubectl create configmap myconfigmap --from-file=./logging.conf
#
如果采用 YAML 配置文件金拒,其內容則為:
vim myconfigmap_logging.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
data:
logging.conf: |
class: logging.handlers.RotatingFileHandler
formatter: precise
level: INFO
filename: %hostname-%timestamp.log
應用
$kubectl apply -f myconfigmap_logging.yml
configmap/myconfigmap configured
$kubectl edit configMap myconfigmap
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"logging.conf":"class: logging.handlers.RotatingFileHandler\nformatter: precise\nlevel: INFO\nfilename: %hostname-%timestamp.log \n"},"kind":"ConfigMap","meta
data":{"annotations":{},"name":"myconfigmap","namespace":"default"}}
$kubectl describe configMap myconfigmap
Name: myconfigmap
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","data":{"logging.conf":"class: logging.handlers.RotatingFileHandler\nformatter: precise\nlevel: INFO\nfilename: %hostna...
Data
====
logging.conf:
----
class: logging.handlers.RotatingFileHandler
formatter: precise
level: INFO
filename: %hostname-%timestamp.log
Events: <none>
pod中應用此configMap
$myconfigmap_pod.yml
apiVersion: v1
kind: Pod
metadata:
name: myconfigpod
spec:
containers:
- image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 60000
name: myconfigpod
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
configMap:
name: myconfigmap
items:
- key: logging.conf
path: myapp/loggin.conf
$kubectl apply -f myconfigmap_pod.yml
檢查
$kubectl get configMap myconfigmap
$kubectl describe pod myconfigpod
$ kubectl exec -it myconfigpod sh
cat /etc/foo/myapp/loggin.conf
class: logging.handlers.RotatingFileHandler
formatter: precise
level: INFO
filename: %hostname-%timestamp.log
說明:
.
錯誤信息如下:
$kubectl describe pod myconfigpod
Warning Failed 2m9s kubelet, k8s-node-122132072 Error: failed to start container "myconfigpod": Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:402: container init caused \"rootfs_linux.go:58: mounting \\\"/data1/docker/containers/xx/resolv.conf\\\" to rootfs \\\"/data1/docker/overlay2/xx/merged\\\" at \\\"/data1/docker/overlay2/xx/merged/etc/resolv.conf\\\" caused \\\"open /data1/docker/overlay2/xx/merged/etc/resolv.conf: read-only file system\\\"\"": unknown