kubernetes configMap 存储

1.模型

首先会在每一个节点上安装一个叫 agent 端 agent 端要做的作用就是监听当前的目标配置中心的配置选项是否发送更新动作 如果有的话 我的agent 端的话要从远程的配置中心 去下载最新的配置文件 替换我当前的 再去触发nginx实现重载 当然对于后期的运维工程师 如果想去发布新的版本的话 我只需要在配置中心对于的域名下 域名服务下 去添加最新的 stable 版本 那这样的话 我们就可以让我们的agent 指向到 我们的最新版本 再一次的去出发后端真实服务器的更新和重载 整个过程是对于我们来说完全是无痕的 不需要我们去做任何的动作 那这就是我们的configmap的模型

2.注入机制

是注入而不是共享

将文件分发给三台机器是不是有两种考虑

1.挂载形式 共享

第一种方式 我们从我们的分发的机器上 那需要的分发的这个文件 我们能不能把它挂载到 你可以在这里搭一个NFS通过共享的方式去实现 没有问题

2.注入的形式

我们通过注入的方式让数据达到一致 比如真的有一个文件发生变化了 那我们类似于执行一条指令来 比如 catt 1.txt 2.txt 文件 用一个新的数据将原来的文件内部去替换掉 那这是不是也可以保证 我们多个pod之间的文件是一样的 这就是让多个不同 服务之间的文件 达到一致性的两种思想 一个是共享一个是注入

3.利弊

当然对于这两种方案啊 各有利弊

我们configmap 的机制 是通过注入的方式

1.注入的优势

一次注入后 ,多次读取不在消耗 网络 IO

可以分批注入 对于网络 IO 的峰值更低

2.注入的劣势

3.共享的优势

4.共享的劣势

每一次在读取文件的时候,都会发生网络IO

对于共享的io同时去向我们的共享服务器读取这个配置文件 那就可能产生峰值的网络IO 的出现

5.总结

共享适合那种有好多不同的小文件 我一起共享给你 你用哪一个 我读取哪一个

那注入的话更适用于那种一两个配置文件 而且大概率回去使用它 那这时候就用注入

3.创建

这里没有提到 --from-env-file, 建议同学们延展了解下 --from-file 和 --from-env-file 的区别

1.--from-file 文件名为 key 文件内容为 value

bash 复制代码
kubectl create configmap 对象名 --from-file=文件路径

1.文件内部必须是一行一对的 k=v,可以在使用的适合注入至pod的内部变成环境变量

1.txt

name=zhangsan

passwd=123

2.文件内部不是一行一对 的k=v 不能被当作环境变量使用

2.txt

今天天气真不错,适合爬山

2.--from-literal 我们直接把对应需要去创建出来的key value 对象直接编写在了我们的选项中或者创建命令里 所以这种方式更适合那种key value比较简短的 比如就写一个用户名

bash 复制代码
kubectl create configmap literal-config --from-literal=name=dave --from-literal=password=pass

3.使用第一种方式创建

1.创建一个jmj.txt文件 文件名随便取

文件内容

bash 复制代码
name=zhangsan
password=123456

执行

bash 复制代码
kubectl create configmap jmj-config --from-file=jmj.file

创建成功

查看一下

bash 复制代码
kubectl get configmap

简写

bash 复制代码
kubectl get cm

获取对象里面的信息

bash 复制代码
kubectl get cm jmj-config -o yaml

建议用文件的方式创建

如果你想把 jmj-config 打出 yaml 可以执行

bash 复制代码
kubectl create configmap jmj-config --from-file=jmj.file --dry-run -o yaml > 2.cm.yaml
1..另一种查看方式
bash 复制代码
kubectl describe cm jmj-config

4.使用第二种方式创建

bash 复制代码
kubectl create configmap literal-config --from-literal=name=dave --from-literal=password=pass

这样创建两个文件 里面分别是 dave 和 pass 然后执行下面的命令 和上面那条命令是一个效果

