ConfigMap 和 Secret 是 Kubernetes 系统上两种特殊类型的存储卷, ConfigMap 对象用 于为容器中的应用提供配置数据以定制程序的行为,不过敏感的配置信息,例如密钥、证书 等通常由 Secret 对象来进行配置。 它们将相应的配置信息保存于对象中,而后在 Pod 资源 上以存储卷的形式将其挂载并获取相关的配置,以实现配置与镜像文件的解捐。 本章将主要讲解 ConfigMap与Secret 存储卷的用法。
ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap跟secret很类似,但它可以更方便地处理不包含敏感信息的字符串。
作为分布式系统的 Kubernetes 也提供了统一配置管理方案一一ConfigMap。 Kubemetes 基于 ConfigMap 对象实现了将配置文件从容器镜像中解祠,从而增强了容器应用的可移植 性。 简单来说,一个 ConfigMap 对象就是一系列配置数据的集合,这些数据可“注入”到 Pod 对象中,并为容器应用所使用;注入方式有挂载为存储卷和传递为环境变量两种。
ConfigMap 对象将配置数据以键值对的形式进行存储,这些数据可以在 Pod 对象中使 用或者为系统组件提供配置,例如控制器对象等。 不过,无论应用程序如何使用 ConfigMap 对象中的数据,用户都完全可以通过在不同的环境中创建名称相同但内容不同的 ConfigMap 对象,从而为不同环境中同一功能的 Pod 资源提供不同的配置信息,实现应用与配置的灵活句兑。
Kubernetes 的不少资源既可以使用 kubectl create命令创建, 也可以使用清单创建, 例如 前面讲到的 namespaceo ConfigMap 是另-个两种创建方式都比较常用的资源。 而且,通过 使用“ kubectl create configmap”命令,用户可以根据目录、文件或直接值创建 ConfigMap 对象。 命令的语法格式如下所示 :
kubectl create conf igrnap <map-name> <data-source>
其中,<map-name>即为 ConfigMap 对象的名称,而 <data-source>是数据源,它可以 通过直接值、文件或目录来获取。 无论是哪一种数据源供给方式,它都要转换为 ConfigMap 对象中的 Key-Value 数据,其中 Key 由用户在命令行给出或是文件数据源的文件名 ,它仅能 由字母、数字、连接号和点号组成,而 Value 则是直接值或文件数据源的内容。
为“ kubectl create configmap,命令使用"--from-literal" 选项可在命令行直接给出键值对来创建 ConfigMap 对象,重复使用此选项则可以传递多个键值对。 命令格式如下:
创建一个名称空间为config以示区别和configmap
--from-literal=redis_host="redis.default.svc.cluster.local" 创建一个redis_hsot的名称为redis.default.svc.cluster.local
--from-literal=log_level="Info" 创建日志级别
[root@master ~]# kubectl create ns config # 创建一个名称空间为config,以示区别 namespace/config created [root@master ~]# kubectl create configmap filebeat-cfg -n config --from-literal=redis_host="redis.default.svc.cluster.local" --from-literal=log_level="Info" # 创建configmap,指定redis_host名称和日志级别 configmap/filebeat-cfg created [root@master ~]# kubectl get cm -n config # 查看创建的configmap信息,在config名称空间下 NAME DATA AGE filebeat-cfg 2 51s [root@master ~]# kubectl get cm -n config -o yaml # 查看configmap详细信息 apiVersion: v1 items: - apiVersion: v1 data: log_level: Info # 日志级别 redis_host: redis.default.svc.cluster.local # redis_host名称 kind: ConfigMap metadata: creationTimestamp: "2020-08-04T01:40:14Z" name: filebeat-cfg namespace: config resourceVersion: "168207" selfLink: /api/v1/namespaces/config/configmaps/filebeat-cfg uid: 2d4517ac-6442-483d-a8d6-60d797fd2a1b kind: List metadata: resourceVersion: "" selfLink: ""
注意:此类方式提供的数据量有限, 一般是在仅通过有限的几个数据项即可为Pod资源提供足够的配置信息时使用。
查看kuberbetes帮助文档,然后再创建yaml配置文件
[root@master configmap]# kubectl explain pods.spec.containers # 可以查看帮助里边的env变量信息 env <[]Object> List of environment variables to set in the container. Cannot be updated. [root@master configmap]# kubectl explain pods.spec.containers.env.valueFrom # 然后再env环境变量下也可以引用 KIND: Pod VERSION: v1 RESOURCE: valueFrom <Object> DESCRIPTION: Source for the environment variable's value. Cannot be used if value is not empty. EnvVarSource represents a source for the value of an EnvVar. FIELDS: configMapKeyRef <Object> # 引用此变量 Selects a key of a ConfigMap. fieldRef <Object> Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP. resourceFieldRef <Object> Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. secretKeyRef <Object> # 引用此变量 Selects a key of a secret in the pod's namespace [root@master configmap]# kubectl explain pods.spec.containers.env.valueFrom.configMapKeyRef # 下面更详细的引用 KIND: Pod VERSION: v1 RESOURCE: configMapKeyRef <Object> DESCRIPTION: Selects a key of a ConfigMap. Selects a key from a ConfigMap. FIELDS: key <string> -required- # 引用文件的键 The key to select. name <string> # 应用文件的名称 Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional <boolean> Specify whether the ConfigMap or its key must be defined
Pod 资源的环境变量值的获得方式之一包括引用 ConfigMap 对 象中的数据,这一点通过在 env 字段中为 valueFrom 内configMapKeyRef对象即可实现, 其使用格式如下 :
其中, 字段 name 的值为要引用的 ConfigMap 对象的名称,字段 key 可用于指定要引用 ConfigMap 对象中某键的键名。 此类环境变量的使用方式与直接定义的环境变量并无区别,它们可被用于容器的启动脚本或直接传递给容器应用等。
1、创建yaml文件
[root@master ~]# mkdir configmap [root@master ~]# cd configmap/ [root@master configmap]# cat pod-cfg.yaml apiVersion: v1 kind: Pod metadata: name: pod-cfg-demo namespace: config spec: containers: - name: filebeat image: ikubernetes/filebeat:5.6.5-alpine env: - name: REDIS_HOST # 定义镜像中redis_host的环境变量名称要大写 valueFrom: # 用来给REDIS_HOST来传值的 configMapKeyRef: name: filebeat-cfg # 引用上面创建好的configMap的值 key: redis_host # 引用上面创建到redis_host的键(创建configMap时的值) - name: LOG_LEVEL # 定义log_level日志级别的环境变量时要大写 valueFrom: configMapKeyRef: name: filebeat-cfg # 也是引用上面的值,与REDIS_HOST值类似 key: log_level # configMap资源中的键
注意:创建引用了 ConfigMap 资源的 Pod 对象时 , 被引用的资源必须事先存在, 否则将无 法启动相应的容器,直到被依赖的资源创建完成为止。不过, 那些未引 用不存在的 ConfigMap 资源的容器将不受 此 影 响 。另外 , ConfigMap 是名称空 间 级别的资源, 它必须与引用它的 Pod 资源在同 一 空间 中 。
2、执行yaml文件并创建pod,查看验证结果
[root@master configmap]# kubectl apply -f pod-cfg.yaml # 创建变量名并引用 pod/pod-cfg-demo created [root@master configmap]# kubectl get pods -n config # 查看此时的pod已经运行 NAME READY STATUS RESTARTS AGE pod-cfg-demo 1/1 Running 0 40s
3、查看此时的环境变量信息
[root@master configmap]# kubectl exec -it pod-cfg-demo -n config -- /bin/sh # 进入pod中查看此时的环境变量 / # printenv KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_SERVICE_PORT=443 LOG_LEVEL=Info # 日志级别是Info HOSTNAME=pod-cfg-demo SHLVL=1 HOME=/root TERM=xterm KUBERNETES_PORT_443_TCP_ADDR=10.96.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 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 KUBERNETES_SERVICE_PORT_HTTPS=443 PWD=/ KUBERNETES_SERVICE_HOST=10.96.0.1 REDIS_HOST=redis.default.svc.cluster.local # 引用的环境变量 FILEBEAT_VERSION=5.6.5
4、此时修改configmap里边的环境变量值,虽然用命令查看此时的环境变量被修改了,实际在pod环境变量并没有被修改。
[root@master ~]# kubectl edit cm filebeat-cfg -n config apiVersion: v1 data: log_level: Notice # 将Info改为Notice redis_host: redis.default.svc.cluster.local [root@master ~]# kubectl get cm filebeat-cfg -n config -o yaml # 用命令查看此时的环境变量已经被修改 apiVersion: v1 data: log_level: Notice # 此时修改完环境变量,并查看此时的环境变量已经被修改 redis_host: redis.default.svc.cluster.local
5、查看pod的环境变量信息未被修改
[root@master configmap]# kubectl exec -it pod-cfg-demo -n config -- /bin/sh / # printenv # 再次查看环境变量 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_SERVICE_PORT=443 LOG_LEVEL=Info # 但是在pod中查看此时的日志级别还是未修改的
存储卷原理:若ConfigMap 对象中的键值来源于较长的文件内容,那么使用环境变量将其导人会使 得变量值占据过多的内存空间而且不易处理。 此类数据通常用于为容器应用提供配置文件, 因此将其内容直接作为文件进行引用方为较好的选择。 其实现方式是,在定义 Pod 资源时, 将此类 ConfigMap 对象配置为 ConfigMap 类型的存储卷,而后由容器将其挂载至特定的挂 载点后直接进行访问。
为“ kubectl create configmap ,命令使用“--from-file” 选项即可基于文件内容来创建ConfigMap对象, 它的命令格式如下。 可以重复多次使用"--from-file"选项传递多个文件内容:
kubectl create configmap <co口figmap_name> --from-file工<path-to-file>
1、创建访问页面路径
[root@master configmap]# cat server.conf # 定义访问页面路径 server { server_name www.peng.com; listen 80; location / { root "/usr/share/nginx/html"; } } [root@master configmap]# cp server.conf server1.conf [root@master configmap]# cat server1.conf server { server_name www.ilinux.io; listen 80; location / { root "/html/ilinux"; } }
2、通过访问页面文件创建configMap,并验证信息
[root@master configmap]# kubectl create configmap nginx-cfg --from-file=./server.conf --from-file=server-second.conf=./server1.conf -n config # 其中server-second.conf是自定义创建的文件名 configmap/nginx-cfg created [root@master configmap]# kubectl get cm -n config # 查看此时创建好的configmap信息 NAME DATA AGE filebeat-cfg 2 72m nginx-cfg 2 30s [root@master configmap]# kubectl get cm nginx-cfg -n config -o yaml apiVersion: v1 data: server.conf: "server {\n \tserver_name www.peng.com;\n \tlisten 80; \tlocation / {\n \t\t \ root \"/usr/share/nginx/html\";\n \t}\n}\n" # 查看此时创建的myserver.conf配置文件 server-second.conf: "server {\n \tserver_name www.ilinux.io;\n \tlisten 80; \tlocation / {\n \t\t root \"/html/ilinux\";\n \t}\n}\n" # 查看此时创建的第二个配置文件 kind: ConfigMap metadata: creationTimestamp: "2020-08-04T02:52:22Z" name: nginx-cfg # configmap名称 namespace: config resourceVersion: "175017" selfLink: /api/v1/namespaces/config/configmaps/nginx-cfg uid: c67ad90a-e873-477e-b76f-8b1e6dbe406b
关联为 Pod 资源的存储卷时, ConfigMap 对象中的每个键都对应地表现为一个文件, 键名转为文件名,而键值则为相应文件的内容,即便是通过直接值创建的键值数据,也一样表现为文件视图。 挂载于容器上之后, 由键值数据表现出的文件位于挂载点目录中,容器中 的进程可直接读取这些文件的内容。 配置Pod 资源时, 基于存储卷的方式引用 ConfigMap 对象的方法非常简单,仅需要指 明存储卷名称及要引用的 ConfigMap 对象名称即可。 下面是于配置文件 myapp-pod.yaml 中定义的 Pod 资源,创建的 ConfigMap 对象 nginx-cfg,容器myapp将其挂载至应用程序 Nginx 加载配置文件模块的目录/etc/ nginx/conf.d 中, 具体如下 :
1、定义一个myapp-pod.yaml文件,将configmap中的nginx-cfg挂载只应用容器中
[root@master configmap]# cat myapp-pod.yaml apiVersion: v1 kind: Pod metadata: name: myapp-pod namespace: config spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: config # 指定挂载的存储卷的名称,与volumes上的名称一致 mountPath: /etc/nginx/conf.d/ volumes: - name: config # 存储卷名称 configMap: name: nginx-cfg # 与前面创建的configmap的nginx-cfg进行关联 items: # 引用哪个键 - key: server.conf # 指定配置文件必须是相对路径才能被调用 path: server-first.conf - key: server-second.conf # key值为上面创建的configmap对应的值 path: server-second.conf # path路径对应的是configmap对应的配置文件
configMap 存储卷的 items 字段的值是一个对象列表,可嵌套使用的字段有三个,具体 如下。
key <string>: 要引用的键名称,必选字段。
path<string>: 对应的键于挂载点目录中生成的文件的相对路径,可以不同于键名称, 必选字段。
mode <integer> : 文件的权限模型,可用范围为 0 到 0777。
上面的配置示例中, server.-firstconf 映射成了server.conf 文件,而 server-second.conf则保持了与键名同名,并明确指定使用 0644 的权限,从而达成了仅装载部分 文件至容器之目的。
2、创建yaml文件,并查看效果
[root@master configmap]# kubectl apply -f myapp-pod.yaml pod/myapp-pod created [root@master configmap]# kubectl get pods -n config NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 12m # 此时查看到新的pod已经创建成功 pod-cfg-demo 1/1 Running 1 7h2m [root@master configmap]# kubectl describe pods nginx-pod -n config # 查看此时的pod运行状态信息,已经是运行状态 .............中间省略了 Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned config/nginx-pod to node2 Normal Pulled 13m kubelet, node2 Container image "nginx:1.14.1-alpine" already present on machine Normal Created 13m kubelet, node2 Created container myapp Normal Started 13m kubelet, node2 Started container myapp
3、进入到容器内部查看此时的配置文件是否存在,和监听的端口是否打开
[root@master configmap]# kubectl exec -it nginx-pod -n config -- /bin/sh # 连接到nginx-pod容器中,查看此时nginx的配置文件信息 / # cd /etc/nginx/conf.d # 切换到访问页面下 /etc/nginx/conf.d # ls # 此时可以看到有两个配置文件信息 server-first.conf server-second.conf /etc/nginx/conf.d # cat server-first.conf # 查看此时的配置文件信息 server { server_name www.peng.com; listen 80; location / { root "/html/peng"; } } /etc/nginx/conf.d # cat server-second.conf # 查看此时的配置文件信息 server { server_name www.ilinux.io; listen 80; location / { root "/html/ilinux"; } } /etc/nginx/conf.d # netstat -nl # 查看此时的端口号80也已经被监听 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
4、如果想要修改监听的端口号怎么办?我们只需要修改nginx-cfg资源里的信息,而不能修改配置文件,因为你已经创建好了pod的容器
[root@master configmap]# kubectl edit cm nginx-cfg -n config # 修改nginx-cfg的配置信息即可 .......此处省略无关信息 apiVersion: v1 data: server-second.conf: "server {\n \tserver_name www.ilinux.io;\n\tlisten 80;\n \ \tlocation / {\n \t root \"/html/ilinux\";\n \t}\n}\n" server.conf: "server {\n \tserver_name www.peng.com;\n \tlisten 8080;\n \tlocation # 将server.conf中80改为8080即可 / {\n root \"/html/peng\";\n \t}\n}\n"
5、此时可以看到修改后的端口监听状态已经成为8080,并创建两个访问页面进行测试,如果端口没有监听,就需要手动重新加载
[root@master configmap]# kubectl edit cm nginx-cfg -n config # 修改nginx-cfg的配置信息即可 }/etc/nginx/conf.d # cat server-first.conf server { server_name www.peng.com; listen 8080; location / { root "/html/peng"; } } /etc/nginx/conf.d # netstat -nlt # 查看此时的端口号是否正常 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN /etc/nginx/conf.d # nginx -s reload # 如果没监听成功,我们就需要手动重新进行加载 2020/08/04 09:30:35 [notice] 26#26: signal process started /etc/nginx/conf.d # netstat -nlt # 查看此时的端口号已经被重新加载成功为8080端口 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN /etc/nginx/conf.d # mkdir /html/peng -p # 创建访问页面目录 /etc/nginx/conf.d # mkdir /html/ilinux -p # 创建访问页面目录 /etc/nginx/conf.d # echo welcome to shanghai > /html/peng/index.html # 创建访问页面 /etc/nginx/conf.d # echo welcome to shanghai-1 > /html/ilinux/index.html # 创建访问页面 /etc/nginx/conf.d # exit
6、查看pod的IP地址,并写入到hosts文件中,进行域名解析并访问
[root@master configmap]# kubectl get pods -o wide -n config # 查看此时创建的pod IP地址 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-pod 1/1 Running 1 3h55m 10.244.2.70 node2 <none> <none> pod-cfg-demo 1/1 Running 2 10h 10.244.2.71 node2 <none> <none> [root@master configmap]# cat /etc/hosts # 进行域名解析 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.7.101 master 192.168.7.102 node1 192.168.7.103 node2 192.168.7.104 nfs 10.244.2.70 www.peng.com # 在master节点上进行域名解析 10.244.2.70 www.ilinux.io # 在master节点上进行域名解析 [root@master configmap]# curl www.peng.com # 访问网页 welcome to shanghai-1 [root@master configmap]# curl www.ilinux.io:8080 # 访问网页 welcome to shanghai
Secret资源的功能类似于ConfigMap,但它专用于存放敏感数据,例如密码、数字证书、私钥、令牌和SSH key 等。
Secret 对象存储数据的方式及使用方式类似于 ConfigMap 对象,以键值方式存储数据, 在 Pod 资源中通过环境变量或存储卷进行数据访问。 不同的是, Secret 对象仅会被分发至调 用了此对象的 Pod 资源所在的工作节点,且只能由节点将其存储于内存中。 另外, Secret 对 象的数据的存储及打印格式为 Base64 编码的字符串,因此用户在创建 Secret 对象时也要提 供此种编码格式的数据。 不过,在容器中以环境变量或存储卷的方式访问时,它们会被自动 解码为明文格式。
需要注意的是,在 Master 节点上, S巳cret 对象以非加密的格式存储于 etcd中,因此 管理员必须加以精心管控以确保敏感数据的机密性,必须确保 etcd 集群节点间以及与 API Server 的安全通信,etcd 服务的访问授权,还包括用户访问 API Server 时的授权,因为拥有 创建 Pod 资源的用户都可以使用 Secret 资源并能够通过 Pod 中的容器访问其数据。
Secret 对象主要有两种用途, 一是作为存储卷注入到 Pod 上由容器应用程序所使用, 二是用于 kubelet 为 Pod 里的容器拉取镜像时向私有仓库提供认证信息。 不过,后面使用 ServiceAccount 资源自建的 Secret 对象是一种更具安全性的方式。
Secret 资源主要由四种类型组成,具体如下。
注意:base编码并非加密机制,其编码的数据可使用“ base64 …decode”一类的命令进 行解码。
手动创建Secret对象的方式有两种:通过kubectl create命令和使用Secret配置文件。
1、创建secret
不少场景中, Pod 中的应用需要通过用户名和密码访问其他服务,例如访问数据库系统等。 创建此类的 Secret 对象,可以使用“ kubectl create secret generic <SECRET_NAME> --from-literal=key=value'’命令直接进行创建,不过为用户认证之需进行创建时, 其使用的 键名通常是 username 和 password。
[root@master configmap]# kubectl create secret generic mysql-root-password -n config --from-literal=password=centos # 创建secret,名称为mysql-root-password,--from-literal=password密码为centos secret/mysql-root-password created
2、查看创建的secret资源信息,此时查看的密码是通过base64进行加密的,但是通过base64可以进行破解。
[root@master configmap]# kubectl get secret mysql-root-password -n config -o yaml # 查看secret的具体信息 apiVersion: v1 data: password: Y2VudG9z # 创建的密码必须事base64编码密钥 kind: Secret metadata: creationTimestamp: "2020-08-04T14:31:43Z" name: mysql-root-password namespace: config resourceVersion: "230246" selfLink: /api/v1/namespaces/config/secrets/mysql-root-password uid: 0a4a4a2e-9c2b-411c-85eb-fb89b23f6daa type: Opaque [root@master configmap]# echo Y2VudG9z | base64 -d # 将base64编码进行解密,可以查看到此时的密码就是centos centos[root@master configmap]# [root@master configmap]# kubectl get secret -n config # 查看创建的secret信息 NAME TYPE DATA AGE default-token-qmgzk kubernetes.io/service-account-token 3 13h mysql-root-password Opaque 1 40m
1、创建Pod,与前面创建的secret进行关联
[root@master configmap]# cat mysql-pod.yaml apiVersion: v1 kind: Pod metadata: name: mysql namespace: config spec: containers: - name: mysql image: mysql:5.6 env: - name: MYSQL_ROOT_PASSWORD # 镜像定义的环境变量名 valueFrom: secretKeyRef: key: password # 密码的键,对应的密码就是上面创建的centos name: mysql-root-password # 创建的secret名称
2、执行yaml文件,创建pod,并查看pod的详细信息
[root@master configmap]# kubectl apply -f mysql-pod.yaml # 创建pod资源 pod/mysql-pod created [root@master configmap]# kubectl get pods -n config # 查看此时的pod运行状态 NAME READY STATUS RESTARTS AGE mysql-pod 1/1 Running 0 17m nginx-pod 1/1 Running 1 6h3m pod-cfg-demo 1/1 Running 2 12h
3、进入到pod容器中,查看此时的信息,此方法不是保存密钥的妥当方法,里面可以看到登录数据库的密码
[root@master configmap]# kubectl exec -it mysql-pod -n config -- /bin/sh # mysql -pcentos # 登录到数据库中 Warning: Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.6.49 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> exit Bye # printenv # 可以使用printenv进行查看环境变量值 KUBERNETES_SERVICE_PORT=443 KUBERNETES_PORT=tcp://10.96.0.1:443 HOSTNAME=mysql-pod MYSQL_MAJOR=5.6 HOME=/root MYSQL_ROOT_PASSWORD=centos TERM=xterm KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MYSQL_VERSION=5.6.49-1debian9 KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 GOSU_VERSION=1.12 KUBERNETES_SERVICE_HOST=10.96.0.1
类似于 Pod 消费 ConfigMap 对象的方式, Secret 对象可以注入为环境变量,也可以存储为卷形式挂载使用。 不过,容器应用通常会在发生错误时将所有环境变量保存于日志信息 中,甚至有些应用在启动时即会将运行环境打印到日志中;另外,容器应用调用第三方程序为子进程时,这些子进程能够继承并使用父进程的所有环境变量。 有鉴于此,使用环境变量引用 Secret 对象中的敏感信息实在算不上明智之举。
在 Pod 中使用 Secret 存储卷的方式,除了其类型及引用标识要替换为 Secret 及 secretName 之外,几乎完全类似于 Config Map 存储卷,包括支持使用挂载整个存储卷、只挂载存储卷 中的指定键值以及独立挂载存储卷中的键等使用方式。
1、创建tls.key和tls.crt密钥文件
[root@master configmap]# openssl genrsa -out tls.key 2048 Generating RSA private key, 2048 bit long modulus ..............+++ .......+++ e is 65537 (0x10001) [root@master configmap]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=myapp.peng.com [root@master configmap]# ll total 32 -rw-r--r-- 1 root root 413 Aug 4 17:02 myapp-pod.yaml -rw-r--r-- 1 root root 652 Aug 4 22:31 my-pod.yaml -rw-r--r-- 1 root root 276 Aug 4 22:49 mysql-pod.yaml -rw-r--r-- 1 root root 407 Aug 4 10:12 pod-cfg.yaml -rw-r--r-- 1 root root 112 Aug 4 16:07 server1.conf -rw-r--r-- 1 root root 114 Aug 4 16:48 server.conf -rw-r--r-- 1 root root 1285 Aug 5 21:37 tls.crt # 查看生成的tls.crt文件 -rw-r--r-- 1 root root 1675 Aug 5 21:37 tls.key # 查看此时生成的tls.key文件
2、基于上面创建的tls.key和tls.crt文件创建 tls类型的secret文件
[root@master configmap]# kubectl create secret tls mysql-cert --cert=./tls.crt --key=./tls.key -n config secret/mysql-cert created [root@master configmap]# kubectl get secrets -n config # 查看此时创建的secret状态 NAME TYPE DATA AGE default-token-qmgzk kubernetes.io/service-account-token 3 36h mysql-cert kubernetes.io/tls 2 4m16s mysql-root-password Opaque 1 23h
3、将上面资源清单文件中定义的资源创建于 Kubernetes 系统上,而后再查看容器挂载点 目录中的文件,以确认其挂载是否成功完成,将创建的secret的tls.crt和ltls.key映射为两个文件
[root@master configmap]# cat my-pod.yaml apiVersion: v1 kind: Pod metadata: name: my-pod namespace: config spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: config mountPath: /etc/nginx/conf.d/ - name: tls # tls存储卷 mountPath: /etc/nginx/certs/ # 存储卷挂载目录 volumes: - name: config configMap: name: nginx-cfg items: - key: server.conf path: server-first.conf - key: server-second.conf path: server-second.conf - name: tls # 创建第二个volume secret: secretName: mysql-cert # secret创建的名称 items: - key: tls.crt # 定义tls.crt名称 path: myapp.crt # 映射为此名称 - key: tls.key # 第二个tls.key的名称 path: myapp.key # 映射的名称 mode: 0600 # 文件权限改为0600
4、创建pod,并查看容器内部的密钥文件
[root@master configmap]# kubectl apply -f my-pod.yaml # 创建pod pod/my-pod created [root@master configmap]# kubectl exec -it my-pod -n config -- /bin/sh # 到容器内部查看加密文件 / # cd /etc/nginx/certs /etc/nginx/certs # ls myapp.crt myapp.key /etc/nginx/certs # exit