【Kubernetes系列九】Kubernetes ConfigMap和Secret

1. ConfigMap介绍

ConfigMap是让配置文件从镜像中解耦,让镜像的可移植性和可复制性。许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。这些配置信息需要与docker image解耦,你总不能每修改一个配置就重做一个image吧?ConfigMap API给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。ConfigMap保存的值为键值方式,value长度没有限制。
注意:configmap是名称空间级别的资源,它必须与引用它的pod资源在同一空间中

2. 创建ConfigMap

ConfigMap支持命令创建和使用清单创建。有以下四种方式创建。

(1) 命令直接创建
为“kubectl create configmap”命令使用"--from-literal"选项可在命令行直接给出键值来创建ConfigMap对象,重复使用此选项可以传递多个键值对。格式如下:

~]# kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2

示列:

~]# kubectl create configmap nginx-config --from-literal=nginx_port=80 --from-literal=server_name=www.ilinux.cn
~]# kubectl get cm    #查看cm资源
NAME           DATA   AGE
nginx-config   2      4s
~]# kubectl describe cm/nginx-config    #查看cm资源nginx-config的详细信息
或者~]# kubectl get configmaps nginx-config -o yaml

(2) 基于文件创建
“kubectl create configmap”命令使用“--from-file”选项即可基于文件内容来创建ConfigMap对象,同样可以重复多次使用。格式如下:

~]# kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt

示列:

~]# mkdir configmap && cd configmap
~]# vim www.conf
server {
    server_name www.ilinux.cn;
    listen 80;
    root /data/web/html/;
}

~]# kubectl create configmap nginx-www --from-file=www.conf=./www.conf    #使用上面创建的文件来创建cm资源对象
~]# kubectl get cm
~]# kubectl get cm nginx-www -o yaml
apiVersion: v1
data:
  www.conf: |
    server {
        server_name www.ilinux.cn;
        listen 80;
        root /data/web/html/;
    }
kind: ConfigMa
......

(3) 基于目录创建
如果配置文件数量较多且存储于有限的目录之中,kubectl还提供了基于目录直接将多个文件分别收纳为键值数据的ConfigMap资源创建方式。将“--from-file”选项后面所跟的路径指向一个目录路径就能将目录下的所有文件一同创建于同一ConfigMap资源中,命令格式如下:

~]# kubectl create configmap <configmap_name> --from-file=<path-to-directory>

这里假设/data/configs/nginx/conf.d/这个目录下有许多的nginx的配置文件,下面这条命令则将这个目录下的所有配置文件在创建ConfigMap资源时,会分别存储为对应的键值数据。

~]# kubectl create configmap nginx-config-files --from-file=/data/configs/nginx/conf.d/

(4) 使用资源清单创建
基于清单文件创建ConfigMap资源时,它所使用的字段包括通常的apiVersion、kind和metadata字段,以及用于存储数据的关键字段“data”。格式如下:

~]# kubectl explain cm
KIND:     ConfigMap
VERSION:  v1
FIELDS:
apiVersion    <string>
kind    <string>
metadata    <Object>
binaryData    <map[string]string>
data    <map[string]string>

示列:

~]# vim configmap-demo.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap-demo
  namespace: default
data:
  log_level: INFO
  log_file: /var/log/test.log

~]# kubectl apply -f configmap-demo.yaml 
~]# kubectl get cm
~]# kubectl get cm/configmap-demo -o yaml
apiVersion: v1
data:
  log_file: /var/log/test.log
  log_level: INFO
kind: ConfigMap
metadata:
......

3. 使用ConfigMap

(1) 环境变量方式注入到pod

~]# vim pod-configmap-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-1
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    env:
    - name: NGINX_SERVER_PORT
      valueFrom:    #下面这一段表示变量NGINX_SERVER_PORT的值来自于configmap资源nginx-config的key(nginx_port)的值
        configMapKeyRef:
          name: nginx-config    #configmap资源名称
          key: nginx_port      #configmap资源里面的key名
    - name: NGINX_SERVER_NAME
      valueFrom:
        configMapKeyRef:
          name: nginx-config
          key: server_name
