第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方式支持动态更新。