把 configmap 做成 volume,挂载到 pod(常用)
一、Configmap 概述
什么是 Configmap?
Configmap 是 k8s 中的资源对象,用于保存非机密性的配置的,数据可以用 key/value 键值对的形式保存,也可通过文件的形式保存。
Configmap 能解决哪些问题?
ConfigMap 的主要作用就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。
我们在部署服务的时候,每个服务都有自己的配置文件,如果一台服务器上部署多个服务:nginx、nginx、apache 等,那么这些配置都存在这个节点上,假如一台服务 器不能满足线上高并发的要求,需要对服务器扩容,扩容之后的服务器还是需要部署 多个服务:nginx、nginx、apache,新增加的服务器上还是要管理这些服务的配置, 如果有一个服务出现问题,需要修改配置文件,每台物理节点上的配置都需要修改, 这种方式肯定满足不了线上大批量的配置变更要求。 所以,k8s 中引入了 Configmap 资源对象,可以当成 volume 挂载到 pod 中,实现统一的配置管理。
1、Configmap 是 k8s 中的资源, 相当于配置文件,可以有一个或者多个 Configmap;
2、Configmap 可以做成 Volume,k8s pod 启动之后,通过 volume 形式映射到容器内部指定目录上;
3、容器中应用程序按照原有方式读取容器特定目录上的配置文件。
4、在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入。
Configmap 应用场景
1、使用 k8s 部署应用,当你将应用配置写进代码中,更新配置时也需要打包镜像,configmap 可以将配置信息和 docker 镜像解耦 ,以便实现镜像的可移植性和可复用性,因为一个 configMap 其实就是一系列配置信息的集合,可直接注入到 Pod 中给容器使用。configmap 注入方式有两种,一种将 configMap 做为存储卷,一种是将configMap 通过 env 中 configMapKeyRef 注入到容器中。
2、使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务中单独一份配置的话,那么更新配置就很麻烦,使用 configmap 可以友好的进行配置共享。
使用 ConfigMap 的限制条件
-
ConfigMap 需要在 Pod 启动前创建出来;
-
并且只有当 ConfigMap 和 Pod 处于同一命名空间时,才可以被 Pod 引用;
-
当 Pod 挂载 ConfigMap 绑定的目录时,目录下的目录并不会挂载到 Pod 内,只有目录下的文件会被挂载。
-
ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1MiB。如果你需要保存超出此尺寸限制的数据,可以考虑挂载存储卷或者使用独立的数据库或者文件服务。
二、Configmap 创建方法
命令行直接创建
直接在命令行中指定 configmap 参数创建,通过--from-literal 指定参数
bash
[root@k8s-master01 ~]# kubectl create configmap nginx-config --from-literal=nginx_port=8080 --from-literal=server_name=myapp.nginx.com
[root@k8s-master01 ~]# kubectl get configmap
NAME DATA AGE
kube-root-ca.crt 1 13d
nginx-config 2 51s
[root@k8s-master01 ~]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 13d
nginx-config 2 66s
[root@k8s-master01 ~]# kubectl describe configmap nginx-config
Name: nginx-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
server_name:
----
nginx.jx.com
nginx_port:
----
8080
BinaryData
====
Events: <none>
###查看创建的configmap的yaml信息
[root@k8s-master01 ~]# kubectl get cm nginx-config -o yaml
apiVersion: v1
data:
server_name: nginx.jx.com
nginx_port: "8080"
kind: ConfigMap
metadata:
creationTimestamp: "2024-02-01T06:57:54Z"
name: nginx-config
namespace: default
resourceVersion: "616425"
uid: 062bd992-202a-4ac3-a578-32542792a43a
创建选项解析:
以下是整理后的参数表格,包含参数名称和含义说明:
| 参数名称 | 含义说明 |
|---|---|
| --allow-missing-template-keys | 设置为true时,忽略模板中字段或映射键缺失导致的错误 |
| --append-hash | 将configmap的哈希值附加到名称后 |
| --as-group | 指定操作时模拟的组(可重复使用) |
| --as-uid | 指定操作时模拟的用户ID |
| --as | 指定操作时模拟的用户名(普通用户或服务账户) |
| --cache-dir | 默认缓存目录路径 |
| --certificate-authority | CA证书文件路径,用于验证服务器证书 |
| --client-certificate | TLS客户端证书文件路径 |
| --client-key | TLS客户端密钥文件路径 |
| --cluster | 指定kubeconfig中的集群名称 |
| --context | 指定kubeconfig中的上下文名称 |
| --disable-compression | 设置为true时禁用请求压缩 |
| --dry-run | 模拟执行模式(none/server/client) |
| --field-manager | 字段所有权管理器名称 |
| --from-env-file | 从键值对文件创建configmap |
| --from-file | 使用文件内容作为configmap的值(文件名作为键) |
| --from-literal | 直接指定键值对插入configmap |
| --help | 显示帮助信息 |
| --insecure-skip-tls-verify | 跳过服务器证书验证(不安全) |
| --kubeconfig | 指定kubeconfig文件路径 |
| --log-flush-frequency | 日志刷新间隔秒数 |
| --match-server-version | 要求服务器与客户端版本匹配 |
| --namespace | 指定请求的命名空间范围 |
| --output | 输出格式(json/yaml/name等) |
| --password | API服务器基本认证密码 |
| --profile | 性能分析类型(cpu/heap等) |
| --profile-output | 性能分析结果输出文件名 |
| --request-timeout | 单次请求超时时间 |
| --save-config | 保存对象配置到注释中 |
| --server | Kubernetes API服务器地址 |
| --show-managed-fields | 输出时保留managedFields字段 |
| --template | 模板字符串/文件路径(配合go-template输出) |
| --tls-server-name | 服务器证书验证名称 |
| --token | API服务器认证令牌 |
| --username | API服务器基本认证用户名 |
| --user | 指定kubeconfig用户名称 |
| --validate | 配置验证级别(strict/warn/ignore) |
| --vmodule | 基于文件过滤的日志设置 |
| --v | 日志详细级别 |
| --warnings-as-errors | 将服务器警告视为错误并以非零状态退出 |
通过文件创建(常用)
通过指定文件创建一个 configmap,--from-file=<文件>,若没有定义key,则使用文件名作为key,文件内容作为value。
以下是关于 www.conf: | 作用的解释表格,并补充了相关 YAML 多行文本语法说明:
YAML 多行文本语法表格
| 语法符号 | 名称 | 作用 | 示例 |
|---|---|---|---|
| ` | ` | 块折叠符 | 保留换行符,末尾换行符会被截断,文本内容原样显示(适合配置文件场景) |
\>- |
块截断符 | 折叠换行符为空格,末尾换行符会被截断 | yaml<br>content: >-<br> line1<br> line2<br> |
| ` | +` | 块保留符 | 保留所有换行符(包括末尾) |
>+ |
块折叠保留 | 折叠换行符为空格,但保留末尾换行符 | yaml<br>content: >+<br> line1<br> line2<br><br> |
指定目录创建 configmap(常用)
yaml
apiVersion: v1
data:
mysql.cnf: |
server_id=1
mysql2.cnf: |
server_id=2
kind: ConfigMap
metadata:
creationTimestamp: "2024-02-01T07:16:32Z"
name: mysql-cnf
namespace: default
resourceVersion: "618449"
uid: 3fc1c8ef-5ddd-477b-bc52-2ecf2de86e25
bash
#使用 envfrom变量
[root@k8s-master01 ~]# cat mysql-pod-envfrom.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod-envfrom
spec:
containers:
- name: mysql
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "sleep 3600" ]
envFrom:
- configMapRef:
name: mysql #指定configmap的名字
restartPolicy: Never
#更新资源清单文件
[root@k8s-master01 ~]# kubectl apply -f mysql-pod-envfrom.yaml
pod/mysql-pod-envfrom created
[root@k8s-master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-pod 1/1 Running 0 13m
mysql-pod-envfrom 1/1 Running 0 107s
[root@k8s-master01 ~]# kubectl exec -it mysql-pod-envfrom -c mysql -- /bin/sh
/ # env
KUBERNETES_PORT=tcp://10.10.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=mysql-pod-envfrom
NGINX_SVC_NODEPORT_PORT_8000_TCP_ADDR=10.10.166.16
SHLVL=1
HOME=/root
NGINX_SVC_NODEPORT_PORT_8000_TCP_PORT=8000
NGINX_SVC_NODEPORT_PORT_8000_TCP_PROTO=tcp
SERVICE_BLUE_SERVICE_HOST=10.10.157.201
NGINX_SVC_NODEPORT_SERVICE_HOST=10.10.166.16
SERVICE_BLUE_SERVICE_PORT=80
SERVICE_BLUE_PORT=tcp://10.10.157.201:80
NGINX_SVC_NODEPORT_PORT_8000_TCP=tcp://10.10.166.16:8000
TERM=xterm
lower=1
KUBERNETES_PORT_443_TCP_ADDR=10.10.0.1
NGINX_SVC_NODEPORT_PORT=tcp://10.10.166.16:8000
NGINX_SVC_NODEPORT_SERVICE_PORT=8000
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
log=1
KUBERNETES_PORT_443_TCP_PORT=443
SERVICE_BLUE_PORT_80_TCP_ADDR=10.10.157.201
KUBERNETES_PORT_443_TCP_PROTO=tcp
SERVICE_BLUE_PORT_80_TCP_PORT=80
SERVICE_BLUE_PORT_80_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.10.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.10.0.1
PWD=/
SERVICE_BLUE_PORT_80_TCP=tcp://10.10.157.201:80
把 configmap 做成 volume,挂载到 pod(常用)
bash
[root@k8s-master01 ~]# cat mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql
labels:
app: mysql
data:
log: "1"
lower: "1"
my.cnf: |
[mysqld]
welcome=duoduo
[root@k8s-master01 ~]# kubectl apply -f mysql-configmap.yaml
configmap/mysql configured
#查看详细配置信息
[root@k8s-master01 ~]# kubectl describe configmap mysql
Name: mysql
Namespace: default
Labels: app=mysql
Annotations: <none>
Data
====
log:
----
1
lower:
----
1
my.cnf:
----
[mysqld]
welcome=duoduo
BinaryData
====
Events: <none>
#创建pod资源清单文件,挂载configmap卷
[root@k8s-master01 ~]# cat mysql-pod-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod-volume
spec:
containers:
- name: mysql
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: [ "/bin/sh","-c","sleep 3600" ]
volumeMounts:
- name: mysql-config
mountPath: /tmp/config
volumes:
- name: mysql-config
configMap:
name: mysql
restartPolicy: Never
[root@k8s-master01 ~]# kubectl apply -f mysql-pod-volume.yaml
pod/mysql-pod-volume created
[root@k8s-master01 configmap]# kubectl exec -it mysql-pod-volume -- /bin/sh
/ #
/ #
/ #
/ # cd /tmp/config/
/tmp/config # ls
log lower my.cnf
/tmp/config # ls -l
total 0
lrwxrwxrwx 1 root root 10 Feb 1 08:12 log -> ..data/log
lrwxrwxrwx 1 root root 12 Feb 1 08:12 lower -> ..data/lower
lrwxrwxrwx 1 root root 13 Feb 1 08:12 my.cnf -> ..data/my.cnf
四、Configmap 热更新
仅限于卷的形式,如果是环境变量的形式则不更新!!!
限于应用程序能够对配置文件进行动态感知。nginx不行,需要在apply之后对pod执行命令:
bash
nginx -s reload
bash
[root@k8s-master01 ~]# kubectl edit configmap mysql
#将log:1 变成 log:2
apiVersion:v1
data:
log:"2"
lower:"1"
重新执行一次资源清单文件
bash
[root@k8s-master01 test1]# kubectl apply -f mysql-pod-volume.yaml
pod/mysql-pod-volume configured
[root@k8s-master01 ~]# kubectl exec -it mysql-pod-volume -- /bin/sh
/ # cat /tmp/config/log
2/ #
#一次构建镜像,通过配置管理中心configmap 实现了 多场景运行