bash 复制代码
kubectl create configmap aa-config --from-file=name --from-file=password

5.yaml

可以通过yaml创建

6.小实验 将当前的configmap 注入到pod内部环境变量

创建 1.pod.yaml

bash 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: literal-config
  namespace: default
data:
  name: dave
  password: pass
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO
---
apiVersion: v1
kind: Pod
metadata:
  name: cm-env-pod
spec:
  containers:
    - name: myapp-container
      image: wangyanglinux/myapp:v1.0
      command: [ "/bin/sh", "-c", "env" ]
      env:
       - name: USERNAME
         valueFrom:
           configMapKeyRef:
             name: literal-config
             key: name
       - name: PASSWORD
         valueFrom:
           configMapKeyRef:
             name: literal-config
             key: password
      envFrom:
        - configMapRef:
            name: env-config
  restartPolicy: Never

env加入环境变量 来源于 某个 configmap name 为 cm 名称 key 为 key

envFrom 直接把这个configmap的所有key value 注入到环境变量 但是不能修改了

bash 复制代码
kubectl create -f 1.pod.yaml

看一下pod的日志

bash 复制代码
 kubectl logs cm-env-pod

7.小实验 将当前的configmap 注入到 mainC的启动命令

configmap可以当做启动参数

创建 2.pod.yaml

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
 name: cm-command-pod
spec:
 containers:
   - name: myapp-container
     image: wangyanglinux/myapp:v1.0
     command: [ "/bin/sh", "-c", "echo $(USERNAME) $(PASSWORD)" ]
     env:
      - name: USERNAME
        valueFrom:
          configMapKeyRef:
            name: literal-config
            key: name
      - name: PASSWORD
        valueFrom:
          configMapKeyRef:
            name: literal-config
            key: password
 restartPolicy: Never
bash 复制代码
kubectl create -f 2.pod.yaml

8.小实验 将当前 Configmap 变成我们的文件去使用

创建 3.pod.yaml

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
 name: cm-volume-pod
spec:
 containers:
   - name: myapp-container
     image: wangyanglinux/myapp:v1.0
     volumeMounts:
       - name: config-volume
         mountPath: /etc/config
 volumes:
  - name: config-volume
    configMap:
      name: literal-config
 restartPolicy: Never

创建一个卷 卷名 叫 config-volume 挂载到当前容器的 /etc/config

bash 复制代码
kubectl create -f 3.pod.yaml

进入容器内部查看

bash 复制代码
kubectl exec -it cm-volume-pod -- /bin/bash

为什么它是蓝色的呢

他不是文件 而是链接

牵扯到 热更新

1.什么是热更新呢

我挂载以后后续我的原文件发送变化 ,我都会把帮你把所有的 现在老版本的给替换掉 这就是为什么要做链接的原因

当我第一次注入的时候 这是原文件 我做一个链接 链接到你的文件上了 如果我要去进行热更新了 换了一个内容 那我注入到第二个文件里 再把第一个链接关系清除 再把第二个文件链接到这个文件名上 你依然用的是这个文件名 但是很显然它的背后发生了变化 而不会在你使用的时候影响你 这就是为什么要做链接的原因

2.创建 nginx 默认 default.conf文件

bash 复制代码
server {
   listen 80 default_server;
   server_name example.com www.example.com;
   location / {
       root   /usr/share/nginx/html;
       index index.html index.htm;
    }
}

3.将default.conf 配置文件转化为 configmap对象

bash 复制代码
kubectl create cm default-nginx --from-file=default.conf

4.将 configmap对象 输出为 yaml形式

bash 复制代码
kubectl get cm default-nginx -o yaml

5.创建一个deployment 控制器

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
 labels:
  app: hotupdate-deploy
 name: hotupdate-deploy
spec:
 replicas: 5
 selector:
  matchLabels:
   app: hotupdate-deploy
 template:
  metadata:
   labels:
    app: hotupdate-deploy
  spec:
   containers:
     - image: nginx
       name: nginx
       volumeMounts:
         - name: config-volume
           mountPath: /etc/nginx/conf.d/
   volumes:
     - name: config-volume
       configMap:
         name: default-nginx
bash 复制代码
kubectl apply -f deployment.yaml

6.进入一个pod里

bash 复制代码
kubectl exec -it pod名 -- /bin/bash

循环查看 default.conf

bash 复制代码
while true; do cat default.conf;sleep 2s;   done

7.开启另一个终端修改configmap对象里的 default.conf

bash 复制代码
kubectl edit cm default-nginx

改成8080

esc wq 保存退出

bash 复制代码
kubectl get  cm default-nginx -o yaml

8.回到之前那个终端

发现配置文件已经改变了

kubernetes会根据服务器的压力自己去调控注入的阶段 什么时候注入第一个 我们会有序的执行 基本会在一两分钟内完成大部分的替换 是没有任何问题的 那从这里我们可以看到这就是热更新的一种标学

所以在后面我们部署服务的时候 我们都建议 大家把 可能会后期修改的配置文件 抽象在 configmap对象里 然后在挂载回我们pod内部 这样做的好处就是 一旦后续我们需要修改的时候 我不需要重新封装镜像 我不需要去重新写控制器 我只需要通过edit 等方式 修改configmap 对象本身就可以修改所有的配置文件

9.还有一个问题 文件内部发生变化了 但是nginx 没有读取变化的配置

默认能够访问到80端口

nginx不支持热更新 配置文件

比如有 traefik web 服务器 支持监听配置文件 热更新 根本不需要重启 ,你改配置文件改完以后就生效了 就这么简单 所以说不是这个机制不好用 而是我们现在内部封装的这个nginx 有点太老了不支持我们所谓的热更新 或者监控文件变化自动趋向到新版

官方为了解决这个问题推出了 改变pod annotations的方式 让他强制滚动更新

patch命令

bash 复制代码
kubectl patch deployment hotupdate-deploy --patch '{"spec":{"template":{"metadata":{"annotations":{"version/config":"666666666"}}}}}'

因为完全可以放入脚本里去执行 ,不想我们的edit我们是一种交互的方式

edit命令修改

bash 复制代码
kubectl edit deployment hotupdate-deploy

修改

esc wq保存退出

滚动更新中

在annotations下,随便打出任意字符的键值对都可以触发滚动更新,比如helloworld:"12345"一样可以触发,原来应该是,只要打的补丁能使资源清单发生变化,都能触发更新

这里再插入一个小知识点

因为镜像加载 默认 是 always 就是如果你的镜像 是 latest 默认就回去远程拉取镜像 然后在启动

你可以把当前镜像下载策略改成如果有就不下载

提醒

使用该configmap挂载的env环境变量的方式 ,那么修改configmap原对象 是环境变量并不会发生改变

使用该configmap 挂载的Volume 中 的数据需要一段时间 (实测大概10秒) 才能同步更新

然后就改不了了 而且是不可逆的

要想再改回去只能把configmap 这个对象删除

相关推荐
RedCong1 小时前
如何在k8s中对接s3存储
云原生·容器·kubernetes
SDL大华1 小时前
【备忘】在Docker中安装宝塔面板,实现环境隔离,又能快速迁移服务器环境
服务器·docker·容器
TC13983 小时前
docker 终端打不开rviz2界面,报错qt.qpa.xcb: could not connect to display
docker·容器
扣脚大汉在网络4 小时前
云原生安全渗透篇
安全·云原生·dubbo
csdn_aspnet5 小时前
使用 .NET 9 和 Azure 构建云原生应用程序:有什么新功能?
microsoft·云原生·azure
字节源流7 小时前
【spring cloud Netflix】Eureka注册中心
云原生·eureka
Brilliant Nemo7 小时前
Docker 镜像相关的基本操作
运维·docker·容器
阿里云云原生1 天前
LLM 不断提升智能下限,MCP 不断提升创意上限
云原生