configmap,Secret

发布时间 2023-06-01 16:34:25作者: XIN-0808

ConfigMap

ConfigMap概述

ConfigMap 用于保存非机密性的配置,通常用来管理应用的配置文件或者环境变量,数据可以用 key/value 键值对的形式保存,也可通过文件的形式保存。

ConfigMap创建方法

命令行创建

直接在命令行中指定 configmap 参数创建,通过--from-literal 指定参数

[root@master config]# kubectl create configmap nginx-config --from-literal=nginx_prot=80 --from-literal=path=/etc/nginx/html
configmap/nginx-config created

查看ConfigMap

[root@master config]# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      29d
nginx-config       2      118s
[root@master config]# kubectl describe cm nginx-config
Name:         nginx-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx_prot:
----
80
path:
----
/etc/nginx/html
Events:  <none>

通过文件/目录创建

通过指定文件创建一个 configmap,--from-env-file=<文件>

[root@master config]# cat mysql.txt 
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
[root@master config]# kubectl create configmap mysql-config --from-env-file=mysql.txt 
configmap/mysql-config created

查看ConfigMap

[root@master config]# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      29d
mysql-config       2      6s
nginx-config       2      7m50s
[root@master config]# kubectl describe cm mysql-config 
Name:         mysql-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
MYSQL_HOST:
----
127.0.0.1
MYSQL_PORT:
----
3306
Events:  <none>

yaml创建

[root@master config]# cat configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf
  namespace: default
data:
  nginx.conf: |
    server {
      server_name www.nginx.com;
      listen 80;
      root /home/nginx/www/
    }
[root@master config]# kubectl create -f configmap.yaml 
configmap/nginx-conf created	

查看ConfigMap

[root@master config]# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      29d
mysql-config       2      9m40s
nginx-conf         1      5s
nginx-config       2      17m
[root@master config]# kubectl describe cm nginx-conf
Name:         nginx-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx.conf:
----
server {
  server_name www.nginx.com;
  listen 80;
  root /home/nginx/www/
}

Events:  <none>

ConfigMap的使用

Pod的使用方式:

  • 将ConfigMap中的数据设置为容器的环境变量
  • 将ConfigMap中的数据设置为命令行参数
  • 使用Volume将ConfigMap作为文件或目录挂载
  • 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

案例:

#创建pod,将configmap加到环境变量中
[root@master config]# cat pod-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx-cm
  namespace: default
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    env:
    - name: nginx_prot          #pod中变量名
      valueFrom:
        configMapKeyRef:
          name: nginx-config    #ConfigMap名称
          key: nginx_prot       #ConfigMap中key名称
    - name: path
      valueFrom:
        configMapKeyRef:
          name: nginx-config
          key: path
[root@master config]# kubectl create -f pod-configmap.yaml
pod/nginx-cm created
#查看pod中的环境变量
[root@master config]# kubectl get pod nginx-cm 
NAME       READY   STATUS    RESTARTS   AGE
nginx-cm   1/1     Running   0          11s
[root@master config]# kubectl exec nginx-cm  env 
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-cm
path=/etc/nginx/html
nginx_prot=80
NGINX_TEST1_SVC_PORT=tcp://10.104.50.60:80
NGINX_TEST1_SVC_PORT_80_TCP=tcp://10.104.50.60:80
NGINX_TEST2_SVC_PORT_80_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_TEST1_SVC_SERVICE_HOST=10.104.50.60
NGINX_TEST1_SVC_SERVICE_PORT=80
NGINX_TEST1_SVC_SERVICE_PORT_HTTP=80
NGINX_TEST1_SVC_PORT_80_TCP_PORT=80
NGINX_TEST2_SVC_SERVICE_HOST=10.103.247.30
NGINX_TEST2_SVC_SERVICE_PORT=80
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
NGINX_TEST2_SVC_SERVICE_PORT_HTTP=80
NGINX_TEST2_SVC_PORT_80_TCP=tcp://10.103.247.30:80
NGINX_TEST2_SVC_PORT_80_TCP_PORT=80
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
NGINX_TEST1_SVC_PORT_80_TCP_PROTO=tcp
NGINX_TEST2_SVC_PORT=tcp://10.103.247.30:80
KUBERNETES_SERVICE_PORT=443
NGINX_TEST1_SVC_PORT_80_TCP_ADDR=10.104.50.60
NGINX_TEST2_SVC_PORT_80_TCP_ADDR=10.103.247.30
NGINX_VERSION=1.21.5
NJS_VERSION=0.7.1
PKG_RELEASE=1~bullseye
HOME=/root

ConfigMap挂载

