第10章 Secret & Configmap
应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名、密码或者密钥。将这些信息直接保存在容器镜像中显然不妥,Kubernetes提供的解决方案是Secret。
Secret会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。Secret会以Volume的形式被mount到Pod,容器可通过文件的方式使用Secret中的敏感数据;此外,容器也可以环境变量的方式使用这些数据。
Secret可通过命令行或YAML创建。比如希望Secret中包含如下信息:用户名admin、密码123456。
10.1 创建Secret
有四种方法创建Secret:
(1)通过--from-literal:
kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
每个--from-literal对应一个信息条目。
(2)通过--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配置文件,如图10-1所示。

图10-1
文件中的敏感数据必须是通过base64编码后的结果,如图10-2所示。

图10-2
执行kubectl apply创建Secret,如图10-3所示。

图10-3
10.2 查看Secret
通过kubectl get secret查看存在的secret,如图10-4所示。

图10-4
显示有两个数据条目,通过kubectl describe secret查看条目的Key,如图10-5所示。

图10-5
如果还想查看Value,可以用kubectl edit secret mysecret,如图10-6所示。

图10-6
然后通过base64将Value反编码,如图10-7所示。

图10-7
10.3 在Pod中使用Secret
Pod可以通过Volume或者环境变量的方式使用Secret。
10.3.1 Volume方式
Pod的配置文件如图10-8所示。

图10-8
① 定义volume foo,来源为secret mysecret。
② 将foo mount到容器路径/etc/foo,可指定读写权限为readOnly。
创建Pod并在容器中读取Secret,如图10-9所示。

图10-9
可以看到,Kubernetes会在指定的路径/etc/foo下为每条敏感数据创建一个文件,文件名就是数据条目的Key,这里是/etc/foo/username和/etc/foo/password,Value则以明文存放在文件中。
我们也可以自定义存放数据的文件名,比如将配置文件改为如图10-10所示那样。

图10-10
这时数据将分别存放在/etc/foo/my-group/my-username和/etc/foo/my-group/my-password中。
以Volume方式使用的Secret支持动态更新:Secret更新后,容器中的数据也会更新。
将password更新为abcdef,base64编码为YWJjZGVm,如图10-11所示。

图10-11
更新Secret,如图10-12所示。

图10-12
几秒钟后,新的password会同步到容器,如图10-13所示。

图10-13
10.3.2 环境变量方式
通过Volume使用Secret,容器必须从文件读取数据,稍显麻烦,Kubernetes还支持通过环境变量使用Secret。
Pod配置文件示例如图10-14所示。

图10-14
创建Pod并读取Secret,如图10-15所示。

图10-15
通过环境变量SECRET_USERNAME和SECRET_PASSWORD成功读取到Secret的数据。
需要注意的是,环境变量读取Secret很方便,但无法支撑Secret动态更新。
10.4 ConfigMap
Secret可以为Pod提供密码、Token、私钥等敏感数据;对于一些非敏感数据,比如应用的配置信息,则可以用ConfigMap。
ConfigMap的创建和使用方式与Secret非常类似,主要的不同是数据以明文的形式存放。
与Secret一样,ConfigMap也支持四种创建方式:
(1)通过--from-literal:
kubectl create configmap myconfigmap --from-literal=config1=xxx--from-literal=config2=yyy
每个--from-literal对应一个信息条目。
(2)通过--from-file:
echo -n xxx > ./config1
echo -n yyy > ./config2
kubectl create configmap myconfigmap --from-file=./config1 --from-file=./config2
每个文件内容对应一个信息条目。
(3)通过--from-env-file:
cat << EOF > env.txt
config1=xxx
config2=yyy
EOF
kubectl create configmap myconfigmap --from-env-file=env.txt
文件env.txt中每行Key=Value对应一个信息条目。
(4)通过YAML配置文件,如图10-16所示。文件中的数据直接以明文输入。

图10-16
与Secret一样,Pod也可以通过Volume或者环境变量的方式使用Secret。
(1)Volume方式如图10-17所示。

图10-17
(2)环境变量方式如图10-18所示。

图10-18
大多数情况下,配置信息都以文件形式提供,所以在创建ConfigMap时通常采用--from-file或YAML方式,读取ConfigMap时通常采用Volume方式。比如给Pod传递如何记录日志的配置信息,如图10-19所示。

图10-19
可以采用--from-file形式,将其保存在文件logging.conf中,然后执行命令:
kubectl create configmap myconfigmap --from-file=./logging.conf
如果采用YAML配置文件,其内容则如图10-20所示。

图10-20
注意,别漏写了Key logging.conf后面的|符号。
创建并查看ConfigMap,如图10-21所示。

图10-21
在Pod中使用此ConfigMap,配置文件如图10-22所示。

图10-22
① 在volume中指定存放配置信息的文件相对路径为myapp/logging.conf。
② 将volume mount到容器的/etc目录。
创建Pod并读取配置信息,如图10-23所示。

图10-23
配置信息已经保存到/etc/myapp/logging.conf文件中。与Secret一样,Volume形式的ConfigMap也支持动态更新,留给大家自己实践。
10.5 小结
本章我们学习了如何向Pod传递配置信息。如果信息需要加密,可使用Secret;如果是一般的配置信息,则可使用ConfigMap。
Secret和ConfigMap支持四种定义方法。Pod在使用它们时,可以选择Volume方式或环境变量方式,不过只有Volume方式支持动态更新。