~]# kubectl apply -f pod-configmap-1.yaml
~]# kubectl get pods
~]# kubectl exec -it pod-cm-1 -- printenv |grep NGINX    #连接pod资源pod-cm-1并执行命令printenv打印环境变量。过滤是否有上面定义的两个环境变量
NGINX_SERVER_PORT=80
NGINX_SERVER_NAME=www.ilinux.cn


#测试,修改端口,可以发现使用环境变量的注入pod中的端口不会根据配置的变更而改变
[root@k8s-master configmap]# kubectl edit cm/nginx-config   #编辑cm资源nginx-config将nginx_port值改为8080
......
apiVersion: v1
data:
  nginx_port: "8080"
......
[root@k8s-master configmap]# kubectl exec -it pod-cm-1 -- printenv |grep NGINX
NGINX_SERVER_PORT=80
NGINX_SERVER_NAME=www.ilinux.cn

上述存在键值数据不多,如果键值数据过多,可以直接使用envFrom字段导入configmap,上述示列可以修改如下

~]# vim pod-configmap-1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-1
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    envFrom:
    - prefix: HTCFG_     #防止导入多个configmap,出现键值重复,设定前缀
      configMapKeyRef:
        name: nginx-config
        optional: false

(2) 存储卷方式挂载ConfigMap

~]# vim pod-configmap-2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-2
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: nginxconf
      mountPath: /etc/nginx/config.d/
      readOnly: true
  volumes:    #创建一个存储卷
  - name: nginxconf    #存储卷名称
    configMap:    #使用configMap类型
      name: nginx-config    #指定configmap资源名称
]# kubectl apply -f pod-configmap-2.yaml
]# kubectl get pods
]# kubectl exec -it pod-cm-2 -- /bin/sh    #连接pod资源pod-cm-2,并进入到挂载目录查看。
/ # ls /etc/nginx/config.d/
nginx_port   server_name
/ # cd /etc/nginx/config.d/
/etc/nginx/config.d # cat nginx_port 
8080
/etc/nginx/config.d # cat server_name 
www.ilinux.cn 

#测试,修改端口,可以发现使用volume的方式挂载configmap到容器中,支持动态更新。
[root@k8s-master configmap]# kubectl edit cm/nginx-config    #编辑cm资源nginx-config将nginx_port值改为8088
apiVersion: v1
data:
  nginx_port: "8088"
[root@k8s-master configmap]# kubectl exec -it pod-cm-2 -- /bin/sh
/etc/nginx/config.d # cat nginx_port 
8088

当然,除了上述挂载整个存储卷,还可以挂载存储卷中的部分键值,独立挂载存储卷中的键值,配置如下
挂载存储卷中的部分键值

~]# vim pod-configmap-3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-3
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: nginxconf
      mountPath: /etc/nginx/config.d/
      readOnly: true
  volumes:    #创建一个存储卷
    - name: nginxconf    #存储卷名称
    configMap:    #使用configMap类型
        name: nginx-config    #指定configmap资源名称
        items:
        - key: myserver.conf
        path: myserver.conf
        mode: 644

独立挂载存储卷中的键值

~]# vim pod-configmap-4.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-4
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: nginxconf
      mountPath: /etc/nginx/config.d/myserver.conf
      subpath: myserver.conf
      readOnly: true
  volumes:    #创建一个存储卷
  - name: nginxconf    #存储卷名称
    configMap:    #使用configMap类型
        name: nginx-config    #指定configmap资源名称

4. Secret资源介绍

Secret对象存储数据的方式及使用方式类似于ConfigMap对象,以键值方式存储数据,在Pod资源中通过环境变量或存储卷进行数据访问,解决了密码、token、密钥等敏感数据的配置问题,而不需要将这些敏感数据暴露到镜像或者pod spec中。另外,Secret对象的数据存储和打印格式为Base64编码的字符串,因此用户在创建Secret对象时也要提供此种编码格式的数据。在容器中以环境变量或存储卷的方式访问时,它们会被自动解码为明文格式。需要注意的是,如果是在Master节点上,Secret对象以非加密的格式存储在etcd中,所以需要对etcd的管理和权限进行严格控制。

Secret的四种类型

Opaque: 自定义数据内容;base64编码,用来存储密码、秘钥、信息、证书等数据,类型标识符为generic。

