Kubernetes配置管理

通常情况下,一个服务的启动需要依赖一些配置,比如一个 java 应用需要知道自己连接的数据库或其他中间件的地址是什么,需要知道连接另一个服务的接口地址是什么,所以需要告诉应用其他服务的配置信息。一般可以通过环境注入或者配置文件进行统一管理,而不是写死在代码里面,这也是云原生应用设计比较重要的因素--配置分离。

在传统的架构中,配置文件可以保存在本地服务器、代码仓库或配置中心,而在 kubernetes 上,其抽象为 ConfigMap(缩写为 CM)和 Secret 的概念,用来管理程序的配置文件或 Pod 变量,比如 Nginx配置、应用配置、Maven seting 配置文件等,

一、什么是 ConfigMap

在传统架构中,配置文件往往被保存在宿主机上,程序启动是可以指定某个配置文件,但是使用容器部署时,容器所在的节点并不固定,所以不能使用这种方式,此处在构建镜像时,如果把配置文件也放在容器里面,那么配置文件一旦有更改的话,也是一件非常麻烦的事情。所以 k8s 抽象了一个 configMap的概念,将配置与 pod 和组件分开,这有助于保持工作负载的可移植性,使配置更易于更改和管理。比如在生产环境中,可以将 Nginx、Redis 等应用的配置文件存储在 ConfigMap 上,然后将其挂载即可使用。

相对于 secret,ConfigMap 更倾向于存储和共享非敏感、未加密的配置信息,假如是集群中使用敏感信息,最好使用 secret。

ConfigMap 用来在键值对数据库(etcd)中保存非加密数据。一般用来保存配置文件。

ConfigMap 可以用作环境变量、命令行参数或者存储卷。

ConfigMap 将环境配置信息与 容器镜像 解耦,便于配置的修改。

ConfigMap 在设计上不是用来保存大量数据的。

ConfigMap 中保存的数据不可超过 1 MiB。

二、创建 ConfigMap

ConfigMap 可以用目录(目录下有多个文件)、单个文件或字符值的方式创建,使用 kubectl 创建一个 ConfigMap 的命令格式如下:

kubectl create configmap <map-name><data-source>

map-name:configMap 的名称

data-source:数据源,可以使数据的目录、文件或字符值ConfigMap 中的数据是以键值对(key-value pair)的形式保存的,其中:key:文件名或秘钥

value:文件内容或字符值

1.基于目录创建 ConfigMap

假如一次性需要多个文件来创建 ConfigMap,可以使用 kubectl create configmap 命令从同一个目录中的多个文件创建 ConfigMap。

(1)创建 conf 目录,里面放置两个文件
[root@master ~]# mkdir /conf
[root@master ~]# cd /conf/
[root@master conf]# echo "this is test01">file01.conf
[root@master conf]# echo "this is test02">file02.conf
(2)基于目录下的所有文件创建 configMap
[root@master conf]# ku create cm game-config-1 --from-file=/conf/
configmap/game-config-1 created

注意:

ConfigMap 是按namespace 隔离的,不同的namespace 之间的configMap 的名称可以相同,但是

不能跨namespace 进行访问,创建ConfigMap 时,可以使用-n 选项指定资源所在的namespace.

(3)查看当前创建的 ConfigMap
[root@master conf]# ku get cm game-config-1
NAME            DATA   AGE
game-config-1   2      42s
[root@master conf]# ku get cm game-config-1 -oyaml
apiVersion: v1
data:
  file01.conf: |
    this is test01
  file02.conf: |
    this is test02
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T00:52:50Z"
  name: game-config-1
  namespace: default
  resourceVersion: "9830"
  uid: 71bf5590-8ee1-457a-8023-e8f614a05df9

注意:

由于该 ConfigMap 是直接基于目录创建的,没有指定 ConfigMap 中的 key 名,因此默认是按照目录下的文件名作为 ConfigMap 数据中的 key 名。

2.基于文件创建 ConfigMap

(1)创建测试文件 game-cfg
[root@master conf]# echo "my name is zhangsan">game.cfg
(2)基于单个文件创建 ConfigMap
[root@master conf]# ku create cm game-config-2 --from-file=/conf/game.cfg 
configmap/game-config-2 created
(3)查看当前创建的 ConfigMap
[root@master conf]# ku get cm game-config-2 -oyaml
apiVersion: v1
data:
  game.cfg: |
    my name is zhangsan
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T00:56:41Z"
  name: game-config-2
  namespace: default
  resourceVersion: "10157"
  uid: 052863de-4988-4dbf-98ad-e0375e2f151c

