7-configmap-secert
ConfigMap 和 Secret 配置应用程序
配置容器化应用程序
配置应用程序的方法:
- 向容器传递命令行参数
- 为每个容器设置自定义的环境变量
- 通过特殊类型的卷将配置文件挂载到容器中
向容器传递命令行参数
- ENTRYPOINT 定义容器启动时被调用的可执行程序
- CMD 指定传递给 ENTRYPOINT 的参数
shell 形式与 exec 形式的主要区别是命令是否在 shell 中调用。
- shell 形式:
ENTRYPOINT node app.js
- exec 形式:
ENTRYPOINT ["node", "app.js"]
# 使用默认的命令行参数
ø> docker run -it bwangel/fortune:args
Configured to generate new fortune every 10 seconds
Sat Feb 13 01:54:01 UTC 2021 Writing fortune to /var/htdocs/index.html
Sat Feb 13 01:54:11 UTC 2021 Writing fortune to /var/htdocs/index.html
^C
# 传递命令行参数给容器,覆盖默认的值
ø> docker run -it bwangel/fortune:args 5
Configured to generate new fortune every 5 seconds
Sat Feb 13 01:54:23 UTC 2021 Writing fortune to /var/htdocs/index.html
Sat Feb 13 01:54:28 UTC 2021 Writing fortune to /var/htdocs/index.html
Sat Feb 13 01:54:33 UTC 2021 Writing fortune to /var/htdocs/index.html
Sat Feb 13 01:54:38 UTC 2021 Writing fortune to /var/htdocs/index.html
^C
k8s 配置中的 cmd
和 args
选项可以覆盖镜像的 entrypoint
和 cmd
设置。
注意: 字符串值无需使用引号包裹,数值需要。
args:
- foo
- bar
- "15"
为容器设置环境变量
环境变量被设置在 pod 的容器定义中,并非是 pod 级别。k8s 在 pod 中会自动暴露相同命名空间下 Service 的环境变量。所以环境变量可以被看作是注入的配置。
环境变量的定义中可以使用 $(SOME_ENV)
的形式引用其他环境变量,同样,cmd 和 args 的配置也可以引用其他环境变量。
利用 ConfigMap 解偶配置
configmap 是一个键值对的表,不同的命名空间下可以有同名的 configmap,通过这种方式将配置和 pod 定义分离开来。
创建 configmap 的多种来源以及最终存储的值:
k create configmap my-config --from-file=foo.json --from-file=bar=foobar.conf --from-file=config-opts/ --from-literal=some=thing
如果创建的 Pod 中引用的 configMap 不存在,那么引用 configmap 的容器会启动失败,其他容器能够正常启动。 如果被引用的 configmap 后续又被正常创建了,那么失败的容器后面又可以重新成功运行。
注意:
envFrom
可以将 configmap 中的配置项设置为环境变量,如果配置项的名称不是一个合法的环境变量名(数字字母+下划线),那么这个环境变量在创建时就会被自动忽略,且不会发出任何事件通知。
- 从本地文件创建 configmap
# configmap-files 是本地的一个文件夹
ø> k create configmap fortune-config --from-file=configmap-files
configmap/fortune-config created
- 检查创建的 configmap 的配置项
ø> k get configmap fortune-config -o=yaml
apiVersion: v1
# 注意,配置项中的管道符号`|`表示配置项的值是一个多行字面量
data:
my-nginx-config.conf: |
server {
listen 80;
server_name kubia.example.com;
gzip on;
gzip_types text/plain application/xml;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
sleep-interval: |
25
kind: ConfigMap
metadata:
creationTimestamp: "2021-02-14T07:09:19Z"
name: fortune-config
namespace: default
resourceVersion: "15400246"
selfLink: /api/v1/namespaces/default/configmaps/fortune-config
uid: a0925cca-bf39-4e67-9cd9-c5a6ea1eae83
- 配置卷是通过挂载的方式加入到容器上的,挂载某一文件夹会隐藏该文件夹中已存在的文件。
mountPath 和 subPath 选项可以指定只挂载文件,而不挂载整个文件夹,这样容器的文件夹就不会覆盖了。
spec:
containers:
- image: some/image
volumeMounts:
- name: myvolume
# 只挂载某个文件,而不是挂载一个文件夹
mountPath: /etc/someconfig.conf
subPath: myconfig.conf
- 更新配置且不重启容器
# edit 命令可以修改 configmap 中的配置文件
ø> k edit configmap fortune-config
configmap/fortune-config edited
# 修改完配置后,再通知 nginx 重启应用
ø> k exec -it -c web-server fortune-configmap-volume -- nginx -s reload
2021/02/16 03:39:49 [notice] 43#43: signal process started
# 这样我们就达到了不重启容器更新配置的目的
注意: configmap 更新时,不同的容器同步配置文件的时间是不同的,因此有可能出现容器间配置文件不一致的情况。
我们可以看到,被挂载的文件链接到了 ..data
文件夹中,而 ..data
文件夹又是一个软连接。
k8s 在更新文件的时候,会先创建好新的文件,再修改 ..data
的链接,这样就达到了一次性更新所有文件的目的。
ø> k exec -it -c web-server fortune-configmap-volume -- ls -lA /etc/nginx/conf.d/ 11:42:58 (02-16)
total 4
drwxr-xr-x 2 root root 4096 Feb 16 03:39 ..2021_02_16_03_39_25.637552423
lrwxrwxrwx 1 root root 31 Feb 16 03:39 ..data -> ..2021_02_16_03_39_25.637552423
lrwxrwxrwx 1 root root 16 Feb 16 03:30 gzip.conf -> ..data/gzip.conf
使用 Secret 给容器传递敏感数据
Secret 是一种类似与 Configmap 的资源,它存储的也是键值对的映射,它支持:
- 将 Secret 条目作为环境变量传递给容器
- 将 Secret 条目暴露为卷中的文件
同时,为了保证 Secret 的安全性,k8s 仅仅将 Secret 分发到需要访问 Secret 的 pod 的所在节点上,同时,Secert 只会写到节点的内存上,不会写到物理存储上。