④.ConfigMap
一.ConfigMap
二.创建ConfigMap
三.Pod引用configmap
四.Redis结合ConfigMap实践
=======================================================
一.ConfigMap
1.1 什么是ConfigMap
ConfigMap资源主要为容器注入相关的程序配置信息,用来制定程序的运行方式,比如Redis监听端口、最大客户端连接数。
当定义好一个ConfigMap资源后,如果Pod需要使用,可以通过环境变量或存储卷的形式将其挂载并加载相关的配置,降低了配置与镜像文件的耦合关系。
1.2 为什么需要ConfigMap
将应用配置信息与程序进行分离,这样可以使得应用程序被更好地复用,通过不同的配置能实现更灵活的功能,例如:在测试环境中Nginx提供test域名访问,且没配置压缩功能,而在生产环境中则需要提供wwww域名访问,且需要开启压缩功能,所以将应用容器与配置分离,根据不同的环境调用不同的ConfigMap配置,能有效的降低耦合度和复杂度。
二.创建ConfigMap
2.1 基于命令创建CM
1.使用 kubectl create configmap命令使用--from-literal选项给出键值对来创建 ConfigMap
[root@master ~]# kubectl create configmap nginx-command-cm --from-literal=ngx.host='0.0.0.0' --from-literal=nginx.port='8899'
configmap/nginx-command-cm created
2.通过 kubectl get configmap 查看 nginx-comand-cm对象YAML格式可以看出,ConfigMap资源没有 sepc和status,而是直接使用data字段嵌套键值数据。
[root@master ~]# kubectl get configmaps nginx-uliangcommand-cm -o yaml
apiVersion: V1
data:
nginx.port: "8899"
ngx.host: 0.0.0.0
kind: ConfigMap
metadata:
creationTimestamp: "2022-04-17T07:11:41Z"
name: nginx-command-cm
namespace: default
resourceVersion:"1270921"
uid: 2691ce16-6e6d-4b2c-a489-a2b01a53bd93
从上配置得知,若要基于配置清单创建ConfigMap资源时,仅需要指定apiVersion、kind、metadata、data这四个字段;
2.2 基于文件创建CM
ConfigMap资源也可以为应用程序提供大段配置,这些大段配置通常保存在一个或多个文件中,可以使用 kubectl create configmap 命令,通过 --from-file 选项一次加载一个配置文件的内容为指定键的值。默认文件名为 key,文件内容为 values
1.准备两个nginx配置文件
#主位置文件
[root@master configmap]# cat myserver.conf
server {
listen 8080;
server_name my.oldxu.net ;
location / {
root /usr/share/nginx/html;
index index.html;
}
include /etc/nginx/conf.d/*.cfg;
}
# 用于开启Nginx状态模块配置
[root@master configmap]# cat myserver-status.cfg
location /ngx_status {
stub_status;
access_log off;
}
2.通过下面的命令可以把准备好的Nginx配置文件保存到ConfigMap对象的 nginx-confs中,其中一个直接使用myserver.conf作为key名称,另一个myserver-status.cfg对应的键名称自定义为status.cfg
[root@master ~]# kubectl create configmap nginx-confs --from-file=./nginx-conf.d/myserver.conf --from-file=status.cfg=./nginx-conf.d/myserver-status.cfg
3.我们通过nginx-confs对象的详情了解到各个键对应的值
kubectl describe configmaps nginx-confs
Name: nginX-confs
Namespace: default
Labels: <none>
Annotations: <none>
Data:
===
myserver.conf: # 键的名称
------ # 下面是键的值
server
listen 8080;
server_name my.oldxu.net;
location / {
root /usr/share/nginx/html;
index index.html;
}
include /etc/nginx/conf.d/*.cfg;
}
status.cfg:
----
location /ngx_status {
stub status;
access_log off;
}
2.3 基于目录创建CM
对于配置文件较多且无需自定义键名称的场景,可以直接在 kubectl create configmap 命令的--from-file选项上附加一个目录路径就能将该目录下的所有文件创建于同一个ConfigMap资源中,各文件名即为键名称。
1.准备多个nginx配置文件,都统一存储至nginx-conf.d目录中;
# 主位管文件
[root@master configmap]# cat nginx-conf.d/myserver.conf
server {
listen 8888;
server_name my.odxu.net ;
location / {
root /usr/share/nginx/html;
index index.html;
}
include /etc/nginx/conf.d/*.cfg;
}
# 用于开启Nginx状态模块配置
[root@master configmap]# cat nginx-conf.d/myserver-status .cfg
location /ngxstatus {
stub_status;
access_log off;
}
# 用于开启Nginx压缩功能
[root@master configmap]# cat nginx-conf.d/myserver-gzip.cfg
gzip on;
2.通过下面的命令将nginx-conf.d目录中的所用文件都保存到nginx-confs-files对象中。
[root@master configmap]# kubectl create configmap nginx-confs-files --from-file= ./nginx-conf.d/
3.此目录包含 myserver.conf,myserver-status.cfg,myserver-gzip.cfg 这3个配登文件,它们会被分别存储为3个键值数据。
kubectl describe configmaps nginx-confs-files
Name: nginx-confs-files
Namespace: default
Labels: <none>
Annotations: <none>
Data:
=====
myserver-gzip.cfg: # 键名称1
====
gzip on;
myserver-status.cfg: # 键名称2
....
location /ngxstatus {
stub_status;
access_log off;
}
myserver.conf: # 键名称3
----
server {
listen 8080;
server_name my.oldxu.net;
location / {
root /usr/share/nginx/html;
index index.html;
}
include /etc/nginx/conf.d/*.cfg;
}
2.4 配合清单创建CM
基于配置清单创建ConfigMap资源时,仅需要指定apiVersion、kind、metadata、data这四个字段;
cat demoapp-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: demoapp-config
namespace: default
data:
host: 0.0.0.0 #key: value
port: "8888" #key: value
myserver.conf: | #key: value
server
listen 80;
server_name k8s.oldxu.net;
location / {
root /usr/share/nginx/html;
include /etc/nginx/conf.d/*.cfg;
}
myserver-status.cfg: | #key: value
location /ngx_status {
stub_status;
access_log off;
}
若键值来自于文件或一个目录,会发现不如通过命令行创建来的有效,因此我们可以先使用命令行加载文件或目录的方式进行创建,而后在通过kubectl get cm -o yaml 获取相关信息进行编辑和保存。
三.Pod引用configmap
3.1 通过环境变量引入CM键值
3.1.1 env引用变量示例
pod清单中除了使用vaule字段直接给定变量之外,还支持valueFrom字段嵌套 configMapKeyRef 来引用ConfigMap对象的键值,具体格式如下:
env:
- name: <string> # 要赋值的环境变量名称
valueFrom: # 定义变量的引用
configMapkeyRef: # 变量来自于configmap对象
name: <string> # configmap对象的名称 (因为有很多configmap,需要指定具体的名称)
key: <string> # configmap的键名称
这种方式赋值环境变量与直接赋值环境变量方式并无区别,它们都可以用于容器的启动脚本或直接传递给容器应用等。
3.1.2 env引用变量实践
demoapp 容器支持通过环境变量 HOST、PORT 为其指定监听的地址和端口。
1.定义configmap资源
[root@master configmap]# cat demoapp-var-conf.yaml
apiVersion: v1
kind: ConfigMap
metadata :
name: demoapp-var-conf
data:
demoapp.host: 0.0.0.0
demoapp.port: "8888"
2.创建一个Pod,然后通过env方式引用变量
cat demoapp-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: demoapp-env-cm
spec:
containers:
- name: demoapp-env-cm
image: oldxu3957/demoapp:v1.0
env:
- name: HOST # HOST变量名
valueFrom:
configMapKeyRef:
name: demoapp-var-conf # 引用demoapp-var-conf资源中的demoapp.host
key: demoapp.host
- name: PORT # PORT变量名
valueFrom:
configMapKeyRef:
name: demoapp-var-conf # 引用demoapp-var-conf资源中的的demoapp.port
key: demoapp.port
3.验证与测试
[root@master configmap]# kubectl exec demoapp-env-cm -- netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0.0.0.0:8888 0.0.0.0:* LISTEN1/python3
注意:
被引用的ConfigMap资源必须事先存在,否则无法在Pod对象中引用ConfigMap资源,另外ConfigMap属于名称空间级别的资源,它必须与引用它的Pod资源在同一名称空间
3.2 通过卷挂载方式引入CM键值
使用环境变量方式导入 ConfigMap 对象中来源较长的文件内容,会导致占据过多的内存空间,同时也不支持内容的动态更新。其次该类数据主要用于为容器提供配置文件,所以将其内容直接通过挂载的方式进行引用,会是一种更好的选择.
3.2.1 引用整个存储卷
将ConfigMap对象的每个键名转为容器挂载点路径下的一个文件名,所以每个键名应该设计为对容器应用加载的配置文件名称。
1.启动一个NginxPod,然后将此前创建的 nginx-confs-files 引用至容器的 /etc/nginx/conf.d目录中;
cat nginx-volume-all-conf.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-volume-all-cm
spec:
containers:
- name: nginx-volume-all-cm
image: nginx
volumeMounts: #1.将nginx-confs-files挂载到/etc/nginx/conf.d/目录下
- name: nginx-confs
mountPath: /etc/nginx/conf.d/
volumes: #2.nginx-confs-files的内容
- name: nginx-confs
configMap:
name: nginx-confs-files
2.此Pod资源引用了nginx-confs-files中包含三个配置文件
[root@master ~]# kubectl exec -it nginx-volume-all-cm -- ls /etc/nginx/conf.d/
myserver-gzip.cfg myserver-status.cfg myserver.conf
# myserver.conf定义主站,然后include包含了所有.cfg文件
3.访问Pod对应8080端口对应的/ngx_status,看是否能打开对应的nginx状态页
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-volume-all-cm 1/1 Running 4m49s 192.168.166.184 node1
[root@master ~]# curl 192.168.166.184:8080/ngx_status
Active connections: 1
server accepts handled requests
1 1 1
Reading: 0 Writing: 1 Waiting: 0
3.2.2 引用存储卷部分键值
有些应用场景中,用户可能期望仅向容器中挂载指定的几个键,例如前面创建的一个名为 demoapp-config 里面有4个键,其中 host、port能为demoapp容器定义监听地址及端口,而 myserver.conf.myserver-status.cfg 能为nginx提供一个虚拟主机站点以及该虚拟站点的状态信息。
1.编写Pod,运行两个容器,分别调用不同的configmap配置
cat demoapp-nginx-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: demoapp-nginx-cm
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: ngxconfs # 将ngxconfs配置文件挂载至/etc/nginx/conf.d/目录下
mountPath: /etc/nginx/conf.d/
- name: demoapp # demoapp容器详情
image: oldxu3957/demoapp:w1.8
env:
- name: PORT
valueFrom:
configMapKeyRef:
name: demoapp-config
key: port
- name: HOST
valueFrom:
configMapKeyRef:
name: demoapp-config
key: host
volumes:
- name: ngxconfs # nginxconfs引用demoapp-config的configmap资源
configMap:
name: demoapp-config
items:
- key: myserver.conf # 要引用的键名称(必写)
path: k8s.oldxu.net.conf # 对应的键在挂载点目录中映射的文件名称(必写)
mode: 0644
- key: myserver-status.cfg
path: myserver-status.cfg
mode: 0644
2.查看容器状态
[root@master ]# kubectl get pod demoapp-nginx-cm -o wide
NAME READY STATUS RESTARTS AGE IP NODE
demoapp-nginx-cm 2/2 Running8 0 17S 192.168.184.48 node2
3.验证nginx容器
[root@master ]# curl http://192.168.184.48/ngx_status
Active connections: 1
server accepts handled requests
2 2 2
Reading: 8 Writing: 1 Waiting: 0
4.验证demoapp容器
[root@master configmap]# kubectl exec -it demoapp-nginx-cm -c demoapp -- netstat -lntp
Proto Recv-0 Send-D Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 LISTEN nginx
tcp 0 0 0.0.0.0:8888 LISTEN demoapp
# demoapp和nginx容器都在一个Pod中,且他们是共享网络命名空间,所以在demoapp容器中能看到nginx的80端口
3.2.3 引用存储卷单个键值
前面两种方式中,无论是装在ConfigMap对象中的所有文件还是部分文件,挂载点目录下原有的文件都会被隐藏。 (打开刚才创建的nginx容器验证,看默认的default.conf配置文件是否还存在)
对于期望将ConfigMap 对象提供的配置文件补充在挂载点目录下的需求来说,这种方法难以实现,好在我们可以通过容器上的volumeMounts字段 subpath 来解决
1.运行一个NginxPod,将demoapp-config中myserver.confmyserver-status.cfg挂载进来测试
cat nginx-subpath-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-subpath-cm
spec:
volumes:
- name: ngxconfs
configMap:
name: demoapp-config
containers:
- name: nginx
image: nginx
volumeMounts:
- name: ngxconfs
mountPath: /etc/nginx/conf.d/k8s.oldxu.net.conf #挂载容器对应的路径
subPath: myserver.conf
- name: ngxconfs
mountPath: /etc/nginx/conf.d/k8s-status.cfg
subPath: myserver-status.cfg
2.验证容器/etc/nginx/conf.d/目录中原有的 default.conf 文件是否能够得以保留
[root@master ~]# kubectl exec -it nginx-subpath-cm --ls -l /etc/nginx/conf.d/
-rw-r--r-- 1 root root 1093 Apr 17 11:58 default.conf
-rw-r--r-- 1 root root 58 Apr 17 11:58 k8s-status.cfg
-rW-r--r-- 1 root root 152 Apr 17 11:58 k8s.oldxu.net.conf
3.访问测试
[root@master configmap]# curl 192.168.166.157
<html>
.....
<h1>Welcome to nginx!</h1>
.....
</html>
# 只能通过k8s.oldxu.net域名方式访问到对应的状态页面,其他方式访问会出现404
[root@master configmap]# curl -HHost:k8s.oldxu.net 192.168.166.157/ngx_status
Active connections: 1
server accepts handled requests
21 21 21
Reading: 0 Writing: 1 Waiting: 0
四.Redis结合ConfigMap实践
4.1 场景说明
- 使用Redis配置的值创建一个ConfigMap文档
- 创建一个Redis Pod,挂载并使用创建的ConfigMap
- 验证配置已经被正确应用
4.2 创建configmap
首先创建一个ConfigMap配置文件,写入一些配置信息
cat <<EOF >./redis-config.yaml
apiVersion: V1
kind: ConfigMap
metadata:
name: example-redis-conf
data:
redis-config: |
bind 0.0.0.0
port 6380
EOF
4.3 创建Redis-Pod
cat redis-server-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-server-cm
spec:
containers:
- name: redis-server-cm
image: redis
command: #调整启动命令
- redis-server
- "/redis-master/redis.conf"
volumeMounts:
- name: config #2.config内容挂载至/redis-master/redis.conf
mountPath: /redis-master/redis.conf
subPath: redis-config #3.将config中redis-config这个key挂载至对应的路径
volumes:
- name: config #1.config数据来源与example-redis-conf这个CM
configMap:
name: example-redis-conf
4.4 检查Redis配置
使用 kubectl exec 进入 pod,运行 redis-cli 工具检查当前配置:
[root@master configmap]# kubectl exec -it redis-server-cm -- /bin/bash
root@redis-server-cm:/data# redis-cli
Could not connect to Redis at 127.0..1:6379:
Connection refused
not connected> exit
root@redis-server-cm:/data# redis-cli -p 6380
127.0.0.1:6380>
1.查看maxclients,最大运行客户端连接数
127.0.0.1:6380> config get maxclients
1) "maxclients"
2) "10000"
2.查看maxmemory,最大能使用的内存;
127.0.0.1:6380> config get maxmemory
1)"maxmemory"
2)"0"
4.5 更新ConfigMap
接下来,向example-redis-config configmap更新一些配置信息
cat redis-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: example-redis-conf
data:
redis-config: |
bind 0.0.0.0
port 6380
maxclients 200000 # 调整最大允许的客户端连接数
maxmemory 2mb # 调整最大使用的内存
requirepass oldxu # 为redis设定一个密码
4.6 验证容器更新
修改后,容器中对应配置值并未更改,联的 ConfigMap 中获取更新的值。
1.删除并重新创建 Pod:
[root@master ~]# kubectl delete pod redis-server-cm
[root@master ~]# kubectl apply -f redis-server-cm.yaml
2.重新登录Redis应用:
[root@master ~]# kubectl exec -it redis-server-cm -- /bin/bash
root@redis-server-cm:/data# redis-cli -p 6380 -a oldxu
127.0.0.1:6380>
3.查看 maxclients
127.0.0.1:6380> config get maxclients
1)"maxclients"
2) "200000"
4.查看 maxmemory,它的值应该是 2097152 bytes,相当于2Mb
127.0.0.1:6380> config get maxmemory
1) "maxmemory"
2) "2097152"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2022-06-14 wireguard