注意:

由于没有指定ConfugMap的key,因此使用文件名作为key。

(4)使用带有 key 的命令创建 configMap
[root@master conf]# ku create cm game-config-3 --from-file=myfile-key=/conf/game.cfg 
configmap/game-config-3 created
(5)查看当前创建的 configMap
[root@master conf]# ku get cm game-config-3 -oyaml
apiVersion: v1
data:
  myfile-key: |
    my name is zhangsan
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T01:01:29Z"
  name: game-config-3
  namespace: default
  resourceVersion: "10564"
  uid: 5fa240bf-9dde-4513-8914-dba3d7507b4a
(6)多次使用使用--from-file 传入参数,用以从多个文件创建 configMap
[root@master conf]# ku create cm game-config-4 --from-file=myfile01-key=/conf/file01.conf --from-file=myfile02-key=/conf/file02.conf 
configmap/game-config-4 created

[root@master ~]# ku get cm game-config-4 -oyaml
apiVersion: v1
data:
  myfile01-key: |
    this is test01
  myfile02-key: |
    this is test02
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T01:05:15Z"
  name: game-config-4
  namespace: default
  resourceVersion: "10880"
  uid: 984774c7-bbf9-4dfe-963c-d630d52f5d3a

3.基于 ENV 文件创建 ConfigMap

假如有一个文件 game-env-file.cfg,里面存储的 key=value 形式的数据,此类文件可以当做某个应用的环境变量配置,此时可以使用--from-env-file 从 ENV 文件创建 configMap。

(1)创建测试用的变 key-value 文件
[root@master ~]# cd /conf/
[root@master conf]# vim game-env-file.cfg
name1=zhangsan
name2=lisi
name3=wangwu
(2)创建 ConfigMap
[root@master conf]# ku create cm game-config-env-file --from-env-file=/conf/game-env-file.cfg 
configmap/game-config-env-file created
(3)查看当前创建的 ConfigMap
[root@master conf]# ku get cm game-config-env-file -o yaml
apiVersion: v1
data:
  name1: zhangsan
  name2: gouman
  name3: wanggouman
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T01:09:32Z"
  name: game-config-env-file
  namespace: default
  resourceVersion: "11244"
  uid: fe7167ee-9f47-4812-9fc5-0427978018ba

4.基于字符值创建 ConfigMap

有时候配置的并不是很多,只有几个 key=value 的参数,可以直接使用 kubectl create configmap--from-lietal 参数来定义命令行的字符值。

备注:

literal:文字的;逐字的;

(1)利用字符值创建 configMap

例如有字符值:spec.level=info和spec.type=charm

[root@master conf]# ku create cm spec-config-1 --from-literal=spec.user01=zhangsan --from-literal=spec.user02=lisi
configmap/spec-config-1 created
(2)查看当前 ConfigMap
[root@master conf]# ku get cm spec-config-1 -o yaml
apiVersion: v1
data:
  spec.user01: zhangsan
  spec.user02: lisi
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T01:14:21Z"
  name: spec-config-1
  namespace: default
  resourceVersion: "11654"
  uid: 4e4013dc-c0b5-476d-9b5b-63e9f689edec

5.删除已创建的ConfigMap

[root@master conf]# ku delete cm spec-config-1
configmap "spec-config-1" deleted

注意:

删除时只需指定要删除的 ConfigMap 的名称。

四、ConfigMap 实践

本实践案例将 CM 创建的变量引入到 pod 内。

在 kubernetes 中,用户可以使用环境变量引用 ConfigMap 中的数据,当容器启动时,kubernetes会将 ConfigMap 数据作为环境变量注入到容器的进程中。为了使用 ConfigMap 中的数据,用户需要在 pod的规范(spec)中定义一个 env 字段,并指定 ConfigMap 中的"键值对"。

1.使用 valueFrom 定义容器的环境变量

(1)先以字符值的形式创建 ConfigMap
[root@master conf]# ku create cm spec-config-2 --from-literal=name1=zhangsan --from-literal=name2=lisi
configmap/spec-config-2 created
(2)查看创建的 ConfigMap
[root@master conf]# ku get cm spec-config-2 -o yaml
apiVersion: v1
data:
  name1: zhangsan
  name2: lisi
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T01:35:02Z"
  name: spec-config-2
  namespace: default
  resourceVersion: "13412"
  uid: 1542a39c-24ec-4e7d-bae4-13942dc117e3
