[kubernetes in Action实践]七、ConfigMap和Secret:配置应用程序

本文详细介绍了在Kubernetes中如何管理应用程序配置,包括使用ConfigMap和Secret传递环境变量、命令行参数,以及实现配置的热更新。ConfigMap用于解耦配置,而Secret则用于安全地传递敏感数据,如Docker镜像仓库的凭证。通过挂载ConfigMap为卷,可以实现在不重启应用的情况下更新配置。同时,文章强调了Secret的内存存储特性,确保了敏感信息的安全。
摘要由CSDN通过智能技术生成

配置容器化应用程序

通常的容器化应用配置:

  • 配置嵌入应用本身(不推荐)
  • 以命令行参数形式配置应用,配置选项多时,将配置文件化
  • 读取环境变量
    相比使用配置文件,优势是不用重新打包
    相比挂载卷,挂载卷需要在容器启动前确保配置文件已写入响应的卷中。(挂载卷因此可以使用gitRepo卷用git仓库管理配置)

向容器传递命令行参数

docker中定义命令和参数

ENTRYPOINT、CMD
Dockerfile的ENTRYPOINT定义容器启动时被调用的可执行程序,CMD指定传递给前者的参数。

尽管可以直接使用CMD指令指定镜像运行时想要执行的命令, 正确的做法依旧是借助ENTRYPOINT指令, 仅仅用CMD指定所需的默认参数。

之后,可以直接运行:docker run <image> <arguments>,传参数会覆盖CMD指定的参数。

shell形式:ENTRYPOINT node app.js
在这里插入图片描述

exec形式:ENTRYPOINT [“node”, “app. js”]
在这里插入图片描述

区别是是否在shell中被调用。shell往往多余,可以直接使用exec形式调用。

准备好脚本文件

# fortuneloop.sh
#!/bin/bash
trap "exit" SIGINT

INTERVAL=$1
echo Configured to generate new fortune every $INTERVAL seconds

mkdir -p /var/htdocs

while :
do
  echo $(date) Writing fortune to /var/htdocs/index.html
  /usr/games/fortune > /var/htdocs/index.html
  sleep $INTERVAL
done
# Dockerfile
FROM ubuntu:latest

RUN apt-get update ; apt-get -y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh

ENTRYPOINT ["/bin/fortuneloop.sh"]
CMD ["10"]

启动镜像测试,发现可以正常应用传递的参数
在这里插入图片描述

在kubernetes中覆盖命令和参数

在kubernetes定义容器时,镜像的ENTRYPOINT和CMD可以被覆盖

kind: Pod
spec:
  containers:
  - image: arrowarcher/fortune:args
  	command: ["/bin/command"]	# 覆盖ENTRYPOINT
    args: ["args0","args1"]		# 覆盖CMD

自定义间隔运行fortune pod
fortune-pod-args.yaml

提示:

args: ["2"]			# 少参数
# or
args:				# 多参数
- foo
- bar
- "2"

pod测试结果:
每2秒切换一次index.html
(使用了kubectl port-forward fortune2s 8081:80转发到80端口)
在这里插入图片描述

为容器设置环境变量

容器化应用通常使用环境变量作为配置源。

kind: Pod
spec:
  containers:
  - image: arrowarcher/fortune:env
  	env:
  	- name: INTERVAL
  	  value: "30"

fortune-env

注意:
每个容器中还会包含同命名空间里每个service对应的环境变量

# 环境变量引用别的环境变量的值
env:
- name: B1
  value: "foo"
- name: B2
  value: "$(B1)bar"

ConfigMap解耦配置

能够在多个环境中区分配置选项。

ConfigMap介绍

在这里插入图片描述
如图使用,应用程序虽然也可以通过kubernetes API直接读取ConfigMap,但应该尽可能保持对kubernetes无感知。

在这里插入图片描述

创建 ConfigMap

直接创建
kubectl create configmap fortune-config --from-literal=sleep-interval=25
创建了fortune-config,包含sleep-interval=25的键值。

添加–from-literal=key=value可以添加多个条目

# kubectl create -f的方式创建
apiVersion: v1
data:
  sleep-interval: "25"
kind: ConfigMap
metadata:
  name: fortune-config

从文件创建
kubectl create configmap my-config --from-file=config-file.conf
此时键名为config-file.conf,值是文件内容。
kubectl create configmap my-config --from-file=customkey=config-file.conf
手动指定键名。
一样可以加多个条目(–from-file)

从文件夹
kubectl create configmap my-config --from-file=/path/to/dir
此时文件名必须是合规的。
在这里插入图片描述
可以同时使用。

给容器传递ConfigMap条目作为环境变量

创建好ConfigMap后传递给pod使用。

如果ConfigMap不存在,对应的容器将会启动失败,其余正常,之后创建ConfigMap将会自动启动。

