(十)Kubernetes ConfigMap和Secret
ConfigMap资源
介绍
ConfigMap
是让配置文件从镜像中解耦,让镜像的可移植性和可复制性。许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。这些配置信息需要与docker image
解耦,你总不能每修改一个配置就重做一个image
吧?ConfigMap API
给我们提供了向容器中注入配置信息的机制,ConfigMap
可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON
二进制大对象。ConfigMap
保存的值为键值方式,value
长度没有限制。
创建ConfigMap
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
ConfigMap
支持命令创建和使用清单创建。有以下四种方式创建。
1、命令直接创建 --from-literal:
为
“kubectl create configmap”
命令使用“--from-literal”
选项可在命令行直接给出键值来创建ConfigMap
对象,重复使用此选项可以传递多个键值对。格式如下:kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2
[root@k8s-master ~]# kubectl create configmap nginx-config --from-literal=nginx_port=80 --from-literal=server_name=www.ilinux.cn #创建cm资源nginx-config,并指定两个键值 configmap/nginx-config created [root@k8s-master ~]# kubectl get cm #查看cm资源 NAME DATA AGE nginx-config 2 4s [root@k8s-master ~]# kubectl describe cm/nginx-config #查看cm资源nginx-config的详细信息 Name: nginx-config Namespace: default Labels: <none> Annotations: <none> Data ==== nginx_port: ---- 80 server_name: ---- www.ilinux.cn Events: <none>
2、命令行基于文件创建 --from-file:
为
“kubectl create configmap”
命令使用“--from-file”
选项即可基于文件内容来创建ConfigMap
对象,同样可以重复多次使用。格式如下:kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
[root@k8s-master ~]# mkdir configmap && cd configmap #创建一个测试目录 [root@k8s-master configmap]# vim www.conf #编辑文件内容用作cm的value server { server_name www.ilinux.cn; listen 80; root /data/web/html/; } [root@k8s-master configmap]# kubectl create configmap nginx-www --from-file=www.conf=./www.conf #使用上面创建的文件来创建cm资源对象 configmap/nginx-www created [root@k8s-master configmap]# kubectl get cm #查看cm资源对象 NAME DATA AGE nginx-config 2 7m1s nginx-www 1 5s [root@k8s-master configmap]# kubectl get cm nginx-www -o yaml #查看cm资源对象nginx-www的现象信息 apiVersion: v1 data: www.conf: | server { server_name www.ilinux.cn; listen 80; root /data/web/html/; } kind: ConfigMap ......
3、命令行基于目录创建 --from-file:
如果配置文件数量较多且存储于有限的目录之中,
kubectl
还提供了基于目录直接将多个文件分别收纳为键值数据的ConfigMap
资源创建方式。将“--from-file”
选项后面所跟的路径指向一个目录路径就能将目录下的所有文件一同创建于同一ConfigMap
资源中,命令格式如下:kubectl create configmap <configmap_name> --from-file=<path-to-directory>
这里假设/data/configs/nginx/conf.d/这个目录下有许多的nginx的配置文件,下面这条命令则将这个目录下的所有配置文件在创建ConfigMap资源时,会分别存储为对应的键值数据。 # kubectl create configmap nginx-config-files --from-file=/data/configs/nginx/conf.d/
4、使用资源清单创建:
基于清单文件创建
ConfigMap
资源时,它所使用的字段包括通常的apiVersion
、kind
和metadata
字段,以及用于存储数据的关键字段“data”
。[root@k8s-master ~]# kubectl explain cm KIND: ConfigMap VERSION: v1 FIELDS: apiVersion <string> kind <string> metadata <Object> binaryData <map[string]string> data <map[string]string>
[root@k8s-master configmap]# vim configmap-demo.yaml apiVersion: v1 kind: ConfigMap metadata: name: configmap-demo namespace: default data: log_level: INFO log_file: /var/log/test.log [root@k8s-master configmap]# kubectl apply -f configmap-demo.yaml configmap/configmap-demo created [root@k8s-master configmap]# kubectl get cm NAME DATA AGE configmap-demo 2 6s nginx-config 2 23m nginx-www 1 16m [root@k8s-master configmap]# kubectl get cm/configmap-demo -o yaml apiVersion: v1 data: log_file: /var/log/test.log log_level: INFO kind: ConfigMap metadata: ....
使用ConfigMap
1、环境变量方式注入到Pod
[root@k8s-master configmap]# vim pod-configmap-1.yaml apiVersion: v1 kind: Pod metadata: name: pod-cm-1 namespace: default labels: app: myapp spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 env: - name: NGINX_SERVER_PORT valueFrom: #下面这一段表示变量NGINX_SERVER_PORT的值来自于configmap资源nginx-config的key(nginx_port)的值 configMapKeyRef: name: nginx-config #configmap资源名称 key: nginx_port #configmap资源里面的key名 - name: NGINX_SERVER_NAME valueFrom: configMapKeyRef: name: nginx-config key: server_name [root@k8s-master configmap]# kubectl apply -f pod-configmap-1.yaml #创建Pod pod/pod-cm-1 created [root@k8s-master configmap]# kubectl get pods #查看pod NAME READY STATUS RESTARTS AGE pod-cm-1 1/1 Running 0 4s [root@k8s-master configmap]# kubectl exec -it pod-cm-1 -- printenv |grep NGINX #连接pod资源pod-cm-1并执行命令printenv打印环境变量。过滤是否有上面定义的两个环境变量 NGINX_SERVER_PORT=80 NGINX_SERVER_NAME=www.ilinux.cn #测试,修改端口,可以发现使用环境变量的注入pod中的端口不会根据配置的变更而改变 [root@k8s-master configmap]# kubectl edit cm/nginx-config #编辑cm资源nginx-config将nginx_port值改为8080 ...... apiVersion: v1 data: nginx_port: "8080" ...... [root@k8s-master configmap]# kubectl exec -it pod-cm-1 -- printenv |grep NGINX NGINX_SERVER_PORT=80 NGINX_SERVER_NAME=www.ilinux.cn
2、存储卷方式挂载ConfigMap
[root@k8s-master configmap]# vim pod-configmap-2.yaml apiVersion: v1 kind: Pod metadata: name: pod-cm-2 namespace: default labels: app: myapp spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 volumeMounts: - name: nginxconf mountPath: /etc/nginx/config.d/ readOnly: true volumes: #创建一个存储卷 - name: nginxconf #存储卷名称 configMap: #使用configMap类型 name: nginx-config #指定configmap资源名称 [root@k8s-master configmap]# kubectl apply -f pod-configmap-2.yaml #创建Pod pod/pod-cm-2 created [root@k8s-master configmap]# kubectl get pods #查看pod NAME READY STATUS RESTARTS AGE pod-cm-1 1/1 Running 0 10m pod-cm-2 1/1 Running 0 4s [root@k8s-master configmap]# kubectl exec -it pod-cm-2 -- /bin/sh #连接pod资源pod-cm-2,并进入到挂载目录查看。 / # ls /etc/nginx/config.d/ nginx_port server_name / # cd /etc/nginx/config.d/ /etc/nginx/config.d # cat nginx_port 8080 /etc/nginx/config.d # cat server_name www.ilinux.cn #测试,修改端口,可以发现使用volume的方式挂载configmap到容器中,支持动态更新。 [root@k8s-master configmap]# kubectl edit cm/nginx-config #编辑cm资源nginx-config将nginx_port值改为8088 apiVersion: v1 data: nginx_port: "8088" [root@k8s-master configmap]# kubectl exec -it pod-cm-2 -- /bin/sh /etc/nginx/config.d # cat nginx_port 8088 /etc/nginx/config.d #
示例
这里使用上面创建的configmap
资源nginx-www
示例。
1)编辑资源清单文件
[root@k8s-master configmap]# vim pod-configmap-3.yaml apiVersion: v1 kind: Pod metadata: name: pod-cm-3 namespace: default labels: app: nginx spec: containers: - name: nginx image: nginx:1.12 ports: - name: http containerPort: 80 volumeMounts: - name: nginxwww mountPath: /etc/nginx/conf.d/ readOnly: true volumes: - name: nginxwww configMap: name: nginx-www
2)创建Pod
[root@k8s-master configmap]# kubectl apply -f pod-configmap-3.yaml pod/pod-cm-3 created [root@k8s-master configmap]# kubectl get pods -o wide #查看pod NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-cm-3 1/1 Running 0 5s 10.244.1.92 k8s-node1 <none> <none>
3)进入到Pod
中查看配置文件,并创建对应的数据目录进行测试
[root@k8s-master configmap]# kubectl exec -it pod-cm-3 -- /bin/sh #进入到pod中 # ls /etc/nginx/conf.d www.conf # cat /etc/nginx/conf.d/www.conf #查看生成的www.conf配置文件 server { server_name www.ilinux.cn; listen 80; root /data/web/html/; } # nginx -T #查看当前nginx加载的配置文件 ...... server { server_name www.ilinux.cn; listen 80; root /data/web/html/; } # mkdir -p /data/web/html #创建数据目录 # echo "<h1>ConfigMap Pod Test</h1>" >> /data/web/html/index.html #创建测试文件 #这里拿kubernetes集群节点测试 [root@k8s-master ~]# vim /etc/hosts #编辑hosts文件将上面的pod和对应的域名进行解析 10.244.1.92 www.ilinux.cn [root@k8s-master ~]# curl www.ilinux.cn #访问测试 <h1>ConfigMap Pod Test</h1>
Secret资源
介绍
Secret
对象存储数据的方式及使用方式类似于ConfigMap
对象,以键值方式存储数据,在Pod
资源中通过环境变量或存储卷进行数据访问,解决了密码、token
、密钥等敏感数据的配置问题,而不需要将这些敏感数据暴露到镜像或者pod spec
中。另外,Secret
对象的数据存储和打印格式为Base64
编码的字符串,因此用户在创建Secret
对象时也要提供此种编码格式的数据。在容器中以环境变量或存储卷的方式访问时,它们会被自动解码为明文格式。需要注意的是,如果是在Master
节点上,Secret
对象以非加密的格式存储在etcd
中,所以需要对etcd
的管理和权限进行严格控制。
Secret
的四种类型
-
Opaque:自定义数据内容;
base64
编码,用来存储密码、秘钥、信息、证书等数据,类型标识符为generic
。 -
kubernetes.io/service-account-token:`Service Account
的认证信息,可在创建
Service Account`时由Kubernetes自动创建。 -
kubernetes.io/dockerconfigjson:用来存储Docker镜像仓库的认证信息,类型标识符为
docker-regiestry
。 -
kubernetes.io/tls:用于为
SSL
通信模式存储证书和私钥文件,命令式创建时类型标识为tls
。
创建Secret
1、命令直接创建 --from-literal:
为
“kubectl create secret generic”
命令使用“--from-literal”
选项可在命令行直接给出键值来创建ConfigMap
对象,重复使用此选项可以传递多个键值对。格式如下:kubectl create secret generic NAME --from-literal=key1=value1 --from-literal=key2=value2
[root@k8s-master ~]# kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=password=MyP@sswd #创建secret资源mysql-auth,并指定两个键值 secret/mysql-auth created [root@k8s-master ~]# kubectl get secret #查看secret资源 NAME TYPE DATA AGE default-token-blm9l kubernetes.io/service-account-token 3 3d mysql-auth Opaque 2 17s [root@k8s-master ~]# kubectl describe secret/mysql-auth #查看secret资源mysql-auth的详细信息 Name: mysql-auth Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== password: 8 bytes username: 4 bytes
2、命令行基于文件创建 --from-file:
为
“kubectl create secret generic”
命令使用“--from-file”
选项即可基于文件内容来创建ConfigMap
对象,同样可以重复多次使用。格式如下:kubectl create secret generic my-secret --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
[root@k8s-master ~]# mkdir secret && cd secret [root@k8s-master secret]# echo -n admin > ./username [root@k8s-master secret]# echo -n 123456 > ./password [root@k8s-master secret]# [root@k8s-master secret]# kubectl create secret generic mysecret --from-file=username=./username --from-file=password=./password secret/mysecret created [root@k8s-master secret]# kubectl get secret NAME TYPE DATA AGE default-token-blm9l kubernetes.io/service-account-token 3 3d mysecret Opaque 2 6s mysql-auth Opaque 2 5m23s [root@k8s-master secret]# kubectl get secret/mysecret -o yaml apiVersion: v1 data: password: MTIzNDU2 #这里可以看到secret存储的值都是base64编码格式 username: YWRtaW4= kind: Secret metadata ......
3、使用资源清单创建:
Secret
资源是标准的Kubernetes API
对象,除了标准的apiVersion
、kind
和metadata
字段,它可用的其他字段如下:data <map[string]string> #"key:value"格式的数据,通常是敏感信息,数据格式需要以Base64格式编码的字符串,因此需要事先完成编码 stringData <map[string]string> #以明文格式(非Base64编码)定义的“key:value"数据;无须事先对数据进行Base64编码,而是在创建为Secret对象时自动进行编码并保存于data字段中。 type <string> #仅是为了便于编程方式处理Secret数据而提供的类型标识。
[root@k8s-master secret]# vim secret-demo.yaml apiVersion: v1 kind: Secret metadata: name: secret-demo namespace: default stringData: username: redis password: redisP@ss type: Opaque [root@k8s-master secret]# kubectl apply -f secret-demo.yaml secret/secret-demo created [root@k8s-master secret]# kubectl get secret NAME TYPE DATA AGE default-token-blm9l kubernetes.io/service-account-token 3 3d1h mysecret Opaque 2 28m mysql-auth Opaque 2 33m secret-demo Opaque 2 5s [root@k8s-master secret]# kubectl get secret/secret-demo -o yaml apiVersion: v1 data: password: cmVkaXNQQHNz username: cmVkaXM= kind: Secret metadata: ......
使用Secret
类似于
Pod
消费ConfigMap
对象的方式,Secret
对象可以注入为环境变量,也可以存储为存储卷形式挂载使用。因为Secret
默认保存的是非明文格式,通过注入为环境变量实为不明智。
存储卷方式示例:
这里假设需要为Nginx
测试创建SSL
虚拟主机
1)首先创建私钥和自签证书
[root@k8s-master secret]# openssl genrsa -out nginx.key 2048 [root@k8s-master secret]# openssl req -new -x509 -key nginx.key -out nginx.crt -subj /C=CN/ST=ShenZhen/L=ShenZhen/O=DevOps/CN=www.ilinux.cn
2)创建secret
[root@k8s-master secret]# kubectl create secret tls nginx-ssl --key=./nginx.key --cert=./nginx.crt secret/nginx-ssl created [root@k8s-master secret]# kubectl get secret nginx-ssl NAME TYPE DATA AGE nginx-ssl kubernetes.io/tls 2 14s
3)编辑资源清单
[root@k8s-master secret]# vim pod-secret-demo.yaml apiVersion: v1 kind: Pod metadata: name: secret-volume-demo namespace: default spec: containers: - name: web-server image: nginx:1.12 volumeMounts: - name: nginxcert mountPath: /etc/nginx/ssl/ readOnly: true volumes: - name: nginxcert secret: secretName: nginx-ssl
4)创建pod
并验证
[root@k8s-master secret]# kubectl apply -f pod-secret-demo.yaml pod/secret-volume-demo created [root@k8s-master secret]# kubectl exec -it secret-volume-demo -- /bin/sh # ls /etc/nginx/ssl tls.crt tls.key