(3)使用valueFrom从ConfigMap中定义变量
vim env-valuefrom.yaml

apiVersion: v1
kind: Pod
metadata:
  name: env-valuefrom
spec:
  containers:
  - name: env-valuefrom
    image: busybox:v1
    command: [ "/bin/sh","-c","env" ]
    env:
    - name: my-name01
      valueFrom:
        configMapKeyRef:
          key: name1
          name: spec-config-2
    - name: my-name02
      valueFrom:
        configMapKeyRef:
          key: name2
          name: spec-config-2
  restartPolicy: Never

在此案例中,env 用于定义环境变量,valueFrom 指定了环境变量的值来源于ConfigMap。 "name:my-name01"用于定义容器中用的变量名,其值来自于 CM 中的 name1 的值。"name1"是在 CM 中定义的 key。

用 valueFrom 的方式引入 pod 中的变量名,可以在定义 pod 的之后指定成另一个名称。相当于在 pod中起了一个新的名字,但是值还是原来 configMap 中给定的值。

(4)创建此 pod
[root@master ~]# ku create -f env-valuefrom.yaml 
pod/env-valuefrom created
(5)查看 pod 日志
[root@master ~]# ku create -f env-valuefrom.yaml 
pod/env-valuefrom created
[root@master ~]# ku logs env-valuefrom
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=env-valuefrom
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
my-name01=zhangsan
my-name02=lisi

2.使用 envFrom 定义容器的环境变量

k8s 从 1.6 的版本开始,引入了一个新的字段 envFrom,实现了在 Pod 中将 configMap 中所有定义的key=value 自动生成为环境变量。

使用 envFrom 时,环境变量的名字是 configMap 中数据的 key 名。

备注:valueFrom和envfrom的区别

通过 valueFrom 来配置环境变量,Pod 的环境变量名与 configMap 中定义的变量名不必相同valueFrom 是指定变量进行映射。

通过 envFrom 会把 configMap 的所有键值对都映射到 Pod 的环境变量中去envFrom 配置的环境变量和 Pod 的环境变量名是相同的

(1)使用envFrom 从 configMap 中定义变量
vim env-envfrom.yaml

apiVersion: v1
kind: Pod
metadata:
  name: env-envfrom
spec:
  containers:
  - name: env-envfrom
    image: busybox:v1
    command: [ "/bin/sh","-c","env" ]
    envFrom:
    - configMapRef:
        name: spec-config-2
  restartPolicy: Never

[root@master ~]# ku describe cm spec-config
Name:         spec-config-2
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
name2:
----
lisi
name1:
----
zhangsan

BinaryData
====

Events:  <none>
(2)创建此pod
[root@master ~]# ku apply -f env-envfrom.yaml 
pod/env-envfrom created
(3)查看pod的日志
[root@master ~]# ku logs env-envfrom
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
name1=zhangsan
HOSTNAME=env-envfrom
name2=lisi
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/

3.以文件的形式挂载 ConfigMap

大部分情况下,ConfigMap 定义的都是配置文件,而不是环境变量,因此需要将 ConfigMap 的文件挂载到 Pod 中,然后 Pod 中的容器就可以引用,此时可以通过 Pod 的 volume 字段进行挂载。

(1)创建测试文件game-properties
[root@master ~]# mkdir /conf
[root@master ~]# cd /conf/
[root@master conf]# echo "this is test01">file01.conf
[root@master conf]# echo "this is test02">file02.conf
(2)使用带有 key 的命令创建 ConfigMap
[root@master ~]# ku create cm spec-config02 --from-file=app1.conf=/conf/file01.conf --from-file=app2.conf=/conf/file02.conf 
configmap/spec-config02 created
(3)查看configMap
[root@master ~]# ku get cm spec-config02 -o yaml
apiVersion: v1
data:
  app1.conf: |
    this is test01
  app2.conf: |
    this is test02
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T01:50:54Z"
  name: spec-config02
  namespace: default
  resourceVersion: "14784"
  uid: 556d8877-29fd-4e26-a4c0-c56644f15336
(4)编写文件,将名为spec-config 的ConfigMap 挂载到容器的/etc/config 目录下
vim dapi-test1-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test1-pod
spec:
  containers:
  - name: dapi-test1-pod
    image: kubeguide/tomcat-app:v1
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: config-volume
      mountPath: /etc/conf
  volumes:
  - name: config-volume
    configMap:
      name: spec-config02
      items:
