linux运维、架构之路-K8s Secret & Configmap

一、介绍

       应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名、密码或者秘钥等。这些信息保存在镜像中不太好。Secret会以密文方式存储数据,避免直接在配置文件中保存敏感信息,Secret会以Volume的形式被mount到Pod,容器通过文件的方式使用Secret中的敏感数据;此外,容器也可以通过环境变量的方式使用这些数据。

二、Secret

1、创建Secret

①通过 --from-litera

kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
[root@k8s-node1 ~]# kubectl get secret 
NAME                  TYPE                                  DATA      AGE
default-token-ff5wq   kubernetes.io/service-account-token   3         13d
mysecret              Opaque                                2         6s

②通过 --from-file

kubectl create secret generic mysecret --from-file=./username --from-file=./password

③通过 --from-env-file

[root@k8s-node1 ~]# cat <<EOF >env.txt
> username=admin
> password=123456
> EOF
[root@k8s-node1 ~]# cat env.txt 
username=admin
password=123456
[root@k8s-node1 ~]# kubectl create secret generic mysecret --from-env-file=env.txt

④通过YAML配置文件

#文件中的敏感数据通过base64编码后#
[root@k8s-node1 ~]# echo -n admin|base64
YWRtaW4=
[root@k8s-node1 ~]# echo -n 123456|base64
MTIzNDU2
[root@k8s-node1 ~]# cat mysecret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
data:
  username: YWRtaW4=
  password: MTIzNDU2

⑤创建查看

[root@k8s-node1 ~]# kubectl apply -f mysecret.yaml 
secret "mysecret" created
[root@k8s-node1 ~]# kubectl get secret mysecret 
NAME       TYPE      DATA      AGE
mysecret   Opaque    2         1m
[root@k8s-node1 ~]# kubectl describe secret mysecret 
Name:         mysecret
Namespace:    default
Labels:       <none>
Annotations:  
Type:         Opaque

Data
====
password:  6 bytes
username:  5 bytes

⑥通过base64将Value反编码

[root@k8s-node1 ~]# echo -n YWRtaW4=|base64 --decode
admin[root@k8s-node1 ~]# echo -n MTIzNDU2|base64 --decode
123456[root@k8s-node1 ~]# 

三、在Pod中使用Secret

        Pod可以通过Volume或者环境变量的方式使用Secret。

1、Volume方式

①创建Pod并在容器中读取Secret

[root@k8s-node1 ~]# cat mypod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy;sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo" #将foo mount到容器路径/etc/foo,权限为readOnly
      readOnly: true
  volumes:
  - name: foo   #定义volume foo,来源为secret mysecret
    secret:
      secretName: mysecret

创建并进到容器中查看

[root@k8s-node1 ~]# kubectl apply -f mypod.yaml 
pod "mypod" created
[root@k8s-node1 ~]# kubectl exec -it mypod /bin/sh
/ # ls /etc/foo
password  username
/ # cat /etc/foo/username
admin/ # cat /etc/foo/password
123456/ #

结果:k8s会在指定的路径/etc/foo下为每条敏感数据创建一个文件,以明文存放在文件中,存放数据的文件名可以自定义

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy;sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username
      - key: password
        path: my-group/my-password

以上自定义数据分别存放在/etc/foo/my-group/my-username和/etc/foo/my-group/my-password中,以Volume方式使用的secret支持动态更新,Secret更新后,容器中的数据也会更新。

②动态更新Secret测试

#将password更新为abcdef
[root@k8s-node1 ~]# echo -n abcdef|base64
YWJjZGVm
[root@k8s-node1 ~]# cat mysecret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
data:
  username: YWRtaW4=
  password: YWJjZGVm

创建几秒钟后查看

[root@k8s-node1 ~]# kubectl apply -f mysecret.yaml 
secret "mysecret" configured
[root@k8s-node1 ~]# kubectl exec -it mypod /bin/sh
/ # cat /etc/foo/password
abcdef/ # 

2、环境变量方式

        通过Volume使用Secret,容器必须从文件读取数据,k8s还支持通过环境变量使用Secret。