注意:
整个configmap文件直接挂载到pod中,若configmap变化,pod会自动感知并拉取到pod内部,但是pod内的进程不会自动重启。

单文件挂载到空目录

[root@master config]# kubectl describe cm nginx-conf
Name:         nginx-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx.conf:
----
server {
  server_name www.nginx.com;
  listen 80;
  root /home/nginx/www/
}

Events:  <none>
[root@master config]# cat pod-configmap-vol.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx-cm-vol
  namespace: default
spec:
  volumes:
  - configMap:
      name: nginx-conf    #configmap名称
    name: config
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    volumeMounts:
    - mountPath: "/etc/config"  #挂载容器目录
      name: config
[root@master config]# kubectl create -f pod-configmap-vol.yaml
pod/nginx-cm-vol created
[root@master config]# kubectl get pod nginx-cm-vol 
NAME           READY   STATUS    RESTARTS   AGE
nginx-cm-vol   1/1     Running   0          10s
[root@master config]# kubectl exec nginx-cm-vol  cat /etc/config/nginx.conf
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
server {
  server_name www.nginx.com;
  listen 80;
  root /home/nginx/www/
}

多文件挂载

创建configmap

[root@master configmap]# cat config1.conf 
user=test1
passwd=12345
[root@master configmap]# cat config2.conf 
user=test2
passwd=4567
[root@master configmap]# kubectl create configmap test-conf --from-file=config1.conf --from-file=config2.conf 
configmap/test-conf created
[root@master configmap]# kubectl get configmap test-conf 
NAME        DATA   AGE
test-conf   2      13s
[root@master configmap]# kubectl describe configmap test-conf 
Name:         test-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
config2.conf:
----
user=test2
passwd=4567

config1.conf:
----
user=test1
passwd=12345

Events:  <none>

创建deployment挂载

[root@master configmap]# cat demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  namespace: default
spec:
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      volumes:
      - configMap:
          name: test-conf
        name: config
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: "/tmp"
          name: config
[root@master configmap]# kubectl create -f demo.yaml
deployment.apps/demo created
[root@master configmap]# kubectl get deploy
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
demo         1/1     1            1           8s
[root@master configmap]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
demo-dcff5b456-l8v9j         1/1     Running   0          17s
[root@master configmap]# kubectl exec -it demo-dcff5b456-l8v9j -- /bin/bash
root@demo-dcff5b456-l8v9j:/# ls -l /tmp/
total 0
lrwxrwxrwx 1 root root 19 Jun  1 08:15 config1.conf -> ..data/config1.conf
lrwxrwxrwx 1 root root 19 Jun  1 08:15 config2.conf -> ..data/config2.conf
root@demo-dcff5b456-l8v9j:/# cat /tmp/config1.conf 
user=test1
passwd=12345
root@demo-dcff5b456-l8v9j:/# cat /tmp/config2.conf  
user=test2
passwd=4567

挂载子路径

[root@master configmap]# kubectl describe configmaps  test-conf 
Name:         test-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
config1.conf:
----
user=test1
passwd=12345

config2.conf:
----
user=test2
passwd=4567

Events:  <none>
[root@master configmap]# cat demo2.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo2
  namespace: default
spec:
  selector:
    matchLabels:
      app: demo2
  template:
    metadata:
      labels:
        app: demo2
    spec:
      volumes:
      - name: config
        configMap:
          name: test-conf
          items:
          - key: config1.conf
            path: config1
          - key: config2.conf
            path: config2
      containers:
      - name: nginx2
        image: nginx
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: "/tmp/config1.conf"
          name: config
          subPath: config1
        - mountPath: "/etc/config2.conf"
          name: config
          subPath: config2
[root@master configmap]# kubectl delete -f demo2.yaml
deployment.apps "demo2" deleted
[root@master configmap]# kubectl create -f demo2.yaml
deployment.apps/demo2 created
[root@master configmap]# kubectl get deploy
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
demo         1/1     1            1           8m11s
demo2        1/1     1            1           6s
[root@master configmap]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
demo-dcff5b456-l8v9j         1/1     Running   0          8m15s
demo2-58998cc654-tlbr4       1/1     Running   0          10s
[root@master configmap]# kubectl exec -it demo2-58998cc654-tlbr4 
error: you must specify at least one command for the container
[root@master configmap]# kubectl exec -it demo2-58998cc654-tlbr4 -- /bin/bash
root@demo2-58998cc654-tlbr4:/# ls -l /tmp/config1.conf 
-rw-r--r-- 1 root root 24 Jun  1 08:23 /tmp/config1.conf
root@demo2-58998cc654-tlbr4:/# ls -l /etc/config2.conf 
-rw-r--r-- 1 root root 23 Jun  1 08:23 /etc/config2.conf
root@demo2-58998cc654-tlbr4:/# cat /tmp/config1.conf 
user=test1
passwd=12345
root@demo2-58998cc654-tlbr4:/# cat /etc/config2.conf 
user=test2
passwd=4567

修改ConfigMap

[root@master config]# kubectl edit cm nginx-conf
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  nginx.conf: |
    server {
      server_name www.nginx.com;
      listen 8080;
      root /home/nginx/www/
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2023-05-25T08:29:22Z"
  name: nginx-conf
  namespace: default
  resourceVersion: "90828"
  selfLink: /api/v1/namespaces/default/configmaps/nginx-conf
  uid: 8a7db3b3-7dc2-4f82-9aee-297d2c7f6b62
#修改完后,大概30秒再查看pod内挂载的配置文件
[root@master config]# kubectl exec nginx-cm-vol -- cat /etc/config/nginx.conf
server {
  server_name www.nginx.com;
  listen 8080;
  root /home/nginx/www/
}

Secret

概述

k8s secrets用于存储和管理一些敏感数据,比如密码,token,密钥等敏感信息。它把 Pod 想要访问的加密数据存放到 Etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。
Secret 可选参数有三种:

  • generic: 通用类型,通常用于存储密码数据。
  • tls:此类型仅用于存储私钥和证书。
  • docker-registry: 若要保存 docker 仓库的认证信息的话,就必须使用此种类型来创建。

Secret有三种类型:

  • Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;创建ServiceAccount后,Pod中指定serviceAccount后,自动创建该ServiceAccount对应的secret;
  • Opaque : base64编码格式的Secret,用来存储密码、密钥等,可以通过 base64 --decode 解码获得原始数据,因此安全性弱。
  • kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息。

Secret创建方法

命令行创建

键值对创建

[root@master ~]# kubectl create secret generic user --from-literal=username=test
secret/user created
[root@master ~]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-w4jbn   kubernetes.io/service-account-token   3      35d
user                  Opaque                                1      8s
[root@master ~]# kubectl describe secrets user 
Name:         user
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
username:  4 bytes
[root@master ~]# kubectl get secrets user  -o yaml
apiVersion: v1
data:
  username: dGVzdA==
kind: Secret
metadata:
  creationTimestamp: "2023-05-31T08:07:46Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:username: {}
      f:type: {}
    manager: kubectl-create
    operation: Update
    time: "2023-05-31T08:07:46Z"
  name: user
  namespace: default
  resourceVersion: "112981"
  selfLink: /api/v1/namespaces/default/secrets/user
  uid: 7076bbf2-7769-494f-abfc-b576c9956e62
type: Opaque
[root@master ~]# echo "dGVzdA=="|base64 --decode
test

本地文件、目录创建(默认情况下key为文件名)

[root@master secrets]# cat user.txt 
admin
[root@master secrets]# kubectl create secret generic username --from-file=user.txt 
secret/username created
[root@master secrets]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-w4jbn   kubernetes.io/service-account-token   3      35d
user                  Opaque                                1      4m27s
username              Opaque                                1      9s
[root@master secrets]# kubectl get secrets username -o yaml
apiVersion: v1
data:
  user.txt: YWRtaW4K
kind: Secret
metadata:
  creationTimestamp: "2023-05-31T08:12:04Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:user.txt: {}
      f:type: {}
    manager: kubectl-create
    operation: Update
    time: "2023-05-31T08:12:04Z"
  name: username
  namespace: default
  resourceVersion: "113472"
  selfLink: /api/v1/namespaces/default/secrets/username
  uid: e89aa43d-77aa-4557-850c-17e1bf4388d4
type: Opaque
[root@master secrets]# echo YWRtaW4K|base64 --decode
admin

yaml创建

通过yaml创建Opaque类型的Secret值需要base64编码

[root@master secrets]# cat passwd.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: password
  namespace: default
type: Opaque
data:
  password: MTIzNDU2  #echo -n 123456|base64加密生成
[root@master secrets]# kubectl create -f passwd.yaml
secret/password created
[root@master secrets]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-w4jbn   kubernetes.io/service-account-token   3      35d
password              Opaque                                1      14s
user                  Opaque                                1      16m
username              Opaque                                1      12m
[root@master secrets]# kubectl describe secrets password 
Name:         password
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes
[root@master secrets]# kubectl get secrets -o yaml password 
apiVersion: v1
data:
  password: MTIzNDU2
kind: Secret
metadata:
  creationTimestamp: "2023-05-31T08:24:13Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:password: {}
      f:type: {}
    manager: kubectl-create
    operation: Update
    time: "2023-05-31T08:24:13Z"
  name: password
  namespace: default
  resourceVersion: "114883"
  selfLink: /api/v1/namespaces/default/secrets/password
  uid: a574afca-5251-44f6-a198-b792005ad7a4
type: Opaque
[root@master secrets]# echo MTIzNDU2|base64 --decode
123456

Secret使用

通过Volume挂载的方式

挂载后key为文件名,value为文件内容
通过Volume挂载到容器内部时,当该Secret的值发生变化时,容器内部具备自动更新的能力,但是通过环境变量设置到容器内部该值不具备自动更新的能力。所以一般推荐使用Volume挂载的方式使用Secret

[root@master secrets]# cat test-secret-volume.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-projected-volume 
spec:
  containers:
  - name: test-secret-volume
    image: busybox
    args:
    - sleep
    - "86400"
    volumeMounts:
    - name: test-secret
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: test-secret
    projected:
      sources:
      - secret:
          name: username
      - secret:
          name: password
[root@master secrets]# kubectl create -f test-secret-volume.yaml
pod/test-projected-volume created
[root@master secrets]# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
nfs-pvc-6fb4755795-74v9d     1/1     Running   1          7d23h
nfs-pvc-6fb4755795-h7wcl     1/1     Running   2          7d23h
nginx-cm                     1/1     Running   1          6d
nginx-cm-vol                 1/1     Running   1          5d23h
nginx-hpa-b9fb96f5c-7n8dx    1/1     Running   0          47h
nginx-hpa-b9fb96f5c-kb4l9    1/1     Running   0          47h
nginx-hpa-b9fb96f5c-qw8sb    1/1     Running   0          47h
php-apache-fc47b9cd7-khgvt   1/1     Running   0          2d
test-projected-volume        1/1     Running   0          24s
[root@master secrets]# kubectl exec -it test-projected-volume -- /bin/sh
/ # ls
bin               dev               etc               home              proc              projected-volume  root              sys               tmp               usr               var
/ # cd projected-volume/
/projected-volume # ls -l
total 0
lrwxrwxrwx    1 root     root            15 May 31 08:40 password -> ..data/password
lrwxrwxrwx    1 root     root            15 May 31 08:40 user.txt -> ..data/user.txt
/projected-volume # cat user.txt 
admin
/projected-volume # cat password 
123456

环境变量方式

[root@master secrets]# cat test-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: default
type: Opaque
data:
  username: YWRtaW4=  #echo -n admin|base64加密生成
  password: MTIzNDU2  #echo -n 123456|base64加密生成
[root@master secrets]# kubectl create -f test-secret.yaml
secret/mysecret created
[root@master secrets]# kubectl describe secrets mysecret 
Name:         mysecret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes
username:  5 bytes
[root@master secrets]# cat test-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-projected-env 
spec:
  containers:
  - name: test-secret-env
    image: busybox
    args:
    - sleep
    - "86400"
    env:
    - name: SECRET_USERNAME
      valueFrom:
        secretKeyRef:
          name: mysecret
          key: username
    - name: SECRET_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysecret
          key: password
[root@master secrets]# kubectl create -f test-secret-env.yaml
pod/test-projected-env created
[root@master secrets]# kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
nfs-pvc-6fb4755795-74v9d     1/1     Running   1          8d
nfs-pvc-6fb4755795-h7wcl     1/1     Running   2          8d
nginx-cm                     1/1     Running   1          6d1h
nginx-cm-vol                 1/1     Running   1          6d1h
nginx-hpa-b9fb96f5c-7n8dx    1/1     Running   0          2d
nginx-hpa-b9fb96f5c-kb4l9    1/1     Running   0          2d
nginx-hpa-b9fb96f5c-qw8sb    1/1     Running   0          2d
php-apache-fc47b9cd7-khgvt   1/1     Running   0          2d1h
test-projected-env           1/1     Running   0          49s
test-projected-volume        1/1     Running   0          91m
[root@master secrets]# kubectl exec -it test-projected-env -- /bin/sh
/ # env|grep SECRET
SECRET_PASSWORD=123456
SECRET_USERNAME=admin

总结

最后我们来对比下Secret和ConfigMap这两种资源对象的异同点:

相同点:

  • key/value的形式
  • 属于某个特定的namespace
  • 可以导出到环境变量
  • 可以通过目录/文件形式挂载
  • 通过 volume 挂载的配置信息均可热更新

不同点:

  • Secret 可以被 ServerAccount 关联
  • Secret 可以存储 docker register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像
  • Secret 支持 Base64 加密
  • Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型