kubernetes.io/service-account-token: Service Account的认证信息,可在创建Service Account`时由Kubernetes自动创建。

kubernetes.io/dockerconfigjson: 用来存储Docker镜像仓库的认证信息,类型标识符为docker-regiestry。

kubernetes.io/tls: 用于为SSL通信模式存储证书和私钥文件,命令式创建时类型标识为tls。

5.创建Secret

(1) 命令式创建
为“kubectl create secret generic”命令使用“--from-literal”选项可在命令行直接给出键值来创建ConfigMap对象,重复使用此选项可以传递多个键值对。格式如下:

~]# kubectl create secret generic NAME --from-literal=key1=value1 --from-literal=key2=value2

示列:

~]# kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=password=passw0rd    #创建secret资源mysql-auth,并指定两个键值
~]# kubectl get secret     #查看secret资源
NAME                  TYPE                                  DATA   AGE
default-token-tnwkb   kubernetes.io/service-account-token   3      110d
mysql-auth            Opaque                                2      17s
~]# kubectl describe secret/mysql-auth 
Name:         mysql-auth
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  8 bytes
username:  4 bytes

(2) 基于文件创建
为“kubectl create secret generic”命令使用“--from-file”选项即可基于文件内容来创建ConfigMap对象,同样可以重复多次使用。格式如下:

~]# kubectl create secret generic my-secret --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt

示列:

~]# mkdir secret && cd secret
~]# echo -n admin > ./username
~]# echo -n 123456 > ./password
~]# kubectl create secret generic mysecret --from-file=username=./username --from-file=password=./password
secret/mysecret created
~]# kubectl get secret 
NAME                  TYPE                                  DATA   AGE
default-token-blm9l   kubernetes.io/service-account-token   3      3d
mysecret              Opaque                                2      6s
mysql-auth            Opaque                                2      5m23s
~]# kubectl get secret/mysecret -o yaml
apiVersion: v1
data:
  password: MTIzNDU2    #这里可以看到secret存储的值都是base64编码格式
  username: YWRtaW4=
kind: Secret
metadata
......

(3) 使用资源清单创建
Secret资源是标准的Kubernetes API对象,除了标准的apiVersion、kind和metadata字段,它可用的其他字段如下:

data    <map[string]string>    #"key:value"格式的数据,通常是敏感信息,数据格式需要以Base64格式编码的字符串,因此需要事先完成编码
stringData    <map[string]string>    #以明文格式(非Base64编码)定义的“key:value"数据;无须事先对数据进行Base64编码,而是在创建为Secret对象时自动进行编码并保存于data字段中。
type    <string>    #仅是为了便于编程方式处理Secret数据而提供的类型标识。

示列:

~]# vim secret-demo.yaml
apiVersion: v1
kind: Secret
metadata:
  name: secret-demo
  namespace: default
stringData:
  username: redis
  password: redisP@ss
type: Opaque
~]# kubectl apply -f secret-demo.yaml 
~]# kubectl get secret
~]# kubectl get secret/secret-demo -o yaml
apiVersion: v1
data:
  password: cmVkaXNQQHNz
  username: cmVkaXM=
kind: Secret
metadata:
......

6.使用secret

类似于Pod消费ConfigMap对象的方式,Secret对象可以注入为环境变量,也可以存储为存储卷形式挂载使用。因为Secret默认保存的是非明文格式,通过注入为环境变量实为不明智。

存储卷方式示例:
(1) 创建私钥和自签证书

~]# openssl genrsa -out nginx.key 2048
~]# openssl req -new -x509 -key nginx.key -out nginx.crt -subj /C=CN/ST=ShenZhen/L=ShenZhen/O=DevOps/CN=www.ilinux.cn

(2) 创建secret

]# kubectl create secret tls nginx-ssl --key=./nginx.key --cert=./nginx.crt 
]# kubectl get secret nginx-ssl

(3) 创建pod使用secret

~]# vim pod-secret-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-demo
  namespace: default
spec:
  containers:
  - name: web-server
    image: nginx:1.12
    volumeMounts:
    - name: nginxcert
      mountPath: /etc/nginx/ssl/
      readOnly: true
  volumes:
  - name: nginxcert
    secret:
      secretName: nginx-ssl

~]# kubectl apply -f pod-secret-demo.yaml 
~]# kubectl exec -it secret-volume-demo -- /bin/sh
# ls /etc/nginx/ssl
tls.crt  tls.key
posted @   彬彬l  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示