①Pod配置文件

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy;sleep 30000
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password

②创建Pod并读取Secret

[root@k8s-node1 ~]# kubectl apply -f mypod-env.yaml 
pod "mypod" created 
[root@k8s-node1 ~]# kubectl exec -it mypod /bin/sh
/ # echo $SECRET_USERNAME
admin
/ # echo $SECRET_PASSWORD
abcdef

四、ConfigMap

           Secret可以为Pod提供密码、Token、私钥等敏感数据,对于一些非敏感数据,如配置信息,则可以用ConfigMap,使用方式与Secret非常类似,主要不同的是数据以明文形式存在。

1、创建ConfigMap

①通过 --from-litera

[root@k8s-node1 ~]# kubectl create configmap myconfigmap --from-literal=config1=xxx --from-literal=config2=yyy
configmap "myconfigmap" created

[root@k8s-node1 ~]# kubectl get configmap 
NAME          DATA      AGE
myconfigmap   2         9s

②通过 --from-file

echo -n xxx >./config1
echo -n yyy >./config2
kubectl create configmap myconfigmap --from-file=./config1 --from-file=./config2

③通过 --from-env-file

cat <<EOF >env.txt
config1=xxx
config2=yyy
EOF
kubectl create configmap myconfigmap --from-env-file=env.txt

④通过YAML配置文件-Volume方式

[root@k8s-node1 ~]# cat myconfigmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfigmap
data:
  config1: xxx
  config2: yyy
[root@k8s-node1 ~]# cat pod_volume.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy;sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: myconfigmap

⑤通过YAML配置文件-环境变量方式

[root@k8s-node1 ~]# cat pod_env.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy;sleep 30000
    env:
      - name: CONFIG_1
        valueFrom:
          secretKeyRef:
            name: myconfigmap
            key: config1
      - name: CONFIG_2
        valueFrom:
          secretKeyRef:
            name: myconfigmap
            key: config2

结论:大多数情况下,配置信息都以文件形式提供,所以创建configMap时通常采用--from-file或YAML方式,读取ConfigMap时通常采用Volume方式。

2、在Pod中使用ConfigMap

①创建YAML配置文件

[root@k8s-node1 ~]# cat myconfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfigmap
data:
  logging.conf: |
    class: logging.handlers.RotatingFileHandler
    formatter: precise
    level: INFO
    filename: %hostname-%timestamp.log

②查看ConfigMap

[root@k8s-node1 ~]# kubectl apply -f myconfigmap.yaml 
configmap "myconfigmap" created
[root@k8s-node1 ~]# kubectl get configmap myconfigmap 
NAME          DATA      AGE
myconfigmap   1         7s
[root@k8s-node1 ~]# kubectl describe configmap myconfigmap 
Name:         myconfigmap
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","data":{"logging.conf":"class: logging.handlers.RotatingFileHandler
formatter: precise
level: INFO
filename: %hostname-%timestamp...

Data
====
logging.conf:
----
class: logging.handlers.RotatingFileHandler
formatter: precise
level: INFO
filename: %hostname-%timestamp.log

Events:  <none>

③Pod中使用ConfigMap

[root@k8s-node1 ~]# cat pod_configmap.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10; touch /tmp/healthy;sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc"   #将volume mount到容器
  volumes:
  - name: foo
    configMap:
      name: myconfigmap
      items:
        - key: logging.conf
          path: myapp/logging.conf  #在volume中指定存放配置信息的文件相对路径为myapp/logging.cnf

④创建Pod并读取配置信息

[root@k8s-node1 ~]# kubectl apply -f pod_configmap.yaml 
pod "mypod" created
[root@k8s-node1 ~]# kubectl exec -it mypod /bin/sh
/ # cat /etc/myapp/logging.conf
class: logging.handlers.RotatingFileHandler
formatter: precise
level: INFO
filename: %hostname-%timestamp.log
/ #

结论:配置信息已保存到/etc/myapp/logging.conf文件中,与Secret一样,Volume形式的ConfigMap也支持动态更新。

原文地址:https://www.cnblogs.com/yanxinjiang/p/12172536.html