(资料图片)
生产中所有的应用程序中,都涉及到配置文件,而配置文件经常会有变更,比如数据库连接、代码版本号等.最典型场景就是:项目经历开发环境、测试环境、预发布环境、线上环境才能完成发布,而每个环境都有定义其独立的各种配置,这些配置手工操作很繁杂,所以好多大公司专门开发了专用配置管理中心,如百度的disconf等。
1、启动容器时,直接向应用程序传递参数,args: []2、将定义好的配置文件复制至镜像之中;3、通过环境变量向容器传递配置数据:有个前提要求,应用得支持从环境变量加载配置信息;4、制作镜像时,使用entrypoint脚本来预处理变量,常见的做法就是使用非交互式编辑工具,将环境变量的值替换到应用的配置文件中;5、基于存储卷向容器传递配置文件;注意: 对于运行容器中的配置改变,需要通过应用程序重载相关配置
kubernetes作为分布式容器调度平台,肯定会遇到同样的问题,那么遇到这种问题后,我们不可能把资源删除后,重新修改一下,然后在启动生成,这种方法就太繁琐的。kubernetes提供了对pod中容器应用的集中配置管理组件:ConfigMap、Secret、downwardAPI。通过这些组件来实现向pod中的容器中注入配置信息的机制。
Configmap是k8s集群中非常重要的一种配置管理资源对象。借助于ConfigMap API向pod中的容器中注入配置信息的机制。ConfigMap不仅仅可以保存单个属性,也可以用来保存整个配置文件或者JSON二进制文件。各种配置属性和数据以 k/v或嵌套k/v 样式 存在到Configmap中 注意: 所有的配置信息都是以明文的方式来进行传递,实现资源配置的快速获取或者更新。
在k8s集群中,有一些核心的配置属性信息是非常敏感的,所以这些信息在传递的过程中,是不希望外人能够看到的,所以,k8s提供了一种加密场景中的配置管理资源对象 -- secret。它在进行数据传输之前,会对数据进行编码,在数据获取的时候,会对数据进行解码。从而保证整个数据传输过程的安全。注意: 这些数据是根据不同的应用场景,采用不同的加密机制。
从严格意义上来说,downwardAPI不是存储卷,它自身就存在。相较于configmap、secret等资源对象需要创建后才能使用,而downwardAPI引用的是Pod自身的运行环境信息,这些信息在Pod启动的时候就存在。downwardAPI 为运行在pod中的应用容器提供了一种反向引用。让容器中的应用程序了解所处pod或Node的一些基础属性信息。
kubernetes作为分布式容器调度平台,肯定会遇到同样的问题,那么遇到这种问题后,我们不可能把资源删除后,重新修改一下,然后在启动生成,这种方法就太繁琐的。kubernetes提供了对pod中容器应用的集中配置管理组件:ConfigMap。通过ConfigMap来实现,借助于ConfigMap API向pod中的容器中注入配置信息的机制。ConfigMap不仅仅可以保存单个属性,也可以用来保存整个配置文件或者JSON二进制文件。注意: 虽然configmap可以对各种应用程序提供定制配置服务,但是我们不能用它来替代专门的配置文件,我们可以简单的把它理解为Linux系统中的/etc目录,专门用来存储配置文件的目录。
kubectl explain cm binaryData 使用二进制传递数据 data 传递数据注意: 基于data的方式传递信息的话,他会在pod的容器内部生成一个单独的数据文件 数据的表现样式: 普通数据: 属性名称: 属性值 文件数据: 文件名称: | 文件内容 注意: | 是"多行键值"的标识符
cat >configmap-test.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: test-cfgdata: cache_host: localhost file.conf: | [daemon] logs=/var/log/test.logEOF注释: data:部分内容是真正的配置项,他们有两种格式: cache_host是Key/value格式 file.conf: | 是文件格式master1 ]# kubectl apply -f configmap-test.yml configmap/test-cfg createdmaster1 ]# kubectl get cmNAME DATA AGEkube-root-ca.crt 1 10dtest-cfg 2 3smaster1 ]# kubectl describe configmap test-cfg Name: test-cfgNamespace: defaultLabels:Annotations: Data====cache_host:----localhostfile.conf:----[daemon]logs=/var/log/test.logBinaryData====Events: # 里面定义了两种类型的配置属性:文件样式和数据样式,都是以kv样式展示 属性名和属性值中间使用 "----" 来隔开
查看命令帮助kubectl create configmap -h参数详解: --from-file=[] 以配置文件的方式创建配置数据 --from-literal=[] 以命令行设置键值对的方式配置数据 --from-env-file="" 以环境变量专用文件的方式配置数据# 单个文件导入kubectl create configmap cm-test1 --from-file=./test1.conf # 多个文件导入kubectl create configmap cm-test1-test2 --from-file=./test1.conf --from-file=./test2.conf # 导入环境变量kubectl create configmap cm-env --from-env-file=./test.env # 使用key-value导入kubectl create configmap cm-key-value --from-literal=name=cyc --from-literal=age=1999
kubectl create configmap redis-config --from-literal=host=0.0.0.0 --from-literal=port=6379kubectl describe configmaps redis-config kubectl get configmaps redis-config -o yaml
mkdir nginx-conf && cd nginx-conf# 主配置文件 cat >myserver.conf<<"EOF"server { listen 8080; server_name www.sswang.com; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; }}EOF# 压缩配置片段文件cat >myserver-gzip.conf<<"EOF"gzip on;gzip_comp_level 5;gzip_proxied expired no-cache no-store private auth;gzip_types text/plain text/css application/xml text/javascript;EOF# 状态配置片段文件cat >myserver-status.conf<<"EOF"location /nginx-status { stub_status on; access_log off;}EOFkubectl create configmap nginx-conf --from-file nginx-conf/myserver.conf \--from-file=nginx-conf/myserver-status.conf --from-file=nginx-conf/myserver-gzip.confkubectl create configmap nginx-conf --from-file=nginx-conf/# 多个文件之间,属性名是文件名,属性值是文件内容,属性和属性彼此之间是通过空行来隔开
mkdir redis-conf && cd redis-confcat >redis_conf.env<<"EOF"bind=10.0.0.19port=6379daemonize=nodatabases=16EOF
kubectl create configmap redis-conf --from-env-file=redis-conf/redis_conf.envkubectl get cm redis-conf -o yamlkubectl describe cm redis-conf
1、通过环境变量的方式,直接传递pod,1.1 环境变量是容器启动时注入的,不会随CM更改而发生变化1.2 通过环境变量脚本的方式,预处理这些配置信息注意:环境变量的名称如果要用横线的话,最好使用下划线(_)2、通过在pod的命令行下运行的方式,比较鸡肋,我们不用3、使用volume的方式挂载入到pod内容器中挂载的Volume数据可以同步更新推荐滚动升级pod的方式来让ConfigMap内容变化生效
1、ConfigMap必须在Pod之前创建2、与ConfigMap在同一个namespace内的pod才能使用ConfigMap,即ConfigMap不能跨命名空间调用。
kubectl explain pod.spec.containers.env name 手工定制环境变量的时候,设置环境变量的名称,必选字段 value 手工定制环境变量的时候,设置环境变量的属性值,可选字段 valueFrom 手工定制环境变量的时候,设置环境变量的属性来源位置
kubectl explain pod.spec.containers.env.valueFrom.configMapKeyRef key 引用哪个confmap中的key name 引用哪个confmap optional 如果设置为false,标识该项是必选项,如果设置为true标识这个key是可选的。
kubectl explain pod.spec.containers.envFrom configMapRef ConfigMap对象中的特定Key secretKeyRef Secret对象中的特定Key prefix 为ConfigMap中的每个属性都添加前缀标识
cat >configmap-env-test.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: nginx-configdata: port: "10086" user: "www"---apiVersion: v1kind: Podmetadata: name: configmap-env-testspec: containers: - name: nginx1 image: 192.168.10.33:80/k8s/my_nginx:v1 env: - name: NGINX_HOST value: "192.168.10.33" - name: NGINX_PORT valueFrom: configMapKeyRef: name: nginx-config key: port optional: true - name: NGINX_USER valueFrom: configMapKeyRef: name: nginx-config key: user optional: falseEOF
# 将变量传入POD中,作为环境变量kubectl apply -f configmap-env-test.yml master1 ]# kubectl exec -it configmap-env-test -- /bin/bashroot@configmap-env-test:/# echo $NGINX_HOST $NGINX_PORT $NGINX_USER192.168.10.33 10086 www
cat >configmap-envfrom-test.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: nginx-configdata: NGINX_PORT: "10086" NGINX_USER: "www"---apiVersion: v1kind: Podmetadata: name: configmap-envfrom-testspec: containers: - name: nginx1 image: 192.168.10.33:80/k8s/my_nginx:v1 envFrom: - configMapRef: name: nginx-configEOF# configMapRef 和 子属性 name必须有两个字母的距离否则会失
[root@master1 ]# kubectl apply -f configmap-envfrom-test.yml configmap/nginx-config createdpod/configmap-envfrom-test created[root@master1 ]# kubectl get podsNAME READY STATUS RESTARTS AGEconfigmap-envfrom-test 1/1 Running 0 4s[root@master1 ]# kubectl exec -it configmap-envfrom-test -- /bin/bashroot@configmap-envfrom-test:/# echo $NGINX_PORT $NGINX_USER10086 www
cat >command-pod.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: command-argdata: time: "3600"---apiVersion: v1kind: Podmetadata: name: command-podspec: containers: - name: command-pod image: 192.168.10.33:80/k8s/busybox:latest command: [ "/bin/sh", "-c", "sleep ${SPECIAL_TIME}" ] env: - name: SPECIAL_TIME valueFrom: configMapKeyRef: name: command-arg key: time restartPolicy: NeverEOFkubectl apply -f command-pod.yml kubectl get cmkubectl describe cm command-arg kubectl get podsmaster1 ]# kubectl exec -it command-pod -- /bin/sh/ # echo $SPECIAL_TIME3600
master1 ]# kubectl run conf-pod --image=192.168.10.33:80/k8s/my_nginx:v1 --env="NAME=cyc"pod/conf-pod created[root@master1 ]# kubectl get podsNAME READY STATUS RESTARTS AGEconf-pod 1/1 Running 0 2s[root@master1 ]# kubectl exec -it conf-pod -- /bin/bashroot@conf-pod:/# echo $NAMEcyc
cat > volume-config.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: volume-configdata: special.name: redis-name redis.conf: | [daemon] daemon=true---apiVersion: v1kind: Podmetadata: name: conf-test-volumespec: volumes: - name: config-volume configMap: name: volume-config containers: - name: nginx image: 192.168.10.33:80/k8s/my_nginx:v1 volumeMounts: - name: config-volume mountPath: /redis_home/EOF
master1 ]# kubectl apply -f volume-config.yml configmap/volume-config createdpod/conf-test-volume createdmaster1 ]# kubectl get cmNAME DATA AGEredis-conf 4 14hmaster1 ]# kubectl get podsNAME READY STATUS RESTARTS AGEconf-test-volume 1/1 Running 0 7smaster1 ]# kubectl exec -it conf-test-volume -- /bin/bashroot@conf-test-volume:/# ls -l /redis_home/lrwxrwxrwx 1 root root 17 Mar 28 04:48 redis.conf -> ..data/redis.conflrwxrwxrwx 1 root root 19 Mar 28 04:48 special.name -> ..data/special.nameroot@conf-test-volume:/# cat /redis_home/special.name redis-nameroot@conf-test-volume:/# cat /redis_home/redis.conf [daemon]daemon=true这些文件虽然看起来是在我们挂载的目录下,实际上,它是经过了两层的软连接才能找到真正挂载的文件。redis_home --> .data --> .2023_03_xxx通过这种双层软连接的方式,只要我们的容器支持重载技术,那么我们只需要更改配置文件就可以实现容器应用的变动。
master1 ]# kubectl edit cm volume-config ...apiVersion: v1data: redis.conf: | [daemon] daemon=false...master1 ]# kubectl exec -it conf-test-volume -- /bin/bashroot@conf-test-volume:/# cat /redis_home/redis.conf [daemon]daemon=false# 等待十几秒后,配置信息自动发生了变动# 整个过程中,无需重启pod对象
mkdir nginx-conf && cd nginx-conf# 主配置文件 cat >myserver.conf<<"EOF"server { listen 8080; server_name www.sswang.com; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; }}EOF# 压缩配置片段文件cat >myserver-gzip.cfg<<"EOF"gzip on;gzip_comp_level 5;gzip_proxied expired no-cache no-store private auth;gzip_types text/plain text/css application/xml text/javascript;EOF# 状态配置片段文件cat >myserver-status.cfg<<"EOF"location /nginx-status { stub_status on; access_log off;}EOFkubectl create configmap nginx-conf-files --from-file=nginx-conf/kubectl describe configmaps nginx-conf-files cat > nginx-conf-configmap.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: nginx-indexdata: index.html: | "hello nginx configmap" ---apiVersion: v1kind: Podmetadata: name: nginx-conf-configmapspec: containers: - image: 192.168.10.33:80/k8s/my_nginx:v1 name: nginx-server volumeMounts: - name: nginxconf mountPath: /etc/nginx/conf.d/ readOnly: true - name: nginxindex mountPath: /usr/share/nginx/html/ readOnly: true volumes: - name: nginxconf configMap: name: nginx-conf-files optional: false - name: nginxindex configMap: name: nginx-index optional: false EOF
master1 ]# kubectl apply -f nginx-conf-configmap.yml configmap/nginx-index createdpod/nginx-conf-configmap createdmaster1 ]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-conf-configmap 1/1 Running 0 63s 10.244.3.244 node1# 查看pod里面配置文件是否正常master1 ]# kubectl exec -it nginx-conf-configmap -- ls -l /etc/nginx/conf.dtotal 0lrwxrwxrwx 1 root root 24 Mar 28 07:41 myserver-gzip.cfg -> ..data/myserver-gzip.cfglrwxrwxrwx 1 root root 26 Mar 28 07:41 myserver-status.cfg -> ..data/myserver-status.cfglrwxrwxrwx 1 root root 20 Mar 28 07:41 myserver.conf -> ..data/myserver.conf# 访问测试master1 ]# curl 10.244.3.244:8080"hello nginx configmap" master1 ]# curl 10.244.3.244:8080/nginx-statusActive connections: 1 server accepts handled requests 2 2 2 Reading: 0 Writing: 1 Waiting: 0
mkdir nginx-conf && cd nginx-conf# 主配置文件 cat >myserver.conf<<"EOF"server { listen 8080; server_name www.sswang.com; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; }}EOF# 压缩配置片段文件cat >myserver-gzip.cfg<<"EOF"gzip on;gzip_comp_level 5;gzip_proxied expired no-cache no-store private auth;gzip_types text/plain text/css application/xml text/javascript;EOF# 状态配置片段文件cat >myserver-status.cfg<<"EOF"location /nginx-status { stub_status on; access_log off;}EOFkubectl create configmap nginx-conf-files --from-file=nginx-conf/kubectl describe configmaps nginx-conf-files cat >nginx-conf-configmap-subfile.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: nginx-indexdata: index.html: "hello nginx sub configmap\n" ---apiVersion: v1kind: Podmetadata: name: nginx-conf-configmapspec: containers: - image: 192.168.10.33:80/k8s/my_nginx:v1 name: nginx-server volumeMounts: - name: nginxconf mountPath: /etc/nginx/conf.d/ readOnly: true - name: nginxindex mountPath: /usr/share/nginx/html/ readOnly: true volumes: - name: nginxconf configMap: name: nginx-conf-files items: - key: myserver.conf path: myserver.conf mode: 0644 - key: myserver-gzip.cfg path: myserver-gzip.cfg mode: 0644 optional: false - name: nginxindex configMap: name: nginx-index optional: false EOF# 此pod不支持访问/nginx-status ,因为没有配置该项
master1 ]# kubectl apply -f nginx-conf-configmap-subfile.yml configmap/nginx-index createdpod/nginx-conf-configmap createdmaster1 ]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-conf-configmap 1/1 Running 0 100s 10.244.3.245 node1master1 ]# kubectl exec -it nginx-conf-configmap -- ls -l /etc/nginx/conf.dtotal 0lrwxrwxrwx 1 root root 24 Mar 28 07:58 myserver-gzip.cfg -> ..data/myserver-gzip.cfglrwxrwxrwx 1 root root 20 Mar 28 07:58 myserver.conf -> ..data/myserver.confmaster1 ]# curl 10.244.3.245:8080hello nginx sub configmapmaster1 ]# curl 10.244.3.245:8080/nginx-status 404 Not Found 404 Not Found
nginx/1.23.3
mkdir nginx-conf && cd nginx-conf# 主配置文件 cat >myserver.conf<<"EOF"server { listen 8080; server_name www.sswang.com; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; }}EOF# 压缩配置片段文件cat >myserver-gzip.cfg<<"EOF"gzip on;gzip_comp_level 5;gzip_proxied expired no-cache no-store private auth;gzip_types text/plain text/css application/xml text/javascript;EOF# 状态配置片段文件cat >myserver-status.cfg<<"EOF"location /nginx-status { stub_status on; access_log off;}EOFkubectl create configmap nginx-conf-files --from-file=nginx-conf/kubectl describe configmaps nginx-conf-files cat >nginx-conf-configmap-subpath.yml<<"EOF"apiVersion: v1kind: ConfigMapmetadata: name: nginx-indexdata: index.html: "hello nginx use sub configmap\n" ---apiVersion: v1kind: Podmetadata: name: nginx-conf-configmapspec: containers: - image: 192.168.10.33:80/k8s/my_nginx:v1 name: nginx-server volumeMounts: - name: nginxconf mountPath: /etc/nginx/conf.d/myserver.conf subPath: myserver.conf readOnly: true - name: nginxconf mountPath: /etc/nginx/conf.d/myserver-gzip.cfg subPath: myserver-gzip.cfg readOnly: true - name: nginxindex mountPath: /usr/share/nginx/html/ readOnly: true volumes: - name: nginxconf configMap: name: nginx-conf-files optional: false - name: nginxindex configMap: name: nginx-index optional: false EOF
master1 ]# kubectl apply -f nginx-conf-configmap-subpath.yml configmap/nginx-index configuredpod/nginx-conf-configmap createdmaster1 ]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-conf-configmap 1/1 Running 0 3s 10.244.3.246 node1master1 ]# kubectl exec -it nginx-conf-configmap -- ls -l /etc/nginx/conf.dtotal 12-rw-r--r-- 1 root root 1093 Mar 28 08:06 default.conf # 不会覆盖原来的配置文件-rw-r--r-- 1 root root 149 Mar 28 08:06 myserver-gzip.cfg-rw-r--r-- 1 root root 165 Mar 28 08:06 myserver.conf
注意:在挂载时不要使用 subPath,因为使用 subPath 之后就不支持自动更新了。
master1 ~]# kubectl get cmNAME DATA AGEkube-root-ca.crt 1 11dnginx-conf-files 3 16mnginx-index 1 11mmaster1 ~]# kubectl edit cm nginx-conf-files ... listen 18080; server_name www.sswang.com;...
master1 ]# kubectl exec -it nginx-conf-configmap -- cat /etc/nginx/conf.d/myserver.confserver { listen 18080; server_name www.sswang.com; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; }}master1 ]# kubectl exec -it nginx-conf-configmap -- nginx -s reload2023/03/28 08:23:59 [notice] 122#122: signal process startedmaster1 ]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-conf-configmap 1/1 Running 0 109s 10.244.3.247 node1[root@master1 ]# curl 10.244.3.247:18080hello nginx sub configmap
标签: