8.1 kubernetes – configMap(用于保存配置文件的存储方案)
configMap 功能在 kubernetes 1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中去读取配置信息。configMap API 给我们提供了向容器中注入配置信息的机制,configMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 json 二进制对象。
其实在我们生产环境中有一种机制,这种机制比较像我们的 configMap,它叫配置文件的注释中心。如下图所示:
在这种情况下它是怎么样一种构建方式呢,首先所有的服务想去正常访问的话,nginx 会向配置文件的注册中心里去索要它的配置信息,这时候配置文件注册中心回去匹配它的对应信息,比如主机名或者是 ip 地址的范围进行分配他的配置文件;那当然不同的一些集群或索要到一些不同的配置文件,包括以后我们要去修改这些的配置文件我们只需要到配置文件注册中心中进行更新,那这样就会触发每一个进程自己的修改以及运行,这样的话我们更改起来包括我们的保存和维护起来更简单更方便。这就是我们配置文件注册中心的一个概念,在 K8S 里它的 configMap
也是这样去想的。
8.1.1 configMap 原理
首先我们可以创建一个 configMap ,比如这保存的是一个 nignx.conf 配置文件(这个也就是所谓的保存的资源)。这个资源呢在后期我们创建 pod 的时候告诉它,在创建 pod 的时候要去引用这么一个 configMap 的配置信息,那这样的话我们的 nginx.conf 配置文件就会注入到该 pod 中,并且不管多少个 pod 过来以后它都能去申请同一个 nginx.conf 的这么一个资源请求。并且后期我对 nginx.conf 文件进行修改以后这里的 pod 里面的内容也会发生变化。当然我们的服务暂时还不支持直接创建文件,我们需要进行 pod 的重启或重载,让他实现热更新才可以。这和我们的 configMap 没有关系主要是和 nginx 的这么一个问题。
-
configmap 原理总结:
-
将配置信息和镜像解耦
-
将配置信息放到 configmap 对象中,然后在 pod 的对象中导入 configmap 对象,实现导入配置的操作
-
声明一个 ConfigMap 的对象,作为 Volume 挂载到 pod 中
-
8.1.2 configMap 的创建
首先对于我们的 configMap 创建有好几种方式:
-
使用目录创建
-
使用文件创建
-
使用字面值创建
8.1.2.1 使用目录创建 configMap
第一种使用目录创建,我们先来看一下它的创建方式:
在某个目录下有两个文件,我们在创建的时候
--from-file
指定在目录下的所有文件都会被创建在 configMap 里面创建一个键值对、键的名字就是文件名,值就是文件里的内容。也就是他存储的结构依旧是一个 Key:value 键值
1、先创建一个 configmap 文件。用于存放我们的 configmap 的创建文件
[15:38:47 root@master-1 ~]#mkdir configmap
[15:38:55 root@master-1 ~]#cd configmap/
#在创建一个 dir 文件使用的是目录来创建我们的 configmap
[15:38:59 root@master-1 configmap]#mkdir dir
[15:39:03 root@master-1 configmap]#cd dir/
2、编写第一个测试文件。这个只是为了演示 configMap 存储的使用方案而已
[15:39:07 root@master-1 dir]#vim game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allwoed=true
secret.code.lives=30
3、编写第二个测试文件,这个只是为了演示 configMap 存储的使用方案而已
[15:45:19 root@master-1 dir]#vim ui.properties
color.good=purple
color.good=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
4、然后我们就可以直接通过kubectl create
创建了
[15:48:09 root@master-1 dir]#kubectl create configmap game-config --from-file=../dir/
kubectl create configmap: #创建 configmap 存储类型
game-config: #创建出来的文件名字叫做 game-config
--from-file=../dir/: #文件路径是我的 /root/configmap/dir
5、通过kubectl get configmaps
查看我们的 configmap 存储类型信息,就会发现有两个数据
[15:51:00 root@master-1 dir]#kubectl get configmaps
NAME DATA AGE
game-config 2 102s
#直接使用 kubectl get cm 也可以
[15:51:17 root@master-1 dir]#kubectl get cm
NAME DATA AGE
game-config 2 2m55s
6、通过kubectl get cm game-config -o yaml
[15:53:32 root@master-1 dir]#kubectl get cm game-config -o yaml
kubectl get cm: #获取 configmap 的资源信息
game-config -o yaml: #指定查看 game-config 资源的信息
7、当然也可以通过 kubectl describe
查看该 configmap 存储类型的信息,也是采用的键值对存储方式
[15:53:42 root@master-1 dir]#kubectl describe cm game-config
kubectl describe: #查看详细信息描述
cm game-config: #类型是 configmap 中的 game-config 资源
这就是通过我们的目录保存的一种方案,接着我们看第二种使用文件创建。
8.1.2.2 使用文件创建 configMap
从单一文件去创建,只要指定为一个文件就可以从单个文件中创建 configmap。其实我们通过命令会发现它的创建方式和我们的目录创建没有区别。其实这里唯一的区别就是一个指定的是目录一个指定的是文件的本体。
--from-file
这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的
1、通过kubectl create configmap
创建
[15:58:10 root@master-1 dir]#kubectl create configmap game-config2 --from-file=game.properties
kubectl create configmap: #创建 configmap 存储类型
game-config2: # configmap 类型名为 game-config2
--from-file=game.properties: # 使用的文件路径是当前路径下的 game.properties 文件
2、通过kubectl get cm
查看当前的 configmap 类型,就会发现多了一个 mage-config 2 ,并且数据只有一个
[16:19:51 root@master-1 dir]#kubectl get cm
NAME DATA AGE
game-config 2 31m
game-config2 1 94s
3、通过kubectl describe
命令查看 configmap 类型信息,并且指定查看 game-config2 这个资源
[16:21:25 root@master-1 dir]#kubectl describe configmaps game-config2
kubectl describe configmaps: #查看 configmap 类型信息
game-config2: #指定查看 game-config2 资源
8.1.2.3 使用字面值创建 configmap
使用文字值创建,利用--from-literal(来自文字)
参数传递配置信息,该参数可以多次使用,格式如下
1、通过指定键名键值来创建
[16:22:42 root@master-1 dir]#kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
kubectl create configmap: #创建 configmap 存储类型
special-config: #指定了 configmap 的名称为 special-config
--from-literal=special.how=very: #指定了键名是 special.how 键值是 very
--from-literal=special.type=charm: #又指定了键名为 special.type 键值是 charm
2、通过kubectl describe
查看 cm(cm 也就是 configmap 的缩写)信息描述
[16:28:12 root@master-1 dir]#kubectl describe cm special-config
kubectl describe cm: #查看 configmap 描述信息
special-config: #指定查看 special-config
既然有三种创建方案,那么创建完成以后呢就带着大家去把这些配置在 pod 中使用看一下效果。
8.1.3 pod 中使用 configMap
8.1.3.1 使用 configMap 来代替我们的环境变量
8.1.3.1.1 创建 special 的 configMap
这里举了一个例子,例子就是先创建了一个 configmap
configMap yaml 文件详解:
apiVersion v1 # api 版本是 V1 版
kind ConfigMap # kind 类型为 configmap
metadata# configmap 元数据信息
name special-config # 该 configmap 名为 special-config
namespace default # 使用的是默认名称空间 default
data# 数据信息
special.how very # 数据信息键值对为 special.how=very
special.type charm # 数据信息键值对为 special.type=charm
1、 编写我们的第一个special-config
configmap
16:48:30 root@master-1 dir #vim sc.yaml
apiVersion v1
kind ConfigMap
metadata
name special-config
namespace default
data
special.how very
special.type charm
2、通过kubectl apply
声明式创建
[16:49:12 root@master-1 dir]#kubectl create -f sc.yaml
3、通过kubectl get cm
查看当前的 configMap 资源信息就发现多了一个 special-config 的资源
8.1.3.1.2 创建 env 的 configMap
创建为了 special configmap 之后我们就开始创建 env 的 configmap
1、回到 configmap 文件中创建一个 env 的目录
[16:49:49 root@master-1 dir]#cd /root/configmap/
[16:52:35 root@master-1 configmap]#mkdir env
[16:52:44 root@master-1 configmap]#cd env/
2、编写一个 env 的 yaml 文件。我是以资源清单的方案来创建 configmap
16:52:46 root@master-1 env #vim env.yaml
apiVersion v1 # api 主板是 v1
kind ConfigMap # kind 类型为 configmap
metadata# 该 configmap 的元数据信息
name env-config # 该 configmap 名为 env-config
namespace default # 使用的是默认名称空间,
data# 该 configmap 使用数据
log_level INFO # log_level 为它的键名,键值为 INFO
3、通过 kubectl apply
声明式创建该 configmap
[16:56:46 root@master-1 env]#kubectl create -f env.yaml
4、通过kubectl get cm
查看当前 configmap 的资源信息,发现 env-config 已经创建
[16:57:16 root@master-1 env]#kubectl get cm
现在就会发现已经有了我们的 env-config 和 special-config ,我们就会那这两个 config 资源注入到我们的一个 pod 的这么一个环境变量中。
8.1.3.1.3 创建 pod 将 env-config 和 special-config 注入到环境变量中
pod yaml 文件详解:
apiVersion v1 # api 使用的是 v1 版
kind Pod # kind 类型为 pod
metadata# 该 pod 的元数据信息
name dapi-test-pod # 该 pod 名为 dapi-test-pod
spec# 该 pod 描述信息
containers# 该 pod 使用的容器信息
name test-container # 容器名称为 test-container
image nginx # 使用的镜像是 nginx
command "/bin/sh""-c""env" # 在容器中运行了一条命令也就是打印出来了环境变量
env# env 环境变量信息
name SPECIAL_LEVEL_KEY # 给这个 env 起了一个名称叫做 SPECIAL_LEVEL_KEY
valueFrom# 值得来源
configMapKeyRef# 从哪一个 configmap 中导入
name special-config # 从 special-config 中导入
key special.how # 导入得是 special.how 这个键,因为我们在 special-config 中有两个键值对,我们把这个 special.how 得值赋予给 SPECIAL_LEVEL_KEY 也就是意味着现在SPECIAL_LEVEL_KEY 值也就是我们的 special.how 对应得值 very
name SPECIAL_TYPE_KEY # 这个 SPECIAL_TYPE_KEY 导入的是 special.type 的值也就是 charm
valueFrom# 值得来源
configMapKeyRef# 从哪一个 configmap 中导入
name special-config # 从 special-config 中导入
key special.type # 导入得是 special.type 这个键
envFrom# env 来源信息
configMapRef# env 是从 configmap 这个存储类型中来的
name env-config
# 并且使用的是这个 configmap 存储中的 env-config,这样的话这个 env-config 就被导入了
restartPolicy Never # 重启策略为 never 永不重启
我将这个 yaml 文件导入之后我们会有三个不同的环境变量,第一个是我们得 env-config 它得键名就是我们的 log_level 键值就是 INFO 。第二个环境变量就是 SPECIAL_LEVEL_KEY 值是对应的 special-config中的special.how 键名的值也就是 very。第三个环境变量就是 SPECIAL_TYPE_KEY 值对应的是 special-config中的special.type 键名的值也就是 charm。
1、编写yaml
文件
17:25:08 root@master-1 env #vim cm-env-pod.yaml
apiVersion v1
kind Pod
metadata
name dapi-test-pod
spec
containers
name test-container
image nginx
command "/bin/sh""-c""env"
env
name SPECIAL_LEVEL_KEY
valueFrom
configMapKeyRef
name special-config
key special.how
name SPECIAL_TYPE_KEY
valueFrom
configMapKeyRef
name special-config
key special.type
envFrom
configMapRef
name env-config
restartPolicy Never
2、通过kubectl create
声明式创建 pod
[17:37:05 root@master-1 env]#kubectl create -f cm-env-pod.yaml
3、通过kubectl get pod
状态信息
[17:37:16 root@master-1 env]#kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 55s
意味该 pod 一启动以后打印了环境变量就没了。
4、通过Kubectl logs
查看 dapi-test-pod 这个 pod 的日志信息
[17:38:01 root@master-1 env]#kubectl logs dapi-test-pod
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://172.30.0.1:443
HOSTNAME=dapi-test-pod
HOME=/root
PKG_RELEASE=1~buster
SPECIAL_TYPE_KEY=charm
KUBERNETES_PORT_443_TCP_ADDR=172.30.0.1
NGINX_VERSION=1.19.2
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
NJS_VERSION=0.4.3
KUBERNETES_PORT_443_TCP_PROTO=tcp
SPECIAL_LEVEL_KEY=very
log_level=INFO
KUBERNETES_PORT_443_TCP=tcp://172.30.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=172.30.0.1
PWD=/
这就是通过 configMap 把我们的一个环境变量注入到我们的 pod 内部
8.1.3.2 在 pod 中使用 configMap 设置命令行参数
8.1.3.2.1 创建 special 的 configmap
使用 configmap 设置命令行得参数,这里得 yaml 文件详解
yaml 文件详解:
apiVersion v1 # api使用的是 v1 版本
kind ConfigMap # kind 类型为 configmap
metadata# 这个 configmap 得元数据信息
name special-config # 这个 configmap 叫做 special-config
namespace default # 使用的名称空间是默认名称空间
data# 数据信息
special.how very # 数据信息键值对为 special.how=very
special.type charm # 数据信息键值对为 special.type=charm
但是这个 configmap 已经在上面一个实验中创建了,所以不用再才创建
8.1.3.2.2 创建 pod 进行演示
yaml 文件详解:
apiVersion v1 # api 使用版本 v1
kind Pod # kind 类型为 pod
metadata# 该 pod 的元数据信息
name dapi-test-pod66 # 该 pod 名为 dapi-test-pod66
spec# 该 pod 详细描述
containers# 容器信息
name test-container # 容器名称为 test-container
image nginx # 使用的是 nginx 镜像
command "/bin/sh""-c""echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)"
# 在 sh 中使用 echo 命令,将我们的环境变量作为输出的命令,其实会发现这里我们导入的配置变量方式和上一个实验一摸一样的
env# env 变量信息
name SPECIAL_LEVEL_KEY # 变量名为 SPECIAL_LEVEL_KEY
valueFrom# 变量值来源信息
configMapKeyRef# 从哪一个 configmap 中来的变量
name special-config # 使用的是 special-config 这个 configmap 存储中的变量
key special.how # 并且键名为 special.how
name SPECIAL_TYPE_KEY # 变量名为 SPECIAL_TYPE_KEY
valueFrom# 变量值来源信息
configMapKeyRef# 从哪一个 configmap 中来的变量
name special-config # 使用的是 special-config 这个 configmap 存储中的变量
key special.type # 并且键名为 special.type
restartPolicy Never # 重启策略为永不重启
如果想让每一个 pod 启用命令可以被调整我们可以通过环境变量的方式进行注入,导入变量再上一个实验演示中已经看过了,就是通过 env 这个关键字进行导入。
1、编写 yaml
文件。
08:51:18 root@master-1 env #vim cm-cmd-pod.yaml
apiVersion v1
kind Pod
metadata
name dapi-test-pod66
spec
containers
name test-container
image nginx
command "/bin/sh""-c""echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)"
env
name SPECIAL_LEVEL_KEY
valueFrom
configMapKeyRef
name special-config
key special.how
name SPECIAL_TYPE_KEY
valueFrom
configMapKeyRef
name special-config
key special.type
restartPolicy Never
2、通过kubectl apply
声明式创建 pod
[09:06:21 root@master-1 env]#kubectl apply -f cm-cmd-pod.yaml
3、通过kubectl get pod
查看 pod 信息 并且状态为完成
[09:06:46 root@master-1 env]#kubectl get pod
4、接着通过kubectl logs
查看该 pod 的日志,已经将这两个变量值输出出来,因为我们在该 pod 的 yaml 文件中让他 echo 出了这两个变量的命令
[09:06:57 root@master-1 env]#kubectl logs dapi-test-pod66
8.1.3.3 通过数据卷插件使用 ConfigMap
通过我们数据卷插件的方式来使用 configMap
8.1.3.3.1 创建 special 的 configmap
使用 configmap 设置命令行得参数,这里得 yaml 文件详解
yaml 文件详解:
apiVersion v1 # api使用的是 v1 版本
kind ConfigMap # kind 类型为 configmap
metadata# 这个 configmap 得元数据信息
name special-config # 这个 configmap 叫做 special-config
namespace default # 使用的名称空间是默认名称空间
data# 数据信息
special.how very # 数据信息键值对为 special.how=very
special.type charm # 数据信息键值对为 special.type=charm
但是这个 configmap 已经在上面一个实验中创建了,所以不用再才创建
在数据卷里面使用这个 configMap,有不同的选项。最基本的都是将文件填入数据卷中,在这个文件中,键就是文件名,键值就是文件内容
8.1.3.3.2 创建 pod 进行演示
yaml 文件详解:
apiVersion v1 # api 接口为 v1
kind Pod # kind 类型为 pod
metadata# pod 元数据信息
name dapi-test-pod11 # pod 名称为 dapi-test-pod11
spec# 该 pod 详细信息描述
containers# 该 pod 使用的容器
name test-container # 容器名为 test-container
image nginx # 使用的镜像是 nginx
command "/bin/sh""-c""cat /etc/config/special.how"
# 在该容器中运行得命令是 cat /etc/config/special.how 这个文件
volumeMounts# 然后再这个容器下进行 volume 的挂载
name config-volume # 挂载的是下面 config-volume 这个 volume 必须和下面匹配
mountPath /etc/config # 挂载到 /etc/config 这个目录下
volumes# 数据卷信息
name config-volume # 这个数据卷得名称为 config-volume 并且必须和上面匹配
configMap# configMap 来源信息
name special-config # 这 configmap 是由 special-config 这个 configMap 中得到
restartPolicy Never # 重启策略为永不重启
1、编写yaml
文件
09:09:58 root@master-1 env #vim cm-vloumes-pod.yaml
apiVersion v1
kind Pod
metadata
name dapi-test-pod11
spec
containers
name test-container
image nginx
command "/bin/sh""-c""cat /etc/config/special.how"
volumeMounts
name config-volume
mountPath /etc/config
volumes
name config-volume
configMap
name special-config
restartPolicy Never
2、通过kubectl apply
声明式创建 pod
[10:48:16 root@master-1 env]#kubectl apply -f cm-vloumes-pod.yaml
3、通过kubectl get pod
进行查看状态已经执行成功
[10:48:58 root@master-1 env]#kubectl get pod
dapi-test-pod11 0/1 Completed 0 20s
4、通过kubectl logs
查看该 pod 日志,会看到容器中/etc/config/special.how
这个文件的信息也就是它的变量赋值。
[10:49:01 root@master-1 env]#kubectl logs dapi-test-pod11
very
5、我们修改该 pod 的 yaml 文件等会好进入这个 pod 中查看它的文件挂载信息。
10:53:42 root@master-1 env #vim cm-vloumes-pod.yaml
apiVersion v1
kind Pod
metadata
name dapi-test-pod11
spec
containers
name test-container
image nginx
command "/bin/sh""-c""sleep 600"
volumeMounts
name config-volume
mountPath /etc/config
volumes
name config-volume
configMap
name special-config
restartPolicy Never
6、删除所有 pod 然后再将cm-vloumes-pod.yaml
文件构建为 pod
[10:54:34 root@master-1 env]#kubectl delete pod --all
7、通过kubectl apply
重新构建该 pod
[10:54:52 root@master-1 env]#kubectl apply -f cm-vloumes-pod.yaml
8、通过kubectl get pod
查看就会发现这个 pod 正在运行中
[10:55:34 root@master-1 env]#kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod11 1/1 Running 0 39s
9、然后我能进入到这个 pod 中,
#进入到该 pod 中
[10:57:05 root@master-1 env]#kubectl exec -it dapi-test-pod11 -- /bin/bash
#进入到该 pod 的 /etc/config/ 目录下
root@dapi-test-pod11:/# cd /etc/config/
#通过 ls 查看就会多了两个文件
root@dapi-test-pod11:/etc/config# ls
special.how special.type
#查看 special.how 文件内容为我们的赋值 very
root@dapi-test-pod11:/etc/config# cat special.how
very
#查看 special.type 文件内容为我们的赋值 charm
root@dapi-test-pod11:/etc/config# cat special.type
charm
这个的含义就是会将我们的 special-config 这个 configmap 的 pod 信息挂载到这个 pod 的 /etc/config 这个目录,也就是会把我们 configMap 中的键名如果以我们 volume 的方案他就会挂载为文件名,键值就会成为文件内容,这也是我们怎么去利用 configmap 达到注册中心的这么一个原理。
8.1.4 ConfigMap 的热更新
我们可以看一下真正的 configMap 热更新,这里给大家做了一个演示,演示的第一个就是创建了一个 configmap
8.1.4.1 创建 configMap
yaml 文件详解:
apiVersion v1 # api 使用版本为 v1
kind ConfigMap # kind 类型为 configmap
metadata# 该 configmap 元数据信息
name log-config # 该 configmap 名称为 log-config
namespace default # 使用的名称空间是默认名称空间
data# 数据信息
log_level INFO # 键名为 log_level,键值为 INFO
--- # 使用 --- 分隔创建一个新的 deployment 资源,在这个 deployment 中调用,调用的方式是通过 volumes 的方式进行挂载
apiVersion apps/v1 # api 使用版本为 apps/v1
kind Deployment # kind 类型是 deployment
metadata# 这个 deployment 的元数据信息
name my-nginx # 这个 deployment 名为 my-nginx
spec# 这个 deployment 详细描述
replicas 1 # pod 副本数目为 1
selector# 选择器匹配
matchLabels# 匹配标签
run my-nginx # 匹配的是 run=nginx 的这个标签
template# pod 模板标签
metadata# pod 元数据详细
labels# 匹配标签信息
run my-nginx # 匹配规则为 run=my-nginx
spec# 详细信息描述
containers# 容器信息
name my-nginx # 容器名为 my-nginx
image nginx # 使用的镜像是 nginx
ports# 端口暴露规则
containerPort 80 # 容器端口为 80
volumeMounts# 数据卷挂载信息
name config-volume # 匹配的是名为 config-volume 的这个数据卷
mountPath /etc/config # 挂载路径为 /etc/config
volumes# 数据卷信息
name config-volume # 该数据卷名为 config-volume
configMap# 调用的 configMap 信息
name log-config # 调用的是一个名为 log-config 的这个 configmap,也就是上面这个configmap 相互呼应相互匹配
1、编写一个yaml
文件
11:37:15 root@master-1 env #vim cm.yaml
apiVersion v1
kind ConfigMap
metadata
name log-config
namespace default
data
log_level INFO
---
apiVersion apps/v1
kind Deployment
metadata
name my-nginx
spec
replicas1
selector
matchLabels
run my-nginx
template
metadata
labels
run my-nginx
spec
containers
name my-nginx
image nginx
ports
containerPort80
volumeMounts
name config-volume
mountPath /etc/config
volumes
name config-volume
configMap
name log-config
2、通过kubectl apply
声明式创建
[11:36:37 root@master-1 ~]#kubectl apply -f svc-deployment.yaml
3、通过 kubectl get pod
查看。并且已经在运行状态。
[11:43:23 root@master-1 env]#kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-74c9c94899-x9lnq 1/1 Running 0 2m48s
4、进入到该 pod 中查看这个文件到底存不存在。
#进入到这个 pod 中
[11:54:00 root@master-1 env]#kubectl exec -it my-nginx-74c9c94899-x9lnq -- /bin/bash
#在这个 pod 中在进入到 /etc/config/ 文件下
root@my-nginx-74c9c94899-x9lnq:/# cd /etc/config/
#通过查看就发现有一个 log_level 的文件
root@my-nginx-74c9c94899-x9lnq:/etc/config# ls
log_level
#通过查看该文件里面的内容正好就是我们在 yaml 文件中定义的变量赋值
root@my-nginx-74c9c94899-x9lnq:/etc/config# cat log_level
INFO
那我们现在进行热更新看一下,通过直接修改这个 configmap。
8.1.4.2 修改 configMap
1、通过kubectl edie
后面加上我们要修改的资源类型
[13:58:49 root@master-1 env]#kubectl edit configmaps log-config
kubectl edit: # 使用 kubectl edit 进行修改
configmaps: # 需要修改的资源类型是我们的 configmap
log-config: # 修改在 configmap 下的 log-config 这个 configmap
2、将 log_level 对呀的值修改为 debug 级别,修改下面红框中的内容改为 DEBUG
3、在通过cat
命令查看就会发现/etc/config/log_level
中已经修改为了 DEBUG 级别了,这样也就意味着我们刚才修改的是 configMap ,而我们 pod 中的文件内容已经发生变化了,如果这个是我们的 nginx 的话就已经到达热更新的这么一个目的了
8.1.4.3 configMap 更新注意事项
注意:
config Map 更新后他并不会让我们的 pod 重载这个文件,也就是比如这个是我们 nginx 的 configmap 文件,然后有一个是我们的 nginx 主进程,这个 nginx 的主进程在启动的时候会加载我们的 nginx 配置文件,并且加载完成以后就不会再看这个文件了,哪怕这个文件发生变化以后也不会进行重读。
那如果我能让这个 pod 去重启,那就相当于它去重新都这个 nginx 的配置文件达到这么一个更新的状态。如果这个服务能够实时的监控这个文件发生变化进行更改的话就不用需要这么一个重启 pod 的过程了,但是我们大部分服务还是不会这样的。
更新 configmap 目前并不会触发相关 pod 的滚动更新,可以通过修改 pod annotations 的方式强制触发滚动更新,修改它的时间,这个时间的更改会触发我们的热更新,这是一种比较简单的触发方案。
kubectl pathc deployment my-nginx --patch '{"spec":{"template":{"metadata":{"annotations":{"version/config":"20190411"}}}}}'
这个例子里我们再.spec.template.metadata.annotations
中添加version/config
,每次通过修改version/config
来触发滚动更新
!!!更新 configmap 后:
-
使用该 configmap 挂载的 ENV 不会同步更新
-
使用该 configmap 挂载的 volume 中的数据需要一段时间(实测大概10秒)才能同步更新
8.1.5 configmap 实现 nginx 域名访问
这里的是一个简单的 nginx 的 server 配置,在 nginx 中都是多域名的,其实像这种情况我们可以通过在打镜像的时候就将配置打到镜像中,但是我这里采用的是 configmap
1.编写 configmap
19:51:44 root@master configm #vim nginx_configmap.yaml
apiVersion v1
kind ConfigMap
metadata
name nginx-config
data
default# 命名为 default 的配置信息
server {
listen 80;
server_name www.testnginx.com;
index index.html;
location / {
root /data/nginx/html; # nginx 中 / 页面路径
if (!-e $request_filename) {
rewrite ^/(.*) /index.html last;
}
}
}
2.编写一个 depolyment 将该 configmap 进行挂载
通过卷的 items 属性能够指定哪些条目会被暴露作为configMap卷中的文件
因为在同一个 configmap 中可能有多个配置项,所以我们通过 items 可以找到指定的配置项
18:54:49 root@master configm #vim nginx_dep.yaml apiVersion apps/v1
kind Deployment
metadata
name nginx-dep
spec
replicas1
selector
matchLabels
app ng-configmap
template
metadata
labels
app ng-configmap
spec
containers
name nginx-configmap
image nginx
ports
containerPort80
volumeMounts
name nginx-static-dir
mountPath /data/nginx/html
name nginx-config
mountPath /etc/nginx/conf.d
volumes
name nginx-static-dir
hostPath# 这里是本地挂载我们的 html 静态文件
path /data/nginx/test1
name nginx-config # 挂载到容器的名字这里我定义为 nginx-config
configMap# 存储类型为 configmap
name nginx-config # 对应刚才上面所创建的 configmap 名称
items# 指定挂载 configmap 的 default 配置
key default
path testnginx.conf # 挂载点,将 default 挂载至容器的 testnginx.conf 中
3.编写 svc
19:26:00 root@master configm #vim nginx_svc.yamlapiVersion v1
kind Service
metadata
name ng-configmap
spec
ports
name http
port80
targetPort80
nodePort30019
protocol TCP
type NodePort
selector
app ng-configmap # 标签选择器匹配刚才在 nginx-de.yaml 中定义的 app: ng-configmap
4.创建 configmap、deployment、svc
[19:52:24 root@master configm]#kubectl apply -f nginx_configmap.yaml
[19:52:31 root@master configm]#kubectl apply -f nginx_svc.yaml
[19:52:38 root@master configm]#kubectl apply -f nginx_dep.yaml
5.查看 pod 已经启动,并且被调度到了 node-1 节点上
[22:24:01 root@master configm]#kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-dep-6c8955c659-wzn89 1/1 Running 0 152m 10.200.84.133 node-1
6.进入容器查看 configmap 已经挂载成功
[19:54:01 root@master configm]#kubectl exec -it nginx-dep-6c8955c659-wzn89 /bin/bash
root@nginx-dep-6c8955c659-wzn89:/# cat /etc/nginx/conf.d/testnginx.conf
server {
listen 80;
server_name www.testnginx.com;
index index.html;
location / {
root /data/nginx/html;
if (!-e $request_filename) {
rewrite ^/(.*) /index.html last;
}
}
}
7.到 node-1 节点的 /data/nginx/test1 目录下创建 index.html 文件
# /data/nginx/test1 会随着 pod 的挂载自定创建
[22:26:03 root@node-1 ~]#echo "node1 nginx configmap" > /data/nginx/test1/index.html
8.浏览器访问验证
但是现在并不能通过域名访问,所以我们需要配置 HA 来实现代理
8.1.5.1 配置 HAproxy 实现域名访问
由于 K8S 并不能通过 7 层访问,所以我们还需要通过安装 HAproxy 来实现代理
1.安装 ha
[22:36:31 root@master configm]#apt install haproxy
# 设置开机启动
[22:38:16 root@master configm]#systemctl enable --now haproxy.service
2.配置 ha
[22:48:34 root@master configm]#vim /etc/haproxy/haproxy.cfg
# 只需在 haproxy 配置文件中添加下面代码
listen k8s-nginx-configmap # 监听ipv6、ipv4和unix sock文件
bind 10.0.0.100:80 # 指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中
mode tcp # 监听模式
server nginx 10.0.0.100:30019 check inter 3s fall 3 rise 5 # 监听服务为 nginx 地址 10.0.0.100:30019 和心跳检测配置
3.重启 ha 服务
[22:51:45 root@master configm]#systemctl restart haproxy.service
4.在其他节点添加主机头实现访问
[22:54:38 root@node-1 ~]#vim /etc/hosts
10.0.0.100 www.testnginx.com
5.访问测试可以看到现在已经实现访问
[22:54:37 root@node-1 ~]#curl www.testnginx.com
node1 nginx configmap
最后nginx实验,deploymen的spec写成了spce,哈哈哈
敲快了我现在就改