百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

在Kubernetes中使用ConfigMap(kubectl set env)

zhezhongyun 2025-05-11 03:03 26 浏览

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

至此,我们已经清理掉之前创建的所有资源。

相关推荐

一篇文章带你了解SVG 渐变知识(svg动画效果)

渐变是一种从一种颜色到另一种颜色的平滑过渡。另外,可以把多个颜色的过渡应用到同一个元素上。SVG渐变主要有两种类型:(Linear,Radial)。一、SVG线性渐变<linearGradie...

Vue3 实战指南:15 个高效组件开发技巧解析

Vue.js作为一款流行的JavaScript框架,在前端开发领域占据着重要地位。Vue3的发布,更是带来了诸多令人兴奋的新特性和改进,让开发者能够更高效地构建应用程序。今天,我们就来深入探讨...

CSS渲染性能优化(低阻抗喷油器阻值一般为多少欧)

在当今快节奏的互联网环境中,网页加载速度直接影响用户体验和业务转化率。页面加载时间每增加100毫秒,就会导致显著的流量和收入损失。作为前端开发的重要组成部分,CSS的渲染性能优化不容忽视。为什么CSS...

前端面试题-Vue 项目中,你做过哪些性能优化?

在Vue项目中,以下是我在生产环境中实践过且用户反馈较好的性能优化方案,整理为分类要点:一、代码层面优化1.代码分割与懒加载路由懒加载:使用`()=>import()`动态导入组件,结...

如何通过JavaScript判断Web页面按钮是否置灰?

在JavaScript语言中判断Web页面按钮是否置灰(禁用状态),可以通过以下几种方式实现,其具体情形取决于按钮的禁用方式(原生disabled属性或CSS样式控制):一、检查原生dis...

「图片显示移植-1」 尝试用opengl/GLFW显示图片

GLFW【https://www.glfw.org】调用了opengl来做图形的显示。我最近需要用opengl来显示图像,不能使用opencv等库。看了一个glfw的官网,里面有github:http...

大模型实战:Flask+H5三件套实现大模型基础聊天界面

本文使用Flask和H5三件套(HTML+JS+CSS)实现大模型聊天应用的基本方式话不多说,先贴上实现效果:流式输出:思考输出:聊天界面模型设置:模型设置会话切换:前言大模型的聊天应用从功能...

ae基础知识(二)(ae必学知识)

hi,大家好,我今天要给大家继续分享的还是ae的基础知识,今天主要分享的就是关于ae的路径文字制作步骤(时间关系没有截图)、动态文字的制作知识、以及ae特效的扭曲的一些基本操作。最后再次复习一下ae的...

YSLOW性能测试前端调优23大规则(二十一)---避免过滤器

AlphalmageLoader过滤器是IE浏览器专有的一个关于图片的属性,主要是为了解决半透明真彩色的PNG显示问题。AlphalmageLoader的语法如下:filter:progid:DX...

Chrome浏览器的渲染流程详解(chrome预览)

我们来详细介绍一下浏览器的**渲染流程**。渲染流程是浏览器将从网络获取到的HTML、CSS和JavaScript文件,最终转化为用户屏幕上可见的、可交互的像素画面的过程。它是一个复杂但高度优...

在 WordPress 中如何设置背景色透明度?

最近开始写一些WordPress专业的知识,阅读数奇低,然后我发一些微信昵称技巧,又说我天天发这些小学生爱玩的玩意,写点文章真不容易。那我两天发点专业的东西,两天发点小学生的东西,剩下三天我看着办...

manim 数学动画之旅--图形样式(数学图形绘制)

manim绘制图形时,除了上一节提到的那些必需的参数,还有一些可选的参数,这些参数可以控制图形显示的样式。绘制各类基本图形(点,线,圆,多边形等)时,每个图形都有自己的默认的样式,比如上一节的图形,...

Web页面如此耗电!到了某种程度,会是大损失

现在用户上网大多使用移动设备或者笔记本电脑。对这两者来说,电池寿命都很重要。在这篇文章里,我们将讨论影响电池寿命的因素,以及作为一个web开发者,我们如何让网页耗电更少,以便用户有更多时间来关注我们的...

11.mxGraph的mxCell和Styles样式(graph style)

3.1.3mxCell[翻译]mxCell是顶点和边的单元对象。mxCell复制了模型中可用的许多功能。使用上的关键区别是,使用模型方法会创建适当的事件通知和撤销,而使用单元进行更改时没有更改记...

按钮重复点击:这“简单”问题,为何难住大半面试者与开发者?

在前端开发中,按钮重复点击是一个看似不起眼,实则非常普遍且容易引发线上事故的问题。想象一下:提交表单时,因为网络卡顿或手抖,重复点击导致后端创建了多条冗余数据…这些场景不仅影响用户体验,更可能造成实...