(5)创建此Pod
[root@master ~]# ku create -f dapi-test1-pod.yaml 
pod/dapi-test1-pod created

注意:

容器的/etc/config 目录会被覆盖掉

(6)查看创建结果
[root@master ~]# ku get pods
NAME             READY   STATUS      RESTARTS   AGE
dapi-test1-pod   1/1     Running     0          20s
env-envfrom      0/1     Completed   0          9m38s
env-valuefrom    0/1     Completed   0          14m
(7)登录容器,查看挂载情况
[root@master ~]# ku exec -it dapi-test1-pod -- bash
root@dapi-test1-pod:/usr/local/tomcat# ls /etc/conf/
app1.conf  app2.conf
root@dapi-test1-pod:/usr/local/tomcat# ls -l /etc/conf/
total 0
lrwxrwxrwx 1 root root 16 Aug 24 01:55 app1.conf -> ..data/app1.conf
lrwxrwxrwx 1 root root 16 Aug 24 01:55 app2.conf -> ..data/app2.conf
root@dapi-test1-pod:/usr/local/tomcat# 
(8)删除Pod
[root@master ~]# ku delete -f dapi-test1-pod.yaml 
pod "dapi-test1-pod" deleted

4.自定义文件名挂载 configMap

很多情况下,需要更改挂载的文件名,可以使用 path 字段指定 configMap 挂载的文件名,比如将文件 app2.conf 挂载到/etc/conf 下,并重命名为 app2.cfg。

(1)编写 Pod 文件
vim dapi-test2-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test2-pod
spec:
  containers:
  - name: dapi-test2-pod
    image: kubeguide/tomcat-app:v1
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: config-volume
      mountPath: /etc/conf
  volumes:
  - name: config-volume
    configMap:
      name: spec-config02
      items:
      - key: app1.conf
        path: app1.cfg
      - key: app2.conf
        path: app2.cfg
(2)创建此 Pod
[root@master ~]# ku create -f dapi-test2-pod.yaml 
pod/dapi-test2-pod created
(3)查看创建结果
[root@master ~]# ku get pods
NAME             READY   STATUS      RESTARTS   AGE
dapi-test2-pod   1/1     Running     0          17s
env-envfrom      0/1     Completed   0          14m
env-valuefrom    0/1     Completed   0          19m
(4)登录容器查看挂载结果
[root@master ~]# ku exec -it dapi-test2-pod -- bash
root@dapi-test2-pod:/usr/local/tomcat# ls -l /etc/conf/
total 0
lrwxrwxrwx 1 root root 15 Aug 24 02:00 app1.cfg -> ..data/app1.cfg
lrwxrwxrwx 1 root root 15 Aug 24 02:00 app2.cfg -> ..data/app2.cfg
root@dapi-test2-pod:/usr/local/tomcat# 
(5)删除Pod
[root@master ~]# ku delete -f dapi-test2-pod.yaml 
pod "dapi-test2-pod" deleted

5.指定挂载的文件权限

(1)编写 Pod 文件,指定文件权限
 vim dapi-test3-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test3-pod
spec:
  containers:
  - name: dapi-test3-pod
    image: kubeguide/tomcat-app:v1
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: config-volume
      mountPath: /etc/conf
  volumes:
  - name: config-volume
    configMap:
      name: spec-config02
      items:
      - key: app1.conf
        path: app1.cfg
        mode: 0644
      - key: app2.conf
        path: app2.cfg
      defaultMode: 0666

备注:

defaultMode:0666 没有设置权限的其他文件默认的权限

(2)创建此 Pod
[root@master ~]# ku create -f dapi-test3-pod.yaml 
pod/dapi-test3-pod created
(3)查看创建结果
[root@master ~]# ku get pods
NAME             READY   STATUS      RESTARTS   AGE
dapi-test3-pod   1/1     Running     0          16s
env-envfrom      0/1     Completed   0          17m
env-valuefrom    0/1     Completed   0          23m
(4)登录容器查看挂载结果
[root@master ~]# ku exec -it dapi-test3-pod -- bash
root@dapi-test3-pod:/usr/local/tomcat# ls -l /etc/conf/
total 0
lrwxrwxrwx 1 root root 15 Aug 24 02:04 app1.cfg -> ..data/app1.cfg
lrwxrwxrwx 1 root root 15 Aug 24 02:04 app2.cfg -> ..data/app2.cfg
root@dapi-test3-pod:/usr/local/tomcat# ls -l /etc/conf/..data
lrwxrwxrwx 1 root root 32 Aug 24 02:04 /etc/conf/..data -> ..2024_08_24_02_04_20.4225963427
root@dapi-test3-pod:/usr/local/tomcat# 
(5)删除此 Pod 和 ConfigMap
[root@master ~]# ku delete -f dapi-test3-pod.yaml 
pod "dapi-test3-pod" deleted

