网站首页 > 精选文章 / 正文
在《为Kubernetes安装Dashboard》中,我们已经使用VirtualBox安装了CentOS 7.9,并在其上安装了Docker 20.10.11、Kubernetes 1.23.3和kubernetes-dashboard v2.4.0。在此基础之上,我们进一步来了解Kubernetes中ConfigMap的使用。
集中化的配置管理能力,对于一个微服务体系结构的系统是至关重要的。我们无法想象当面对数千台物理服务器中运行的数万个容器时,我们需要找到并登录到容器中去修改配置的场景。
ConfigMap作为Kubernetes内置的配置管理组件,在一定程度上解决了配置的集中管理能力。
创建一个ConfigMap资源
首先,我们在虚拟机中创建一个目录,用来存放本章节中需要使用到的一些文件:
mkdir -p ~/kubernetes/configmap/
cd ~/kubernetes/configmap/
然后,我们在此创建“demo-cm.yaml”文件,用以描述ConfigMap的一些信息:
vi demo-cm.yaml
将以下内容保存到文件中:
apiVersion: v1
kind: ConfigMap
metadata:
name: demo
data:
MY_CONF: hello
最后,我们执行以下命令,创建ConfigMap资源:
kubectl apply -f demo-cm.yaml
执行结果如下:
configmap/demo created
我们可通过以下命令来查看当前系统中“default”命名空间下的ConfigMap资源:
kubectl get configmaps
输出结果为:
NAME DATA AGE
demo 1 65s
kube-root-ca.crt 1 5d21h
其中,名称为“demo”的即为我们刚创建的ConfigMap。
我们可通过以下命令来查看这个ConfigMap的信息:
kubectl describe configmap demo
输出结果为:
Name: demo
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
MY_CONF:
----
hello
BinaryData
====
Events: <none>
我们可看到配置项“MY_CONF”的值为“hello”。
接下来,我们创建一个POD来使用这个ConfigMap。
创建一个POD来使用ConfigMap
为了体验下ConfigMap的使用,我们首先需要创建一个POD,并通过这个POD使用刚创建的ConfigMap,来直观地感受ConfigMap在POD中的呈现。
因此,我们对POD本身没有什么要求,它只要能持续地运行在那里就可以了。因此,我们需要基于镜像“centos:7”创建一个可以持续运行的镜像。
首先,我们创建一个Shell脚本,在其中编写一个死循环,作为在容器中运行的主程序:
vi endless-loop.sh
将以下内容写入到文件中:
#!/bin/bash
while [ 1 ]
do
sleep 1
done
然后,我们来创建一个以此脚本作为主程序的镜像。首先,我们创建Dockerfile文件:
vi endless-loop.dockerfile
将以下内容写入到Dockerfile文件中:
FROM centos:7
COPY ./endless-loop.sh /opt/
WORKDIR /opt/
CMD /bin/bash endless-loop.sh
现在,我们执行以下命令来创建Docker镜像:
docker image build -t endless-loop:test -f endless-loop.dockerfile .
执行结果如下:
Sending build context to Docker daemon 4.096kB
Step 1/4 : FROM centos:7
---> eeb6ee3f44bd
Step 2/4 : COPY ./endless-loop.sh /opt/
---> 920452a78377
Step 3/4 : WORKDIR /opt/
---> Running in 41acd739fe5f
Removing intermediate container 41acd739fe5f
---> 53a9cc112964
Step 4/4 : CMD /bin/bash endless-loop.sh
---> Running in 735a9295b59d
Removing intermediate container 735a9295b59d
---> b628de4edc20
Successfully built b628de4edc20
Successfully tagged endless-loop:test
我们先通过这个镜像来启动一个容器,确保容器不会立刻退出:
docker container run --name endless-loop -d endless-loop:test
我们执行以下命令,检查容器的运行情况:
docker ps -a | grep endless-loop
执行结果为:
2fc873bcf37f endless-loop:test "/bin/sh -c '/bin/ba…" About a minute ago Up About a minute
说明程序正在持续运行,也就是说刚才制作的镜像是符合预期的。
现在,我们清理掉这个容器:
docker container stop endless-loop
docker container rm endless-loop
到此为止,我们已经有了用于体验ConfigMap的镜像。现在,我们基于此镜像创建一个POD,并使用之前的ConfigMap。
首先,我们编写“demo-rc.yaml”,用以在Kubernetes中创建一个ReplicationController,来帮我们管理容器:
vi demo-rc.yaml
将以下内容写入到文件中:
apiVersion: v1
kind: ReplicationController
metadata:
name: demo
spec:
replicas: 1
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: endless-loop:test
imagePullPolicy: Never
envFrom:
- configMapRef:
name: demo
执行以下命令创建ReplicationController:
kubectl apply -f demo-rc.yaml
执行结果为:
replicationcontroller/demo created
说明ReplicationController已成功创建,现在我们执行以下命令来检查其运行情况:
kubectl get rc demo
执行结果为:
NAME DESIRED CURRENT READY AGE
demo 1 1 1 2m46s
表示ReplicationController运行正常,且已创建了POD。
现在,我们执行以下命令,列出上一个被拉起的容器:
docker container ls -l
执行结果为:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27cb5c5b1c50 b628de4edc20 "/bin/sh -c '/bin/ba…" 3 minutes ago Up 3 minutes k8s_demo_demo-sd8fm_default_25212cbd-8386-44c7-b477-c6d386901156_0
根据容器的名称,我们可以看出这个容器即使Kubernetes刚创建的容器。接下来我们通过容器的唯一标识登录到容器中:
docker exec -it 27cb5c5b1c50 /bin/bash
然后,我们通过以下命令来检查环境变量的值:
echo $MY_CONF
输出结果为:
hello
说明我们已经成功地将ConfigMap中配置的内容应用到POD中容器的环境变量中了。
ConfigMap的用法
刚才我们所尝试的用法,是将ConfigMap的值映射到POD的环境变量中。除此之外,ConfigMap还可以通过卷的形式被挂载到容器中或者配置成为容器中应用的启动参数。而且即使以环境变量的形式,也可以通过使用“env”属性来指定使用哪些值,并将其映射到容器中的哪个名称的环境变量。
另外,创建ConfigMap也不止通过YAML文件一种方法,也可以通过命令中通过字面量的形式创建,或使用文件等。即:
创建ConfigMap的方法:
- 通过YAML文件
- 通过字面量
- 通过文件或目录
使用ConfigMap的方法:
- 映射到容器的环境变量
- 以卷的形式挂载给容器
- 映射到容器运行的主程序的命令行参数
使用字面量创建ConfigMap
我们可通过以下命令来创建包含“key1”和“key2”两个配置项的ConfigMap,其值分别为“value1”和“value2”:
kubectl create configmap literal-configs --from-literal=key1=value1 --from-literal=key2=value2
执行结果为:
configmap/literal-configs created
我们可通过以下命令来查看ConfigMap的详细信息:
kubectl describe configmap literal-configs
执行结果为:
Name: literal-configs
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
key1:
----
value1
key2:
----
value2
BinaryData
====
Events: <none>
可以看到,该ConfigMap中有配置项“key1”的值为“value1”,“key2”的值为“value2”。
使用文件创建ConfigMap
使用文件来创建ConfigMap有两种方法:
- 为ConfigMap中的每个配置项指定一个文件,这个文件中的内容即为配置项的值。
- 直接指定一个目录,则目录中每个文件的名称即为配置项的名称,文件的内容即为配置项的值。
我们首先来创建一个包含“hello”的文本文件:
echo hello > say.txt
然后我们创建一个目录,并在目录中创建名为“application.yml”的文件:
mkdir conf-dir
vi conf-dir/application.yml
将以下内容输入到文件中:
server:
port: 8080
然后,我们执行以下命令创建ConfigMap:
kubectl create configmap file-configs --from-file=say=say.txt --from-file=conf-dir
输出结果为:
configmap/file-configs created
ConfigMap已被成功创建,我们可查看其详细信息:
kubectl describe configmap file-configs
输出结果为:
Name: file-configs
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
application.yml:
----
server:
port: 8080
say:
----
hello
BinaryData
====
Events: <none>
由此可见,我们指定的配置项“say”的值即为文件“say.txt”的内容,而目录“conf-dir”中的“application.yml”的文件名成为了另一个配置项,其内容即为这个文件的值。
至此,我们已经了解了ConfigMap的各种创建方式。最后,我们在通过卷的形式将ConfigMap中的配置挂载给POD。
将ConfigMap的配置挂载给POD
我们继续使用刚才的“endless-loop:test”镜像。
首先,我们来编辑一份YAML配置:
vi demo-volume-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: demo-volume
spec:
replicas: 1
template:
metadata:
labels:
app: demo-volume
spec:
containers:
- name: demo-volume
image: endless-loop:test
imagePullPolicy: Never
volumeMounts:
- name: config-files
mountPath: /opt/config-files
volumes:
- name: config-files
configMap:
name: file-configs
执行以下命令,创建ReplicationController:
kubectl apply -f demo-volume-rc.yaml
执行结果为:
replicationcontroller/demo-volume created
查看ReplicationController的状态:
kubectl get rc demo-volume
执行结果为:
NAME DESIRED CURRENT READY AGE
demo-volume 1 1 1 77s
说明ReplicationController运行正常,再查看POD状态:
kubectl get pods
执行结果为:
NAME READY STATUS RESTARTS AGE
demo-sd8fm 1/1 Running 0 176m
demo-volume-2qf4d 1/1 Running 0 2m9s
说明POD运行正常,然后找到上一个被创建的Docker容器:
docker ps -a -l
执行结果为:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80e401edd797 b628de4edc20 "/bin/sh -c '/bin/ba…" 2 minutes ago Up 2 minutes k8s_demo-volume_demo-volume-2qf4d_default_ab041f62-e3df-4038-8280-eb65d9f4d299_0
通过容器的唯一标识,我们登录到容器中:
docker exec -it 80e401edd797 /bin/bash
在容器中查看挂载配置的目录中的文件:
ll /opt/config-files
输出结果为:
lrwxrwxrwx 1 root root 22 Feb 3 17:35 application.yml -> ..data/application.yml
lrwxrwxrwx 1 root root 10 Feb 3 17:35 say -> ..data/say
说明配置已经通过文件的形式被挂载到了POD中。之后我们可以分别查看两个文件的内容。
查看application.yml文件的内容:
cat /opt/config-files/application.yml
输出结果为:
server:
port: 8080
查看say文件的内容:
cat /opt/config-files/say
输出结果为:
hello
两个文件的内容均与之前的配置一致。至此,以卷的形式将ConfigMap挂载到POD已经完成。
在命令行参数中使用ConfigMap
在这里,我们继续使用之前的“endless-loop:test”镜像,以及之前创建的名为“literal-configs”的ConfigMap。
我们首先创建ReplicationController的YAML文件:
vi demo-cmd-rc.yaml
将以下内容写入到文件中:
apiVersion: v1
kind: ReplicationController
metadata:
name: demo-cmd
spec:
replicas: 1
template:
metadata:
labels:
app: demo-cmd
spec:
containers:
- name: demo-cmd
image: endless-loop:test
imagePullPolicy: Never
envFrom:
- configMapRef:
name: literal-configs
command:
- /bin/bash
- -c
- /bin/bash /opt/endless-loop.sh $(key1) $(key2)
然后,执行以下命令创建ReplicationController:
kubectl apply -f demo-cmd-rc.yaml
输出结果为:
replicationcontroller/demo-cmd created
查看ReplicationController的状态:
kubectl get rc demo-cmd
输出结果为:
NAME DESIRED CURRENT READY AGE
demo-cmd 1 1 1 3m16s
ReplicationController运行正常,继续查看POD状态:
kubectl get rc demo-cmd
执行结果为:
NAME READY STATUS RESTARTS AGE
demo-cmd-dp9rr 1/1 Running 0 3m50s
demo-sd8fm 1/1 Running 0 3h48m
demo-volume-2qf4d 1/1 Running 0 54m
可见名为“demo-cmd-dp9rr”的POD已经启动成功,我们再获取上一个被创建的容器:
docker container ls -a -l
执行结果为:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4752902d8055 b628de4edc20 "/bin/bash -c '/bin/…" 5 minutes ago Up 5 minutes k8s_demo-cmd_demo-cmd-dp9rr_default_b0b41dd3-aad2-45d1-98c3-5d20b4b765a8_0
我们通过容器的唯一标识登录到容器中:
docker exec -it 4752902d8055 /bin/bash
在容器中执行以下命令:
ps -ef
输出结果为:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 18:25 ? 00:00:00 /bin/bash /opt/endless-loop.sh value1 value2
root 381 0 0 18:31 pts/0 00:00:00 /bin/bash
root 407 1 0 18:31 ? 00:00:00 sleep 1
root 408 381 0 18:31 pts/0 00:00:00 ps -ef
可以看到,PID为“1”的进程,其启动参数中包含了配置在“literal-configs”中的“key1”和“key2”对应的配置的值。至此,我们已经成功地在容器主程序的命令行中使用ConfigMap的配置作为参数使用。
到此,ConfigMap的各种创建和使用方法我们均已操作完成,下面我们来对环境进行清理。
清理环境
在清理环境时,我们只需要删除对应的ReplicationController和ConfigMap即可。
首先,我们删除之前创建的ReplicationController:
kubectl delete rc demo demo-volume demo-cmd
执行结果为:
replicationcontroller "demo" deleted
replicationcontroller "demo-volume" deleted
replicationcontroller "demo-cmd" deleted
三个ReplicationController均已删除成功。然后我们查看POD,确保各POD也已被清理:
kubectl get pods
执行结果为:
No resources found in default namespace.
可见,相应的POD也已被清理掉。接下来我们清理之前创建的ConfigMap:
kubectl delete cm demo file-configs literal-configs
执行结果为:
configmap "demo" deleted
configmap "file-configs" deleted
configmap "literal-configs" deleted
三个ConfigMap也已被清理掉。
最后,我们将用于测试的Docker镜像清理掉即可:
docker image rm endless-loop:test
执行结果为:
Untagged: endless-loop:test
Deleted: sha256:b628de4edc20584151b35c9ce9a52361ea2817960c1d33dc36b86b96f43903cf
Deleted: sha256:53a9cc112964809a04b193db3c9a86909f588b303b80992689ef045328c30ce7
Deleted: sha256:920452a783774eafe837b08de071520310c1226e380f5a0ee98ca237a001b1b7
Deleted: sha256:4aa58aac0ed84d437c2fd8562b5d56bbba78a4871426d6d962541315804817ed
至此,我们已经清理掉之前创建的所有资源。
Tags:yaml map
猜你喜欢
- 2025-05-03 大模型直接搜索图片内容!群晖部署AI相册管理工具 immich(二)
- 2025-05-03 这样构建 K8s 中间件运维平台,运维真的能少遭很多罪……
- 2025-05-03 构建 Kubernetes中间件运维平台:标准化、可视化与全栈运维
- 2025-05-03 flutter集成 百度地图 ^2.0.1版本 | 绕坑必备
- 2025-05-03 涨薪技术|Kubernetes(k8s)之yaml语法大全
- 2025-05-03 步步为营把k8s pvc存储从一个ceph集群迁移到另一个
- 2025-05-03 opsone运维管理平台的独门绝技系列之一
- 2025-05-03 教你 7 步快速构建 GitLab 持续集成环境
- 2025-05-03 Kubernetes中的PV、PVC、Configmap介绍
- 2025-05-03 kubernetes环境手动部署 Prometheus 监控系统安装文档