kubernetes的secret和configmap
用kubernetes管理机密信息
应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥,将这些信息直接保存在容器镜像中显然不妥,kubernetes提供了解决方案是secret
secret资源对象:解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。
secret可通过命令行或YAML创建。比如希望secret包含如下信息:
1.用户名 admin
2.密码 123456
创建secret
通过 --from-kiteral:
[root@master de]# kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
[root@master de]# kubectl describe secrets mysecret Name: mysecret Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== password: 6 bytes username: 5 bytes
每个 --from-literal 对应一个信息条目。
Generic:通用的、一般的。加密方式。
通过--from-file:
[root@master de]# echo -n admin > ./username [root@master de]# echo -n 123456 > ./password [root@master de]# kubectl create secret generic mysecret --from-file=./username --from-file=./passwo secret/mysecret created
每个文件内容对应一个信息条目
这种方式不推荐使用,需要将存储的数据写入到文件中,注意每个文件只能存储一个数据。
[root@master de]# kubectl get secrets mysecret NAME TYPE DATA AGE mysecret Opaque 2 2m27s
[root@master de]# kubectl describe secrets mysecret Name: mysecret Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== password: 6 bytes username: 5 bytes
通过--from-env-file:
[root@master de]# cat env.txt username=admin password=123456
[root@master de]# kubectl create secret generic mysecret --from-env-file=env.txt secret/mysecret created
这种方式可以在同一个文件内写入多个数据
[root@master de]# kubectl get secrets mysecret NAME TYPE DATA AGE mysecret Opaque 2 2m33s
通过yaml配置文件:
[root@master de]# echo -n admin | base64 YWRtaW4= [root@master de]# echo -n 123456 | base64 MTIzNDU2 [root@master de]# [root@master de]# vim env.yml [root@master de]# kubectl get secrets mysecret NAME TYPE DATA AGE mysecret Opaque 2 6m21s [root@master de]# kubectl delete secrets mysecret secret "mysecret" deleted [root@master de]# kubectl apply -f env. env.txt env.yml [root@master de]# kubectl apply -f env.yml secret/mysecret created [root@master de]# kubectl get secrets mysecret NAME TYPE DATA AGE mysecret Opaque 2 32s [root@master de]# kubectl describe secrets mysecret Name: mysecret Namespace: default Labels: <none> Annotations: Type: Opaque Data ==== password: 6 bytes username: 5 bytes
查看value
[root@master de]# kubectl edit secrets mysecret # Please edit the object below. Lines beginning with a ‘#‘ will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 data: password: MTIzNDU2 username: YWRtaW4= kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"password":"MTIzNDU2","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"}} creationTimestamp: "2020-07-26T06:44:04Z" name: mysecret namespace: default resourceVersion: "160163" selfLink: /api/v1/namespaces/default/secrets/mysecret uid: 73ffac16-1c59-4488-ab58-3c05ef1b092f type: Opaque
通过base64将value反编码
123456[root@master de]# echo -n YWRtaW4= | base64 --decode admin[root@master de]#
volume方式使用secret
1.pod可以通过volume或者环境变量的方式使用secret
pod配置文件如下:
[root@master de]# cat pod.yml apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - image: busybox name: mypod volumeMounts: - mountPath: /etc/foo name: foo readOnly: true args: - /bin/sh - -c - sleep 30000 volumes: - name: foo secret: secretName: mysecret
查看
[root@master de]# kubectl get pod NAME READY STATUS RESTARTS AGE mypod 1/1 Running 0 3s
[root@master de]# kubectl exec -it mypod sh
/ # ls /etc/foo/
password username
/ # exit
[root@master de]# kubectl exec -it mypod sh
/ # cat /etc/foo/
..2020_07_26_07_07_36.664212846/ password
..data/ username
/ # cat /etc/foo/username
admin/ #
可以看到,kubernetes会在指定的路径/etc/foo/username和 /etc/foo/password, value则以明文存放在文件中。
我们也可以自定义存放数据的文件名:
[root@master de]# cat pod.yml apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - image: busybox name: mypod volumeMounts: - mountPath: /etc/foo name: foo readOnly: true args: - /bin/sh - -c - sleep 30000 volumes: - name: foo secret: secretName: mysecret items: - key: username path: my-group/my-username - key: password path: my-group/my-password
[root@master de]# kubectl apply -f pod.yml pod/mypod created [root@master de]# kubectl exec -it mypod sh / # cat etc/foo/my-group/my-password / # cat etc/foo/my-group/my-username admin/ # exit
这时数据将分别存放在 /etc/foo/my-group/my-username 和 /etc/foo/my-group/my-password中。
以volume方式使用的secret 支持动态更新: secret更细后,容器中的数据也就更新。
[root@master de]# echo -n caoyi888 | base64
Y2FveWk4ODg=
[root@master de]# cat env.yml apiVersion: v1 data: password: Y2FveWk4ODg= username: YWRtaW4= kind: Secret metadata: name: mysecret1
[root@master de]# kubectl apply -f env.yml
secret/mysecret1 configured
[root@master de]# kubectl exec -it mypod sh / # cat /etc/foo/my-group/my-username / # cat /etc/foo/my-group/my-password caoyi888/ # exit
没有动pod,就可以动态更新密码
环境变量方式使用secret
通过volume使用secret ,容器必须从文件读取数据,会稍微麻烦,kubernetes还支持通过环境变量使用secret
[root@master de]# cat pod.yml apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - image: busybox name: mypod args: - /bin/sh - -c - sleep 30000 env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password
[root@master de]# kubectl exec -it mypod sh / # echo $SECRET_USERNAME admin / # echo $SECRET_PASSWORD 123456
通过环境变量secret_username和secret_password成功读取到secret的数据。
需要注意的是,环境变量读取secret很方便,但无法支撑secret动态更新。
用configMap管理配置
secret可以为pod提供密码、token,私钥等敏感数据;对于一些非敏感数据,比如应用的配置信息,用configMap。
configMap的创建和使用方法好与secregt非常类似,主要的不同是数据以明文形式存放。
通过--from-literal:
[root@master de]# kubectl create configmap myconfigimap --from-literal=config1=xxx --from-literal=config2=yy configmap/myconfigimap created [root@master de]# kubectl describe configmaps myconfigimap Name: myconfigimap Namespace: default Labels: <none> Annotations: <none> Data ==== config2: ---- yy config1: ---- xxx Events: <none>
每个--from-literal对应一个信息条目。
通过--from-file:
[root@master de]# echo -n aaa > ./config1 [root@master de]# echo -n bbb > ./config2 [root@master de]# kubectl create configmap myconfigmap1 --from-file=./config1 --from-file=./config2 configmap/myconfigmap1 created [root@master de]# kubectl get configmap myconfigmap1 NAME DATA AGE myconfigmap1 2 74s [root@master de]# kubectl describe configmaps myconfigmap1 Name: myconfigmap1 Namespace: default Labels: <none> Annotations: <none> Data ==== config1: ---- aaa config2: ---- bbb Events: <none>
每个文件内容对应一个信息条目。
通过 --from-env-file
[root@master de]# cat env.txt config1=aaa config2=bbb [root@master de]# kubectl create configmap myconfigmap --from-env-file=env.txt configmap/myconfigmap created [root@master de]# kubectl get configmaps NAME DATA AGE myconfigimap 2 7m42s myconfigmap 2 26s myconfigmap1 2 4m42s [root@master de]# kubectl describe configmaps myconfigmap Name: myconfigmap Namespace: default Labels: <none> Annotations: <none> Data ==== config1: ---- aaa config2: ---- bbb Events: <none>
文件env.txt中每行key=value对应每一个信息条目
通过YAML配置文件:
[root@master de]# cat caoyi.yml apiVersion: v1 data: config1: aaa config2: bbb kind: ConfigMap metadata: name: myconfigmap2 [root@master de]# kubectl apply -f caoyi.yml configmap/myconfigmap2 created [root@master de]# kubectl get configmaps NAME DATA AGE myconfigimap 2 11m myconfigmap 2 4m15s myconfigmap1 2 8m31s myconfigmap2 2 12s [root@master de]# kubectl describe configmaps myconfigmap2 Name: myconfigmap2 Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"config1":"aaa","config2":"bbb"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"myconfigmap2","namespa... Data ==== config1: ---- aaa config2: ---- bbb Events: <none>
案例:
通过volume方式
[root@master de]# cat pod.yml apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - image: busybox name: mypod volumeMounts: - mountPath: /etc/foo name: foo readOnly: true args: - /bin/sh - -c - sleep 30000 volumes: - name: foo configMap: name: myconfigmap2
[root@master de]# kubectl exec -it mypod sh / # cat /etc/foo/ ..2020_07_26_08_12_42.774514494/ config1 ..data/ config2 / # cat /etc/foo/config1 / # cat /etc/foo/config2 bbb/ # exit
环境变量方式:
[root@master de]# cat pod.yml apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - image: busybox name: mypod args: - /bin/sh - -c - sleep 30000 env: - name: BALALA_1 valueFrom: configMapKeyRef: name: myconfigmap2 key: config1 - name: BALALA_2 valueFrom: configMapKeyRef: name: myconfigmap2 key: config2
[root@master de]# kubectl exec -it mypod sh / # echo $BALALA / # echo $BALALA_1 aaa / # echo $BALALA_2 bbb
大多数情况下,配置信息都已文件形式提供,所以在创建configMap时通常采用 --from-file或ymal方式,读取configMap 时通常采用volume方式
比如给pod传递如何记录日志的配置信息:
[root@master de]# cat loggin.conf class: logging.handlers.RotatingFileHandler formatter: precise level: INFO filename: %hostname-%timestamp.log [root@master de]# kubectl create configmap myconfigmap3 --from-file=loggin.conf --dry-run -o yaml apiVersion: v1 data: loggin.conf: | class: logging.handlers.RotatingFileHandler formatter: precise level: INFO filename: %hostname-%timestamp.log kind: ConfigMap metadata: creationTimestamp: null name: myconfigmap3 [root@master de]# cat caoyi1.yml apiVersion: v1 data: loggin.conf: | class: logging.handlers.RotatingFileHandler formatter: precise level: INFO filename: %hostname-%timestamp.log kind: ConfigMap metadata: creationTimestamp: null name: myconfigmap3 [root@master de]# kubectl apply -f caoyi1.yml configmap/myconfigmap3 created [root@master de]# kubectl get configmaps NAME DATA AGE myconfigimap 2 35m myconfigmap 2 27m myconfigmap1 2 32m myconfigmap2 2 23m myconfigmap3 1 11s [root@master de]# kubectl describe configmaps myconfigmap3 Name: myconfigmap3 Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"loggin.conf":"class: logging.handlers.RotatingFileHandler\nformatter: precise\nlevel: INFO\nfilename: %hostnam... Data ==== loggin.conf: ---- class: logging.handlers.RotatingFileHandler formatter: precise level: INFO filename: %hostname-%timestamp.log Events: <none> [root@master de]# cat loggin.conf class: logging.handlers.RotatingFileHandler
在pod中使用此configMap,配置文件为:
[root@master de]# kubectl exec -it mypod sh / # ls /etc/config/de/loggin.conf /etc/config/de/loggin.conf / # cat /etc/config/de/loggin.conf class: logging.handlers.RotatingFileHandler formatter: precise level: INFO filename: %hostname-%timestamp.log / # exit
配置信息已经保存到/etc/myapp/loggin.conf文件中。secret一样,volume形式的configMAP也支持动态更新。