确认[Kubernetes]ConfigMap的创建和使用方法

首先

我想要确认一下如何创建和使用ConfigMap这一次。
ConfigMap是用来保存配置信息的资源。与Secret类似,但Secret用于处理机密信息,而ConfigMap用于处理非机密的配置信息。

创建ConfigMap

可以按照与Secret类似的方法创建ConfigMap。由于创建方法有多种,所以我想尝试各种不同的方法。

–来自文件

在Secret中,我们指定了一个Key(文件)对应一个Value,但在ConfigMap中,一个Key(文件)可以对应多个Value。

maxmemory=2mb
maxmemory-policy=allkeys-lru

使用此配置文件创建ConfigMap。

$ kubectl create configmap --save-config sample-configmap1 --from-file=./redis.conf
configmap/sample-configmap1 created
$ kubectl get configmaps
NAME                DATA   AGE
sample-configmap1   1      11s
$ kubectl describe configmaps sample-configmap1
Name:         sample-configmap1
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"kind":"ConfigMap","apiVersion":"v1","metadata":{"name":"sample-configmap1","creationTimestamp":null},"data":{"redis.conf":"maxmemory=2mb...

Data
====
redis.conf:
----
maxmemory=2mb
maxmemory-policy=allkeys-lru

Events:  <none

–来自环境文件

此次将使用相同的redis.conf作为envfile。

$ kubectl create configmap sample-configmap2 --from-env-file=redis.conf
configmap/sample-configmap2 created
$ kubectl describe configmaps sample-configmap2
Name:         sample-configmap2
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
maxmemory:
----
2mb
maxmemory-policy:
----
allkeys-lru
Events:  <none>

我从相同的redis.conf文件创建了一个ConfigMap,但是使用–from-file选项时,对于一个Key(redis.conf),有两个Value(maxmemory=2mb, maxmemory-policy=allkeys-lru)进行设置。
相比之下,当使用–from-env-file选项时,每个Key(maxmemory, maxmemory-policy)和Value(2mb, allkeys-lru)都是一对一地进行设置的。

–从文字上看

这次我们将直接指定每个键和值来创建。

$ kubectl create configmap --save-config sample-configmap3 --from-literal=maxmemory=2mb --from-literal=maxmemory-policy=allkeys-lru
configmap/sample-configmap3 created
$ kubectl describe configmaps sample-configmap3
Name:         sample-configmap3
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"kind":"ConfigMap","apiVersion":"v1","metadata":{"name":"sample-configmap3","creationTimestamp":null},"data":{"maxmemory":"2mb","maxmemor...

Data
====
maxmemory-policy:
----
allkeys-lru
maxmemory:
----
2mb
Events:  <none>

尽管顺序不同,但与–from-env-file相似,Key和Value仍然是一对一的关系。

根据宣言创作

最后我想从宣言中创作一下。

apiVersion: v1
kind: ConfigMap
metadata:
  name: sample-configmap4
data:
  maxmemory: 2mb
  maxmemory-policy: allkeys-lru

我要应用这个宣言稿。

$ kubectl apply -f configmap.yaml
configmap/sample-configmap4 created
$kubectl describe configmaps sample-configmap4
Name:         sample-configmap4
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","data":{"maxmemory":"2mb","maxmemory-policy":"allkeys-lru"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"sam...

Data
====
maxmemory:
----
2mb
maxmemory-policy:
----
allkeys-lru
Events:  <none>

在这种情况下,与 –from-env-file 相同,键和值是一对一的关系。

ConfigMap的使用

我們將確認已創建的 ConfigMap 的使用方法。與 Secret 一樣,ConfigMap 也有幾種不同的方法,我們將分別進行確認。

使用特定的键作为环境变量。

由于相同的redis.conf文件,我创建了两个不同的ConfigMap,我想分别进行确认。

键和值是一对多。

首先,这是一个通过–from-file创建的ConfigMap。这个ConfigMap有一个键,设置了两个值。

我编写了以下宣言书。

apiVersion: v1
kind: Pod
metadata:
  name: redis1
spec:
  containers:
  - name: redis1
    image: redis:latest
    env:
      - name: redis_conf
        valueFrom:
          configMapKeyRef:
            name: sample-configmap1
            key: redis.conf

应用这个清单,确认已设置的环境变量。

$ kubectl apply -f redis1.yaml
pod/redis1 created
$ kubectl exec -it redis1 /bin/bash
root@redis1:/data# printenv | grep maxmemory
redis_conf=maxmemory=2mb
maxmemory-policy=allkeys-lru
root@redis1:/data# echo $maxmemory

root@redis1:/data# echo $maxmemory-policy
-policy
root@redis1:/data# echo $redis_conf
maxmemory=2mb maxmemory-policy=allkeys-lru

环境变量已设置,但尝试用echo命令进行确认时,感觉有点奇怪。我在想它是否可用…

Key和Value是一对一的关系。

这次使用了由from-env-file创建的ConfigMap。这个ConfigMap是以一对一的方式设置了键和值。

我已经创建了以下清单。
我将尝试设置两个键-值对中的maxmemory。

apiVersion: v1
kind: Pod
metadata:
  name: redis2
spec:
  containers:
  - name: redis2
    image: redis:latest
    env:
      - name: MAX_MEMORY
        valueFrom:
          configMapKeyRef:
            name: sample-configmap2
            key: maxmemory

应用此清单,并确认已设置的环境变量。

$ kubectl apply -f redis2.yaml
pod/redis2 created
$ kubectl exec -it redis2 /bin/bash
root@redis2:/data# printenv | grep MAX
MAX_MEMORY=2mb
root@redis2:/data# echo $MAX_MEMORY
2mb

这次设置正如我们预期的那样。

使用所有的键作为环境变量

只指定 ConfigMap,使用所有的 Key,放在 envFrom 下面。

先从键和值为一对多的ConfigMap中确认。
应用以下清单并进行确认。

首先,尝试从1对n的ConfigMap中确认键和值。
应用以下清单并进行确认。

apiVersion: v1
kind: Pod
metadata:
  name: redis3
spec:
  containers:
  - name: redis3
    image: redis:latest
    envFrom:
    - configMapRef:
        name: sample-configmap1
$ kubectl apply -f redis3.yaml
pod/redis3 created
$ kubectl exec -it redis3 /bin/bash
# printenv
redis.conf=maxmemory=2mb
maxmemory-policy=allkeys-lru
・・・
root@redis3:/data# echo $maxmemory

root@redis3:/data# echo $maxmemory-policy
-policy
root@redis3:/data# echo $redis.conf
.conf

果然很奇怪呢。


接下来我们会验证键(Key)和值(Value)为一对一的ConfigMap。
执行以下清单并进行确认。

apiVersion: v1
kind: Pod
metadata:
  name: redis4
spec:
  containers:
  - name: redis4
    image: redis:latest
    envFrom:
    - configMapRef:
        name: sample-configmap2
$ kubectl apply -f redis4.yaml
pod/redis4 created
$ kubectl exec -it redis4 /bin/bash
root@redis4:/data# printenv
maxmemory-policy=allkeys-lru
・・・
HOSTNAME=redis4
・・・
root@redis4:/data# echo $maxmemory-policy
2mb-policy
root@redis4:/data# echo $maxmemory
2mb

在使用printenv命令时,看起来设置没问题,但使用echo命令确认后,maxmemory-policy的设置有些奇怪。
好像是由于环境变量中包含了「.」「-」和换行符,导致无法按预期引用。

在创建ConfigMap时,最好通过以下提及的卷的方式来使用,以避免包含它们。

以卷的形式挂载

就像Secret一样,ConfigMap也可以作为Volume挂载。我们来确认一下这个操作。

只挂载特定的键

键和值是一对多。

我需要确认一下Key和Value的对应关系是1对n的ConfigMap的运行情况。

我們將應用以下宣言並進行確認。請在mountPath中指定容器的掛載路徑,並在path中指定掛載後的文件名。

apiVersion: v1
kind: Pod
metadata:
  name: redis5
spec:
  containers:
    - name: redis5
      image: redis:latest
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: sample-configmap1
        items:
        - key: redis.conf
          path: redis.conf
$ kubectl apply -f redis5.yaml
pod/redis5 created
$ kubectl exec -it redis5 /bin/bash
root@redis5:/data# cd /etc/config/
root@redis5:/etc/config# ls
redis.conf
root@redis5:/etc/config# cat redis.conf
maxmemory=2mb
maxmemory-policy=allkeys-lru

设置得很好啊。

键和值是一对一的。

下面我们将尝试挂载一个只包含特定Key的ConfigMap,其中Key和Value是一对一的关系。
在这个例子中,我们只挂载maxmemory这个Key。

apiVersion: v1
kind: Pod
metadata:
  name: redis6
spec:
  containers:
    - name: redis6
      image: redis:latest
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: sample-configmap2
        items:
        - key: maxmemory
          path: redis_maxmemory

我会应用这份宣言并进行确认。

$ kubectl apply -f redis6.yaml
pod/redis6 created
$ kubectl exec -it redis6 cat /etc/config/redis_maxmemory
2mb

确实设定了。
但是,我对Redis并不很了解,所以不确定这个设定是否可以作为Redis的参数使用。

将所有的密钥连接

我想要通过在Manifest文件中只指定ConfigMap并挂载所有Key来进行验证。
我想要分别挂载1对N和1对1的ConfigMap来测试操作。

apiVersion: v1
kind: Pod
metadata:
  name: redis7
spec:
  containers:
    - name: redis7
      image: redis:latest
      volumeMounts:
      - name: config-volume1
        mountPath: /etc/config1
      - name: config-volume2
        mountPath: /etc/config2
  volumes:
    - name: config-volume1
      configMap:
        name: sample-configmap1
    - name: config-volume2
      configMap:
        name: sample-configmap2

我們將應用這份宣言並進行確認。

$ kubectl apply -f redis7.yaml
pod/redis7 created
$ kubectl exec -it redis7 /bin/bash
root@redis7:/etc# cd /etc/config1
root@redis7:/etc/config1# ls
redis.conf
# cat redis.conf
maxmemory=2mb
maxmemory-policy=allkeys-lru
# cd ../config2
root@redis7:/etc/config2# ls
maxmemory  maxmemory-policy
root@redis7:/etc/config2# cat maxmemory
2mb
root@redis7:/etc/config2# cat maxmemory-policy
allkeys-lru

对于1对n的情况,其中一个Key将作为文件名,并且其中包含多个值。
而对于1对1的情况,多个Key分别成为一个文件,并且其中包含各个值。

总结

因为和 Secret 一样的方法,所以我以为能很轻松地做到,但意外地陷入了困难。果然还是要试过才能知道很多事情。

在相同的配置信息下,我们确认了 ConfigMap 的构建和使用方式会导致容器中显示不同。根据使用的容器镜像的不同,我们需要调整 ConfigMap 的构建和使用方式。