K8S-Configmap

Configmap 创建方法

命令行直接创建

使用 kubectl create configmap 命令可以直接从字面值创建 ConfigMap。通过 --from-literal 参数指定键值对,格式为 key=value。多个键值对可以重复使用 --from-literal 参数。

示例命令:

bash 复制代码
kubectl create configmap example-config --from-literal=key1=value1 --from-literal=key2=value2
从文件创建

ConfigMap 可以从一个或多个文件的内容创建。使用 --from-file 参数指定文件路径。文件内容将作为键值对的值,文件名默认为键。

示例命令:

bash 复制代码
kubectl create configmap file-config --from-file=path/to/config-file
从目录创建

整个目录中的文件可以批量创建为 ConfigMap。目录中的每个文件将生成一个键值对,文件名作为键,文件内容作为值。

示例命令:

bash 复制代码
kubectl create configmap dir-config --from-file=path/to/config-dir/
从环境文件创建

环境文件(如 .env 文件)可以通过 --from-env-file 参数转换为 ConfigMap。文件中的每一行应为 KEY=VALUE 格式。

示例命令:

bash 复制代码
kubectl create configmap env-config --from-env-file=path/to/.env
YAML 文件定义

通过 YAML 文件定义 ConfigMap 资源并应用。YAML 文件中需包含 databinaryData 字段来存储配置数据。

示例 YAML 文件:

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: yaml-config
data:
  key1: value1
  key2: value2

应用 YAML 文件:

bash 复制代码
kubectl apply -f configmap.yaml
合并多种来源

在创建 ConfigMap 时可以同时使用多个来源,如合并字面值、文件和目录。

示例命令:

bash 复制代码
kubectl create configmap mixed-config \
  --from-literal=key1=value1 \
  --from-file=path/to/file \
  --from-env-file=path/to/.env
注意事项
  • 键名必须符合 DNS 子域名规范(仅包含字母、数字、-_.)。
  • 避免在配置数据中包含敏感信息,敏感数据应使用 Secret 对象。
  • 更新 ConfigMap 后,需要重启或滚动更新 Pod 才能使更改生效。
bash 复制代码
[root@k8s-master01 ~]# kubectl create configmap tomcat-config --from-literal=tomcat_port=8080 --from-literal=server_name=myapp.tomcat.com

[root@k8s-master01 ~]# kubectl get configmap

NAME               DATA   AGE

kube-root-ca.crt   1      13d

tomcat-config      2      51s

[root@k8s-master01 ~]# kubectl get cm

NAME               DATA   AGE

kube-root-ca.crt   1      13d

tomcat-config      2      66s

[root@k8s-master01 ~]# kubectl describe configmap tomcat-config

Name:         tomcat-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
server_name:
----
tomcat.jx.com
tomcat_port:
----
8080

BinaryData
====

Events:  <none>

###查看创建的configmap的yaml信息
[root@k8s-master01 ~]# kubectl get cm tomcat-config -o yaml
apiVersion: v1
data:
  server_name: tomcat.jx.com
  tomcat_port: "8080"
kind: ConfigMap
metadata:
  creationTimestamp: "2024-02-01T06:57:54Z"
  name: tomcat-config
  namespace: default
  resourceVersion: "616425"
  uid: 062bd992-202a-4ac3-a578-32542792a43a

通过文件创建

通过指定文件创建一个 configmap,--from-file=<文件>

bash 复制代码
[root@k8s-master01 configmap]# cat nginx.conf

server {

server_name www.nginx.com;

listen 80;

root /home/nginx/www/

}

[root@k8s-master01 configmap]# kubectl create configmap nginx-conf --from-file=www=./nginx.conf 
configmap/nginx-conf created	

[root@k8s-master01 configmap]#  kubectl describe configmap www-nginx

Name:         nginx-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
www:
----
server {

server_name www.nginx.com;

listen 80;

root /home/nginx/www/

}


BinaryData
====

Events:  <none>


[root@k8s-master01 configmap]# kubectl get cm nginx-conf -o yaml
apiVersion: v1
data:
  www: |  
    server {

    server_name www.nginx.com;

    listen 80;

    root /home/nginx/www/

    }
kind: ConfigMap
metadata:
  creationTimestamp: "2024-02-01T07:12:53Z"
  name: nginx-conf
  namespace: default
  resourceVersion: "618054"
  uid: 3ee6f787-9372-4bda-b0f6-d350b2235d50
  
##www: | 作用是表示www这个可以的内容是多行的。

指定目录创建 configmap

bash 复制代码
[root@k8s-master01 configmap]# mkdir mysql-test
[root@k8s-master01 configmap]# cd mysql-test/
[root@k8s-master01 mysql-test]# echo server_id=1 > mysql.cnf
[root@k8s-master01 mysql-test]# echo server_id=2 > mysql2.cnf

[root@k8s-master01 configmap]# kubectl create configmap mysql-cnf --from-file=/root/configmap/mysql-test/
configmap/mysql-cnf created


#查看 configmap 详细信息

[root@k8s-master01 configmap]# kubectl describe cm mysql-cnf 
Name:         mysql-cnf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
mysql.cnf:
----
server_id=1

