MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

在Kubernetes中使用ConfigMap(kubernetes的namespace)

2025-05-03 14:26 huorong 精选文章 6 ℃ 0 评论

在《为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

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言