暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kubernetes K8S中ConfigMap管理容器化应用的配置

IT运维大爆炸 2023-09-06
59

1、简介

ConfigMap是Kubernetes中的一种资源类型,用于存储非机密性的配置数据,例如环境变量、配置文件、命令行参数等。它允许将这些配置数据从容器镜像中分离出来,以便在容器启动时注入到容器中。ConfigMap通常用于存储应用程序的配置信息,以实现应用程序的可配置性。

2、特点和用途

  • 解耦配置和应用程序代码:通过使用 ConfigMap,您可以将配置数据从容器镜像中分离出来,使应用程序的配置更易于管理。这有助于将配置信息与代码分离,使得配置更具可维护性。

  • 集中管理配置:ConfigMap 允许您将配置信息集中存储在 Kubernetes 集群中的 ConfigMap 资源中。这使得可以轻松地更改配置,而不必重新构建或重新部署容器镜像。

  • 多容器共享配置:ConfigMap 中的配置数据可以被多个容器共享,这对于具有多个容器的 Pod 非常有用。例如,一个 Pod 中的多个容器可以共享相同的配置信息。

  • 配置热更新:当配置信息更改时,ConfigMap 可以让您热更新配置,而不需要重新启动容器。这有助于减少服务中断时间。

  • 不敏感信息存储:ConfigMap 通常用于存储不敏感的配置信息,如环境变量、配置文件、命令行参数等。对于敏感信息(如密码和密钥),应使用 Kubernetes 的 Secrets 资源来存储。

  • 命令行工具支持:Kubernetes 提供了命令行工具(kubectl)以及 API 来创建、管理和查看 ConfigMap 资源。

3、存储类型

  • 应用程序的环境变量:您可以将应用程序所需的环境变量存储在 ConfigMap 中,然后将它们注入到容器中,以配置应用程序的行为。

  • 配置文件:配置文件的内容可以存储在 ConfigMap 中,并通过卷挂载到容器中。这使得您可以更改配置文件内容而无需重新构建容器镜像。

  • 数据库连接字符串:敏感的数据库连接字符串可以存储在 ConfigMap 中,并注入到应用程序中,以实现与数据库的连接。

  • 应用程序的参数和标志:除了环境变量之外,您还可以将应用程序所需的参数和标志存储在 ConfigMap 中,以在容器启动时传递给应用程序。

  • 任何其他的键值对配置:ConfigMap 可以存储任何键值对配置数据,这些数据对应用程序的运行或配置可能有影响。这使得您可以将各种类型的配置信息集中管理。

<!--注意:ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1 MiB。如果你需要保存超出此尺寸限制的数据,你可能希望考虑挂载存储卷 或者使用独立的数据库或者文件服务。-->

4、ConfigMap 和 Secret的区别

  • ConfigMap:用于存储非敏感的配置信息,例如环境变量、配置文件、命令行参数等。数据以明文形式存储,适合存储不敏感的配置。

  • Secret:专门用于存储敏感的配置信息,如密码、API 密钥、TLS 证书等。数据以 Base64 编码形式存储,并且在 etcd 中加密,用于安全地存储和传递敏感数据。

5、适用场景

  • 使用 ConfigMap 中的某一 key 作为文件名,对应 value 作为文件内容。例如:替换 nginx 容器中的 etc/nginx/conf.d/default.conf 配置文件。

  • ConfigMap也是名称空间隔离的。不同的namespace不能调用ConfigMap、secret。

6、使用命令行的方式创建

#创建配置
[root@node1 ~]# vim redis.conf
redis.host=127.0.0.1
redis.port=6379
redis.password=123456

#创建configmap
[root@node1 ~]# kubectl create configmap redis-config --from-file=redis.conf

#以明文的方式获取
[root@node1 ~]# kubectl get configmap -o yaml
- apiVersion: v1
data:
  redis.conf: |
    redis.host=127.0.0.1
    redis.port=6379
    redis.password=123456
     
#使用k=v模式创建configmap
[root@node1 ~]# kubectl create cm myconfig-3 --from-literal=hello=123 --from-literal=world=456 -o yaml
apiVersion: v1
data:
hello: "123"
world: "456"
kind: ConfigMap
metadata:
name: myconfig-3
namespace: default