mysql2.cnf:
----
server_id=2


BinaryData
====

Events:  <none>

[root@k8s-master01 configmap]# kubectl get cm mysql-cnf -o 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

编写 configmap 资源清单 YAML 文件

bash 复制代码
[root@k8s-master01 configmap]# cat mysql-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    [mysqld]
    log-bin
    log_bin_trust_function_creators=1
    lower_case_table_names=1
  slave.cnf: |
    [mysqld]
    super-read-only
    log_bin_trust_function_creators=1

#上面中的 | 表示master.cnf文件是多行文件
[root@k8s-master01 configmap]# kubectl get cm mysql -o yaml
apiVersion: v1
data:
  master.cnf: |
    [mysqld]
    log-bin
    log_bin_trust_function_creators=1
    lower_case_table_names=1
  slave.cnf: |
    [mysqld]
    super-read-only
    log_bin_trust_function_creators=1
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"master.cnf":"[mysqld]\nlog-bin\nlog_bin_trust_function_creators=1\nlower_case_table_names=1\n","slave.cnf":"[mysqld]\nsuper-read-only\nlog_bin_trust_function_creators=1\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"mysql"},"name":"mysql","namespace":"default"}}
  creationTimestamp: "2024-02-01T07:39:13Z"
  labels:
    app: mysql
  name: mysql
  namespace: default
  resourceVersion: "620920"
  uid: acad5d26-6692-4c1b-a389-cd37bbe81d7d

三、使用 Configmap

通过环境变量引入

使用 configMapKeyRef变量

bash 复制代码
#创建一个存储 mysql 配置的 configmap

[root@k8s-master01 ~]# cat mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  log: "1"
  lower: "1"
[root@k8s-master01 ~]# kubectl apply -f mysql-configmap.yaml

configmap/mysql created

[root@k8s-master01 ~]# kubectl get cm

NAME               DATA   AGE

kube-root-ca.crt   1      13d

mysql              2      82s

#创建 pod,引用 Configmap 中的内容

[root@k8s-master01 ~]# cat mysql-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
spec:
  containers:
  - name: mysql
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    env:
    - name: log_bin #定义环境变量 log_bin
      valueFrom:
        configMapKeyRef:
          name: mysql #指定 configmap 的名字
          key: log #指定 configmap 中的 key
    - name: lower #定义环境变量 lower
      valueFrom:
        configMapKeyRef:
          name: mysql
          key: lower
  restartPolicy: Never


#更新资源清单文件

[root@k8s-master01 ~]# kubectl apply -f mysql-pod.yaml

[root@k8s-master01 ~]#  kubectl exec -it mysql-pod -- /bin/sh

/ # env
log_bin=1
KUBERNETES_PORT=tcp://10.10.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=mysql-pod
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
SERVICE_BLUE_PORT_80_TCP_ADDR=10.10.157.201
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
SERVICE_BLUE_PORT_80_TCP_PORT=80
SERVICE_BLUE_PORT_80_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.10.0.1: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
    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
[root@k8s-master01 ~]# kubectl edit configmap mysql

#将log:1 变成 log:2
apiVersion:v1
data:
 log:"2"
 lower:"1"
重新执行一次资源清单文件

```shell
[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 实现了 多场景运行
```

在 Kubernetes 1.24 版本中,如果 ConfigMap 无法进行热更新,可能有以下几种原因及解决方法:

**一、检查更新方式**

  1. **对于环境变量方式**:

\- 如果是通过环境变量的方式将 ConfigMap 中的值注入到容器中,那么 Kubernetes 本身是不支持自动热更新环境变量的。这种情况下,应用程序需要自己有重新读取环境变量的机制。例如,应用可以定期重新读取环境变量或者通过监听文件系统变化等方式来实现类似的效果,但这需要在应用层面进行开发。

\- 示例代码(在应用中实现定期重新读取环境变量的伪代码):

\```python

bash 复制代码
  import time

 

   def reload_environment_variables():
​     \# 重新获取环境变量的逻辑

​     pass

 
   while True:

​     reload_environment_variables()

​     time.sleep(60)  # 每分钟重新加载一次环境变量

\- 注意,这只是一个简单的示例,实际实现可能因应用程序的编程语言和运行环境而有所不同。

  1. **对于挂载文件方式**:

\- 当以文件形式挂载 ConfigMap 到容器中时,Kubernetes 支持一定程度的热更新。但这也依赖于应用程序是否能够检测到文件内容的变化并重新加载。一些应用程序(如 NGINX)可以自动检测并重新加载配置文件的变化,而有些应用可能需要通过发送信号(如 SIGHUP)等方式来触发重新加载。

\- 例如,对于 NGINX,当它检测到挂载的配置文件(来自 ConfigMap)发生变化时,它会自动重新加载配置。但如果应用没有这种自动检测和重新加载的机制,你可能需要在容器内编写一个脚本或使用工具来监控文件变化并触发应用的重新加载。

\- 以下是一个使用 inotifywait(Linux 下的文件变化监控工具)来监控文件变化并执行重新加载命令的示例脚本(假设应用的重新加载命令是`myapp reload`):

bash 复制代码
   #!/bin/bash

 

   while true; do

​    inotifywait -e modify /path/to/config/file  # 将/path/to/config/file替换为实际的挂载文件路径

​    myapp reload  # 执行应用的重新加载命令

   done
bash 复制代码
  \- 这个脚本需要在容器内运行,并且需要安装 inotify-tools。你可以将其添加到容器的启动命令或者作为一个单独的进程运行。

 

**二、检查相关组件和配置**

 

1. **确保 Kubernetes 版本和功能正常**:

  \- 虽然 1.24 版本理论上应该支持 ConfigMap 的挂载文件热更新,但可能存在一些特定的配置或环境因素导致问题。确保你的 Kubernetes 集群是正确安装和配置的,并且相关的组件(如 kubelet 等)运行正常。可以检查 kubelet 的日志,看是否有任何与 ConfigMap 处理相关的错误或警告信息。

  \- 查看 kubelet 日志的命令(在节点上执行):

```apl
   journalctl -u kubelet -f  # -f 选项用于实时跟踪日志