设置环境变量

	# 单传递条目
	containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL		# 设置环境变量INTERVAL
      valueFrom: 
        configMapKeyRef:		# ConfigMap初始化
          name: fortune-config	# 引用ConfigMap名称
          key: sleep-interval	# 环境变量的值为sleep-interval的值
	# 所有条目,使用envForm
	containers:
  - image: luksa/fortune:env
    envForm:
    - prefix: CONFIG_		# 为环境变量设置前缀,可选,不设置将与ConfigMap键名一样
      configMapKeyRef:		# ConfigMap初始化
        name: fortune-config	# 引用ConfigMap名称

在这里插入图片描述

多个条目时,如果ConfigMap的某键名格式不正确,创建环境变量时会忽略对应的条目(忽略时不会发出事件通知)。

传递ConfigMap条目作为命令行参数

需要先初始化环境变量,再在参数字段中引用改变量

# 单传递条目
containers:
 - image: luksa/fortune:env
   env:
   - name: INTERVAL		# 设置环境变量INTERVAL
     valueFrom: 
       configMapKeyRef:		# ConfigMap初始化
         name: fortune-config	# 引用ConfigMap名称
         key: sleep-interval	# 环境变量的值为sleep-interval的值
   args: ["$(INTERVAL)"]

使用 configMap 卷将条目暴露为文件(适合大配置)

创建ConfigMap
nginx配置文件(开启了gzip压缩)和值文件:
configmap-files

在这里插入图片描述
如图包含了目录下所有文件的内容。键名与文件名相同。

在卷内使用ConfigMap 的条目
在这里插入图片描述
fortune-pod-configmap-volume.yaml
总的来说就是挂载一个卷,卷定义指定configMap,挂载位置是/etc/nginx/conf.d。
创建pod并端口转发:在这里插入图片描述
查看ConfigMap两个条目所在文件夹:
在这里插入图片描述
如果只暴露其中一个条目可以使用items

  volumes:
  - name: config
    configMap:
      name: fortune-config
      items:
      - key: my-nginx-config.conf
        path: gzip.conf				# 值储存位置

注意:挂载卷时如果目录下已经存在文件,都会被隐藏,可能导致容器损坏(比如/etc)
volumeMount额外的subPath字段可以用来挂载卷中的某个独立文件或文件集,无需挂载完整卷。这样不会隐藏现有文件
在这里插入图片描述

volumeMounts:
    - name: config              # 挂载configMap卷
      mountPath: /etc/some.conf   # 挂载成文件而不是目录
      subPath: myconfig.conf      # 要挂载的文件

configMap卷中的文件权限
默认为644 (-rw-r-r–)。
可以使用卷规格定义中的defaultMode属性改变默认权限
fortune-pod-configmap-volume-defaultMode.yaml

Config更新后可以不重启应用程序

使用环境变量或者命令行参数作为配置源的弊端在于无法在进程运行时更新配置。 将ConfigMap暴露为卷可以达到配置热更新的效果, 无须重新创建pod或者重启容器,进程发现文件被改变之后进行重载。

修改之前的configmap
kubectl edit configmap fortune-config
gzip on ->gzip off

查看容器内部:
在这里插入图片描述
由于nginx不会自动重启,我们手动重启:
在这里插入图片描述
2次访问变了,修改配置热更新成功!
在这里插入图片描述

k8s是通过符号链接更新configMap卷的文件的:
在这里插入图片描述
配置更新后会将…data链接至新文件夹(重新写入所有文件)

如果挂载的是容器中的单个文件而不是完整的卷, ConfigMap更新之后对应的文件不会被更新!至少书中当时是如此。
总结
更新 ConfigMap 后:
使用该 ConfigMap 挂载的 Env 不会同步更新
使用该 ConfigMap 挂载的 Volume 中的数据需要一小段时间才能同步更新。

使用Secret给容器传递敏感数据

介绍Secret

Secret和ConfigMap不仅结构类似(键值对),使用方法也相同,作环境变量(不安全),作卷。。。但是Secret只分发到pod所在节点的内存里,不写入物理储存,这样从节点上删除Secret时不用擦除磁盘了。

每个pod有个默认挂载的Secret,包含了pod内部安全访问kubernetes API服务器的全部信息。
在这里插入图片描述
使用私有镜像仓库时就需要secret

  • 创建包含 Docker 镜像仓库证书的 Secret。
kubectl create secret docker-registry mydockerhubsecret \ 
--docker-username=myusername --docker-password=mypassword \ 
--docker-email=my.email@provider.com
  • pod定义中的 imagePullSecrets 宇段引用该Secret

在这里插入图片描述

其实不用为每个pod引用secret拉取镜像,可以添加secret至serviceAccount使所有pod自动添加镜像拉取secret。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值