7、使用yaml的方式创建

#创建配置文件
[root@node1 ~]# vim configmap.yaml
apiVersion: v1
kind: ConfigMap
data:
 # k: v
redis.conf: |
  redis.host=127.0.0.1
  redis.port=6379
  redis.password=123456
metadata:
name: myconfig
namespace: default

#启动
[root@node1 ~]# kubectl apply -f configmap.yaml

#查看 configmap简写为cm
[root@node1 ~]# kubectl get configmap myconfig -o yaml
apiVersion: v1
data:
redis.conf: |
  redis.host=127.0.0.1
  redis.port=6379
  redis.password=123456

8、通过挂载的方式

这种方式key是文件名,value是整个文件内容。我们无法单独获取到整个内容中的指定配置

#创建配置文件
[root@node1 ~]# vim redis.conf
redis.host=127.0.0.1
redis.port=6379
redis.password=123456

#创建configmap
[root@node1 ~]# kubectl create configmap redis-config --from-file=redis.conf

#配置yaml文件
[root@node1 ~]# vim mypod-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod-cm
spec:
containers:
   - name: busybox
    image: busybox
    command: [ "/bin/sh","-c","while true; do sleep 20;cat etc/config/redis.conf;done;" ]
    volumeMounts:
     - name: config-volume
      mountPath: etc/config
volumes:
   - name: config-volume
    configMap:
      name: redis-config
restartPolicy: Never

#启动
[root@node1 ~]# kubectl apply -f mypod-cm.yaml

#查看日志
[root@node1 ~]# kubectl logs mypod-cm
redis.host=127.0.0.1
redis.port=6379
redis.password=123456

#修改配置
[root@node1 ~]# kubectl edit cm redis-config  

#测试同步更新:等一分钟左右看Pod日志,容器里面挂载目录内容确实更新的了,更新是基于内容的事件订阅做的。
[root@node1 ~]# kubectl --kubeconfig=sit logs mypod-cm
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
redis.host=127.0.0.1
redis.port=6379
redis.password=12345678
redis.host=127.0.0.1
redis.port=6379
redis.password=12345678

<!--注意:虽然有热更新。一般使用方式。configmap改掉。直接把Pod删了。Pod是通过Deploy部署的。旧Pod删除以后,deploy拉起一个新的,重新引用新的configmap。这里主要怕redis-server etc/config/redis.conf服务启动之前读取配置是一次性的,后期配置变更之后,可能还是读取的原来配置。-->

9、通过参数方式

这种方式configmap是kv 字符串。我们可以在任何位置获取到k,v进行使用

#创建配置文件 
[root@node1 ~]# vim myconfig.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfig
namespace: default
data:
my.level: info
my.msg: hello

#创建configmap
[root@node1 ~]# kubectl apply -f myconfig.yaml

#配置yaml文件
[root@node1 ~]# vim ceshicmpod.yaml
apiVersion: v1
kind: Pod
metadata:
name: ceshicmpod
spec:
containers:
   - name: busybox
    image: busybox
    command: [ "/bin/sh", "-c", "while true; do sleep 20;echo $(LEVEL) $(TYPE);done" ]
    env:
       - name: LEVEL
        valueFrom:
          configMapKeyRef:
            name: myconfig
            key: my.level
       - name: TYPE
        valueFrom:
          configMapKeyRef:
            name: myconfig
            key: my.msg
restartPolicy: Never

#启动
[root@node1 ~]# kubectl apply -f ceshicmpod.yaml

#查看日志
[root@node1 ~]# kubectl logs ceshicmpod
info hello

#修改配置
[root@node1 ~]# kubectl edit cm myconfig
configmap/myconfig edited

#env环境变量的方式引用的cm。热更新没有生效。
[root@node1 ~]# kubectl logs ceshicmpod
info hello
info hello
info hello
info hello
info hello
info hello
info hello
info hello
info hello
info hello

<!--注意:env环境变量的方式引用的cm。热更新暂时没用。最终希望Deploy-部署的Pod删除了,重新拉起就行。-->

欢迎大家扫码关注:

本公众号只写原创,不接广告、不接广告、不接广告。下期小伙伴想学习什么技术,可以私信发我吆。

文章转载自IT运维大爆炸,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论