```



 

2. **检查 Pod 和容器配置**:

  \- 确认 Pod 的配置正确地将 ConfigMap 挂载到容器中。检查 Pod 的 YAML 配置文件,确保挂载路径和方式正确。

  \- 例如,以下是一个 Pod 配置中挂载 ConfigMap 的示例片段:
bash 复制代码
   apiVersion: v1

   kind: Pod

   metadata:

​    name: myapp-pod

   spec:

​    containers:

​    \- name: myapp-container

​     image: myapp-image

​     volumeMounts:

​     \- name: config-volume

​      mountPath: /etc/config  # 挂载路径

​      readOnly: true

​    volumes:

​    \- name: config-volume

​     configMap:

​      name: my-configmap

\- 确保`mountPath`是应用程序预期的路径,并且`configMap`的名称正确指向你想要更新的 ConfigMap。

  1. **检查应用程序自身的行为**:

\- 有些应用程序可能在启动时读取配置文件并缓存了内容,之后不再重新读取。这种情况下,即使 ConfigMap 的文件内容更新了,应用程序也不会感知到变化。需要检查应用程序的文档或代码,了解它是否有这种行为,并根据需要进行调整。

\- 例如,如果应用是用 Java 编写的,并且使用了类似 Spring 的框架,可能需要配置 Spring 的相关属性来支持配置文件的热更新。具体配置可能因应用架构和使用的技术栈而异。

**三、其他可能的问题和解决方法**

  1. **网络和存储问题**:

\- 如果 ConfigMap 的更新在存储后端(如 etcd)成功,但容器无法及时获取到更新后的内容,可能是网络或存储相关的问题。检查节点之间的网络连接,确保容器能够正常访问存储 ConfigMap 的 etcd 或其他存储系统。

\- 可以使用网络诊断工具(如 ping、traceroute 等)来检查网络连通性。如果是存储系统的问题,可能需要进一步检查存储的配置和状态,看是否有性能瓶颈或错误。

  1. **权限问题**:

\- 容器内的应用程序可能没有足够的权限来读取更新后的 ConfigMap 文件。确保容器运行的用户或进程有对挂载目录的读取权限。

\- 可以检查容器的安全上下文(security context)设置,确保它允许对挂载文件的正确访问。例如,在 Pod 的 YAML 配置文件中可以设置容器的安全上下文如下:

bash 复制代码
   apiVersion: v1

   kind: Pod

   metadata:

​    name: myapp-pod

   spec:

​    containers:

​    \- name: myapp-container

​     image: myapp-image

​     volumeMounts:

​     \- name: config-volume

​      mountPath: /etc/config

​      readOnly: true

​     securityContext:

​      runAsUser: 1000  # 设置容器内运行的用户 ID

​      readOnlyRootFilesystem: false  # 根据需要设置根文件系统的只读属性
相关推荐
初圣魔门首席弟子6 小时前
核心 Bug:客户端与服务器端口不匹配(导致请求无法送达)
linux·网络
福尔摩斯张6 小时前
TCP协议深度解析:从报文格式到连接管理(超详细)
linux·c语言·网络·c++·笔记·网络协议·tcp/ip
刀刀是个萌妹子6 小时前
使用CloneZilla还原操作系统
linux·运维·服务器
列逍6 小时前
Linux文件(二)
linux·磁盘·文件系统·挂载·软硬链接·缓冲区
一个平凡而乐于分享的小比特6 小时前
U-Boot 和 Linux 内核的关系及设备树详解
linux·设备树·uboot
mobº6 小时前
K8s 集群部署微服务 - DevOps(二)
微服务·kubernetes·devops
王老师青少年编程7 小时前
csp信奥赛C++标准模板库STL(3):list的使用详解
c++·容器·stl·list·标准模板库·csp·信奥赛
Sleepy MargulisItG7 小时前
【Linux网络编程】UDP Socket
linux·网络·udp
一条懒鱼6667 小时前
k8s-网络
网络·容器·kubernetes