• 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也支持动态更新。

  • 相关阅读:
    随机性的控制
    856. 括号的分数
    376. 摆动序列(贪心算法)
    XGBoost 安装方法
    1405. 最长快乐字符串(贪心算法)
    1296. 划分数组为连续数字的集合(贪心算法)
    1353. 最多可以参加的会议数目(贪心算法)
    435. 无重叠区间(贪心算法)
    Array-数组-数据结构
    认识Redis和安装
  • 原文地址:https://www.cnblogs.com/yanxinjiang/p/12172536.html
Copyright © 2020-2023  润新知