[root@master ~]# ku delete cm spec-config

6.利用 SubPath 解决挂载覆盖的问题

当挂载 ConfigMap 或 Secret 到容器内部时,会覆盖容器中的目录,也就是是说,在容器中的对应的目录中,就只剩下我们挂载进去的文件,此目录中其他的文件都会丢失。从而导致容器无法正常运行。为了解决挂载覆盖的问题,需要使用 SubPath 的方式进行挂载。

(1)创建测试用的配置文件
vim nginx.conf 

user  nginx;
#This is my ngin-config
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  ' -  [] "" '
                        '  "" '
                        '"" ""';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
(2)使用带有 key 的命令创建 configMap
[root@master ~]# ku create cm nginx-config --from-file=nginx.conf=nginx.conf
configmap/nginx-config created
(3)查看configMap
[root@master ~]# ku get cm nginx-config -o yaml
apiVersion: v1
data:
  nginx.conf: |
    user  nginx;
    #This is my ngin-config
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    events {
        worker_connections  1024;
    }
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
        log_format  main  ' -  [] "" '
                            '  "" '
                            '"" ""';
        access_log  /var/log/nginx/access.log  main;
        sendfile        on;
        #tcp_nopush     on;
        keepalive_timeout  65;
        #gzip  on;
        include /etc/nginx/conf.d/*.conf;
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2024-08-24T02:13:52Z"
  name: nginx-config
  namespace: default
  resourceVersion: "16789"
  uid: 2b1298e9-f007-4e55-92ff-3a0945cdac85
(4)创建 Pod 文件,挂载文件
 vim dapi-test4-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test4-pod
spec:
  containers:
  - name: dapi-test4-pod
    image: nginx:1.7.9
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nginx-config
      mountPath: /etc/nginx/nginx.conf
      subPath: nginx.conf
  volumes:
  - name: nginx-config
    configMap:
      name: nginx-config
      items:
      - key: nginx.conf
        path: nginx.conf

备注:

mountPath 表示容器中目录

subPath 表示configmap 中文件的key 名

(5)创建此 Pod
[root@master ~]# ku create -f dapi-test4-pod.yaml 
pod/dapi-test4-pod created
(6)查看创建结果
[root@master ~]# ku get pods
NAME             READY   STATUS      RESTARTS   AGE
dapi-test4-pod   1/1     Running     0          8s
env-envfrom      0/1     Completed   0          31m
env-valuefrom    0/1     Completed   0          36m
(7)登录容器查看挂载结果
[root@master ~]# ku exec -it dapi-test4-pod -- bash
root@dapi-test4-pod:/# cat /etc/nginx/nginx.conf 
user  nginx;
#This is my ngin-config
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  ' -  [] "" '
                        '  "" '
                        '"" ""';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}
root@dapi-test4-pod:/# 
(8)删除此 Pod
[root@master ~]# ku delete -f dapi-test4-pod.yaml 
pod "dapi-test4-pod" deleted

五、configMap 限制

ConfigMap 在使用时有很多的限制,如果没有正确使用 ConfigMap,可能会导致 Pod 不能正常操作,目前具有的限制如下:

1:必须创建 ConfigMap 才能在 Pod 中引用它,如果 Pod 引用的 ConfigMap 不存在,Pod 将无法启动,一直处于 Pending 状态,可以通过 describe 命令查看

2:Pod 引用的键必须存在于 configMap 中,否则 Pod 无法启动,一直处于ContainerCreating 状态可以通过 describe 命令查看査看,

3:使用 envFrom 配置容器环境变量时,默认会跳过被视为无效的键,但是不影响 Pod 的启动,无效的变量会记录在事件日志中。

4:configMap 和引用它的 Pod 需要在同一个命名空间。

六、加密数据管理

上一节讲解的 ConfigMap 主要用于非安全的数据,与其对应的是 Secret 对象类型,用来保存敏感信息,例如密码、令牌或 SSH Key,将这些信息放在 Serret 中比较安全和灵活。用户可以创建 Secret 并且引用到 Pod 中,比如使用 Secre 初始化 Redres、MySQL 密码等。

1.创建secret

创建 Secret 的方式有很多,可以使用命令行工具 Kubectl 或通过 yaml 文件创建。

(1)使用 kubect1 命令行创建 secret

假设有些 Pod 需要访问数据库,可以将账户、密码存储在 username.txt 和 password.txt 文件中,然后以文件的形式创建 Secret 供 Pod 使用。

首先创建账户信息:

[root@master ~]# echo "admin">username.txt
[root@master ~]# cat username.txt 
admin
[root@master ~]# echo "password123">password.txt
[root@master ~]# cat password.txt 
password123

以文件 username.txt 和 password.txt 创建 Secret,创建方式和 ConfigMap 一致:

[root@master ~]# ku create secret generic db-user-pass --from-file=username.txt --from-file=password.txt 
secret/db-user-pass created

备注:

generic:通用

db-user-pass:创建的secret的名字

查看 Secret:

[root@master ~]# ku get secret db-user-pass
NAME           TYPE     DATA   AGE
db-user-pass   Opaque   2      52s

备注:

Opaque 不透明的,表示secret 是加密的形式保存数据的

[root@master ~]# ku describe secrets/db-user-pass
Name:         db-user-pass
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password.txt:  12 bytes
username.txt:  6 bytes

默认情况下,get 和 describe 命令都不会显示文件的内容,这是为了防止 Secret 中的内容被意外暴露。所以,显示出来的信息中 Data 字段没有对应的值,只显示了文件的名字。

(2)通过 yaml文件创建 secret

手动创建 Secret 时,每一项内容必须是 base64 编码的,所以要先对明文进行编码:

[root@master ~]# echo -n "admin"
admin[root@master ~]# echo -n "admin" | base64
YWRtaW4=
[root@master ~]# echo -n "pwd123" | base64
cHdkMTIz

然后创建一个 yaml文件,格式如下:

vim db-user-secret.yaml 

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: bXlwYXNzd29yZA==

备注:

Opaque:不透明的

最后使用该文件创建一个 Secret:

[root@master ~]# ku create -f db-user-secret.yaml 
secret/mysecret created

2.解码 secret

[root@master ~]# ku get secret mysecret -o yaml
apiVersion: v1
data:
  password: bXlwYXNzd29yZA==
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: "2024-08-24T02:35:03Z"
  name: mysecret
  namespace: default
  resourceVersion: "18630"
  uid: 96e8cfd5-d7c5-4841-b0cf-e404f7be3c58
type: Opaque

[root@master ~]# echo "bXlwYXNzd29yZA==" | base64 --decode
mypassword[root@master ~]# 

3.在 pod 中应用 secret

secret 和 ConfigMap 的用法类似,也可以作为数据卷挂载,或作为环境变量以供 Pod 的容器使用。

和 ConfigMap 一样,可以在 Pod 的 volume 中使用 Secret:

vim secret-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: nginx:1.7.9
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

[root@master ~]# ku create -f secret-pod.yaml 
pod/mypod created

查看Pod中的信息

[root@master ~]# ku exec -it mypod /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls /etc/foo 
password  username
# cat /etc/foo/username
admin# 
# cat /etc/foo/password
mypassword# 
# 
相关推荐
运维小文1 分钟前
K8S资源限制之LimitRange
云原生·容器·kubernetes·k8s资源限制
登云时刻2 分钟前
Kubernetes集群外连接redis集群和使用redis-shake工具迁移数据(二)
redis·容器·kubernetes
wuxingge9 小时前
k8s1.30.0高可用集群部署
云原生·容器·kubernetes
志凌海纳SmartX10 小时前
趋势洞察|AI 能否带动裸金属 K8s 强势崛起?
云原生·容器·kubernetes
锅总10 小时前
nacos与k8s service健康检查详解
云原生·容器·kubernetes
BUG弄潮儿10 小时前
k8s 集群安装
云原生·容器·kubernetes
Code_Artist11 小时前
Docker镜像加速解决方案:配置HTTP代理,让Docker学会科学上网!
docker·云原生·容器
何遇mirror11 小时前
云原生基础-云计算概览
后端·云原生·云计算
颜淡慕潇12 小时前
【K8S系列】kubectl describe pod显示ImagePullBackOff,如何进一步排查?
后端·云原生·容器·kubernetes
Linux运维日记12 小时前
k8s1.31版本最新版本集群使用容器镜像仓库Harbor
linux·docker·云原生·容器·kubernetes