• 3.k8s存储之ConfigMap、Secret


    1、ConfigMap

    • ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制大对象
    • 相当于一个配置文件的注册中心,将数据保存在etcd中,让Pod以变量和volume挂载
    • 应用场景
      • 比如好几个Pod共用一个配置文件

    1.1、目录创建

    • —from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容 (—from-file 指定目录)

    • # 创建game.properties 和 ui.properties 文件
      [root@k8smaster configmap]# cat properties/game.properties
      enemies=aliens
      lives=3
      enemies.cheat=true
      enemies.cheat.level=noGoodRotten
      secret.code.passphrase=UUDDLRLRBABAS
      secret.code.allowed=true
      secret.code.lives=30
      [root@k8smaster configmap]# cat properties/ui.properties
      color.good=purple
      color.bad=yellow
      allow.textmode=true
      how.nice.to.look=fairlyNice
      
      # 使用命令创建 并且查看 DATA 表示键的数量
      [root@k8smaster configmap]# kubectl create configmap game-config --from-file=/root/configmap/properties
      configmap/game-config created
      [root@k8smaster configmap]# kubectl get configmap
      NAME          DATA   AGE
      game-config   2      11s
      
      # 查看详细信息
      [root@k8smaster configmap]# kubectl get configmap game-config -o yaml
      apiVersion: v1
      data:
        game.properties: |
          enemies=aliens
          lives=3
          enemies.cheat=true
          enemies.cheat.level=noGoodRotten
          secret.code.passphrase=UUDDLRLRBABAS
          secret.code.allowed=true
          secret.code.lives=30
        ui.properties: |
          color.good=purple
          color.bad=yellow
          allow.textmode=true
          how.nice.to.look=fairlyNice
      kind: ConfigMap
      metadata:
        creationTimestamp: "2020-12-17T03:31:25Z"
        managedFields:
        - apiVersion: v1
          fieldsType: FieldsV1
          fieldsV1:
            f:data:
              .: {}
              f:game.properties: {}
              f:ui.properties: {}
          manager: kubectl
          operation: Update
          time: "2020-12-17T03:31:25Z"
        name: game-config
        namespace: default
        resourceVersion: "1357422"
        selfLink: /api/v1/namespaces/default/configmaps/game-config
        uid: 2085e855-4bf9-4cdb-9ee8-30f1385ae2c5
      
      

    1.2、文件创建

    • 只要指定为一个文件就可以从单个文件中创建 ConfigMap

    • —from-file 这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的 (—from-file 指定文件)

    • # 创建configmap 并查看
      [root@k8smaster configmap]# kubectl create configmap game-config1 --from-file=/root/configmap/properties/ui.properties
      configmap/game-config1 created
      [root@k8smaster configmap]# kubectl get configmap game-config1
      NAME           DATA   AGE
      game-config1   1      22s
      
      # 查看详细信息 和目录创建效果一样
      [root@k8smaster configmap]# kubectl get configmap game-config1 -o yaml
      apiVersion: v1
      data:
        ui.properties: |
          color.good=purple
          color.bad=yellow
          allow.textmode=true
          how.nice.to.look=fairlyNice
      kind: ConfigMap
      metadata:
        creationTimestamp: "2020-12-17T03:37:30Z"
        managedFields:
        - apiVersion: v1
          fieldsType: FieldsV1
          fieldsV1:
            f:data:
              .: {}
              f:ui.properties: {}
          manager: kubectl
          operation: Update
          time: "2020-12-17T03:37:30Z"
        name: game-config1
        namespace: default
        resourceVersion: "1358296"
        selfLink: /api/v1/namespaces/default/configmaps/game-config1
        uid: 46e88eb8-1377-4710-abf6-a1d92273d5bf
      
      
      [root@k8smaster configmap]# kubectl describe configmap game-config1
      Name:         game-config1
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      
      Data
      ====
      ui.properties:
      ----
      color.good=purple
      color.bad=yellow
      allow.textmode=true
      how.nice.to.look=fairlyNice
      

    1.3、字面值创建

    • 使用文字值创建,利用 —from-literal 参数传递配置信息,该参数可以使用多次

    • # 创建configmap并查看
      [root@k8smaster configmap]# kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
      configmap/special-config created
      [root@k8smaster configmap]# kubectl describe configmap special-config
      Name:         special-config
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      
      Data
      ====
      special.how:
      ----
      very
      special.type:
      ----
      charm
      Events:  <none>
      
      # 查看详细信息 用cm也可以
      [root@k8smaster configmap]# kubectl get cm  special-config -o yaml
      apiVersion: v1
      data:
        special.how: very
        special.type: charm
      kind: ConfigMap
      metadata:
        creationTimestamp: "2020-12-17T03:43:34Z"
        managedFields:
        - apiVersion: v1
          fieldsType: FieldsV1
          fieldsV1:
            f:data:
              .: {}
              f:special.how: {}
              f:special.type: {}
          manager: kubectl
          operation: Update
          time: "2020-12-17T03:43:34Z"
        name: special-config
        namespace: default
        resourceVersion: "1359169"
        selfLink: /api/v1/namespaces/default/configmaps/special-config
        uid: 96b10ac7-964d-4c49-8dec-9dfd1697be72
      
      

    1.4、Pod中使用

    • 使用 ConfigMap 来替代环境变量

      • 资源清单示例

        • 如果创建ConfigMap是对应的name已经存在,则会更新其中的键值对,不会删除或创建失败

        • 如果使用不存在的configmap 会出现失败等错误

        • apiVersion: v1
          kind: ConfigMap
          metadata:
            name: special-config
            namespace: default
          # ConfigMap 中的键值对
          data:
            special.how: very
            special.type: charm
          
        • apiVersion: v1
          kind: ConfigMap
          metadata:
            name: log-config
            namespace: default
          # ConfigMap 中的键值对
          data:
            log_level: INFO
          
        • apiVersion: v1
          kind: Pod
          metadata:
            name: env-test-pod
          spec:
            containers:
            - name: test-container
              image: nginx
              # 打出环境变量
              command: [ "/bin/sh", "-c", "env" ]
              # 设置容器的环境变量 多个
              env:
              # 环境变量名称为 SPECIAL_LEVEL_KEY
              - name: SPECIAL_LEVEL_KEY
                # 对应的值从configmap中取 configmap的名称为special-config 取得是key为special.how的值 做为 环境变量的值
                valueFrom:
                  configMapKeyRef:
                    name: special-config
                    key: special.how
              - name: SPECIAL_TYPE_KEY
                valueFrom:
                  configMapKeyRef:
                    name: special-config
                    key: special.type
              - name: UI_PROPERTIES
                valueFrom:
                  configMapKeyRef:
                    name: game-config
                    key: ui.properties
              # 将configmap所有的键值对作为 环境变量 key为名称 value为值
              envFrom:
              - configMapRef:
                  name: log-config
            restartPolicy: Never
          
        • # 创建Pod 并查看日志
          [root@k8smaster configmap]# kubectl apply -f env-test-pod.yaml
          pod/env-test-pod created
          [root@k8smaster configmap]# kubectl get pod
          NAME                            READY   STATUS      RESTARTS   AGE
          env-test-pod                    0/1     Completed   0          54s
          
          # 查看日志后发现输出了我们设置的环境变量
          [root@k8smaster configmap]# kubectl logs env-test-pod
          
          SPECIAL_TYPE_KEY=charm
          
          UI_PROPERTIES=color.good=purple
          color.bad=yellow
          allow.textmode=true
          how.nice.to.look=fairlyNice
          
          SPECIAL_LEVEL_KEY=very
          
          log_level=INFO
          
          
    • 用 ConfigMap 设置命令行参数

      • 资源清单示例

        • apiVersion: v1
          kind: Pod
          metadata:
            name: linecommand-test-pod
          spec:
            containers:
            - name: test-container
              image: nginx
              # 在命令参数中 使用环境变量 用$(环境变量名)
              command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
              env:
              - name: SPECIAL_LEVEL_KEY
                valueFrom:
                  configMapKeyRef:
                    name: special-config
                    key: special.how
              - name: SPECIAL_TYPE_KEY
                valueFrom:
                  configMapKeyRef:
                    name: special-config
                    key: special.type
            restartPolicy: Never
          
        • # 创建 Pod 并查看
          [root@k8smaster configmap]# kubectl apply -f linecommand-test-pod.yaml
          pod/linecommand-test-pod created
          [root@k8smaster configmap]# vim linecommand-test-pod.yaml
          [root@k8smaster configmap]# kubectl get pod
          NAME                            READY   STATUS      RESTARTS   AGE
          linecommand-test-pod            0/1     Completed   0          65s
          
          # 创建日志 发现输出了 环境变量
          [root@k8smaster configmap]# kubectl logs linecommand-test-pod
          very charm
          
          
    • 通过数据卷插件使用ConfigMap

      • 在数据卷里面使用这个 ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容

      • 资源清单示例

        • apiVersion: v1
          kind: Pod
          metadata:
            name: volume-test-pod
          spec:
            containers:
            - name: test-container
              image: nginx
              command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
              # 容器挂载的数据卷
              volumeMounts:
              # 数据卷的名称 在Pod声明的数据卷中选择
              - name: config-volume
                # 挂载到容器内部的路径
                mountPath: /etc/config
            # Pod的数据卷
            volumes:
            # 数据卷的名称
            - name: config-volume
              # 数据卷挂载的地方 此处是来源configMap 名称是special-config 
              # 也就是说哪个容器使用的数据卷 会在容器挂载的路径下生成多个文件(取决于configmap中key的数量) key为文件名,value为文件内容
              configMap:
                name: special-config
            restartPolicy: Never
          
        • # 创建Pod并查看
          [root@k8smaster configmap]# kubectl apply -f volume-test-pod.yaml
          pod/vloume-test-pod created
          [root@k8smaster configmap]# kubectl get pod
          volume-test-pod                 0/1     Completed   0          24s
          
          # 查看日志 输出了文件内容
          [root@k8smaster configmap]# kubectl logs vloume-test-pod
          very
          
          

    1.5、ConfigMap热更新

    • 更新 ConfigMap 后

      • 使用该 ConfigMap 挂载的 Env 不会同步更新

      • 使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新 (这样就可以实时修改配置文件,比如nginx的)

      • 虽然配置文件可以热更新,但是能不能起作用还要看具体情况,比如nginx,启动之后,就不会再去看配置文件了,我们需要手动重启nginx,来达到重新读取配置文件的目的,如果有的服务可以一直监测配置文件,我们则不用手动处理(这种情况很少)

      • 更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,可以通过修改 pod annotations 的方式强制触发滚动更新

        • $ kubectl patch deployment hot-update-test --patch '{"spec": {"template": {"metadata": {"annotations":{"version/config": "20201010" }}}}}'
          
        • 这个例子里我们在 .spec.template.metadata.annotations 中添加 version/config ,每次通过修改version/config 来触发滚动更新

    • 资源清单示例

      • apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: hot-update-test
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: nginx
          template:
            metadata:
              labels:
                app: nginx
            spec:
              containers:
              - name: my-nginx
                image: nginx
                ports:
                - containerPort: 80
                # 容器使用Pod的容器卷 并挂载在自己内部
                volumeMounts:
                - name: config-volume
                  mountPath: /etc/config
              # 声明Pod的容器卷
              volumes:
              - name: config-volume
                configMap:
                  name: log-config
        
      • # 创建Pod 并查看挂载目录下的文件 和文件内容
        [root@k8smaster configmap]# kubectl apply -f hot-update-test.yaml
        deployment.apps/hot-update-test created
        [root@k8smaster configmap]# kubectl get pod
        NAME                               READY   STATUS      RESTARTS   AGE
        hot-update-test-6fd96995b6-jfw2w   1/1     Running     0          100s
        
        # 查看挂载目录下的文件 和文件内容
        [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- ls /etc/config
        log_level
        [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- cat /etc/config/log_level
        INFO
        
      • 修改 ConfigMap(log-config)中的内容 (将INFO改成DEBUD)

        • [root@k8smaster configmap]# kubectl edit configmap log-config
          configmap/log-config edited
          [root@k8smaster configmap]# kubectl describe configmap log-config
          Name:         log-config
          Namespace:    default
          Labels:       <none>
          Annotations:
          Data
          ====
          log_level:
          ----
          DEBUG
          Events:  <none>
          
        • # 查看log_level 文件内容发生了改变
          [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- cat /etc/config/log_level
          DEBUG
          

    2、Secret

    • ConfigMap将数据以明文的方式存放,不太安全,Secret可以用Base64编码存放,比较安全
    • Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec中。Secret 可以以 Volume 或者环境变量的方式使用
    • Secret 有三种类型
      • Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中,比如coredns、kube-proxy可以访问(不是什么都可以访问Kubernetes API)
      • Opaque :base64编码格式的Secret,用来存储密码、密钥等
      • kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息

    2.1、Service Account

    • # 查找系统的Pod 
      [root@k8smaster secret]# kubectl get pod -n kube-system
      NAME                                READY   STATUS    RESTARTS   AGE
      coredns-7ff77c879f-494fb            1/1     Running   2          46h
      coredns-7ff77c879f-tvgrz            1/1     Running   2          46h
      etcd-k8smaster                      1/1     Running   3          6d19h
      kube-apiserver-k8smaster            1/1     Running   3          6d19h
      kube-controller-manager-k8smaster   1/1     Running   16         6d19h
      kube-flannel-ds-amd64-hflj8         1/1     Running   4          6d6h
      kube-flannel-ds-amd64-s9xhk         1/1     Running   3          6d6h
      kube-flannel-ds-amd64-wp7mp         1/1     Running   4          6d6h
      kube-proxy-5l8kb                    1/1     Running   2          47h
      kube-proxy-6n8vp                    1/1     Running   2          47h
      kube-proxy-lgcxp                    1/1     Running   2          47h
      kube-scheduler-k8smaster            1/1     Running   17         6d19h
      
      # 查看 kube-proxy/run/secrets/kubernetes.io/serviceaccount 下的文件
      # ca.crt 是https的证书信息 namespace 是命名空间 token 是访问时携带的token
      [root@k8smaster secret]# kubectl exec -it -n kube-system kube-proxy-5l8kb -- ls /run/secrets/kubernetes.io/serviceaccount
      ca.crt  namespace  token
      

    2.2、Opaque

    • Opaque 类型的数据是一个 map 类型,要求 value 是 base64 编码格式

      • [root@k8smaster secret]# echo admin | base64
        YWRtaW4K
        [root@k8smaster secret]# echo 123456 | base64
        MTIzNDU2Cg==
        
        # 解码
        [root@k8smaster secret]# echo YWRtaW4K | base64 -d
        admin
        
    • 资源清单示例

      • apiVersion: v1
        kind: Secret
        metadata:
          name: mysecret
        type: Opaque
        data:
          username: YWRtaW4=
          password: MTIzNDU2Cg==
        
      • # 创建 secret 并查看
        [root@k8smaster secret]# kubectl apply -f secret-test.yaml
        secret/mysecret created
        
        [root@k8smaster secret]# kubectl get secret
        NAME                  TYPE                                  DATA   AGE
        default-token-99w8n   kubernetes.io/service-account-token   3      6d19h
        mysecret              Opaque                                2      8s
        
        
    • 将 Secret 挂载到 Volume 中

      • Secret中的键值对会以文件的方式存在在容器挂载的目录下 key为文件名 value为文件值(自动解码)

      • 资源清单示例

        • apiVersion: v1
          kind: Pod
          metadata:
            name: opaque-test
            labels:
              name: opaque-test
          spec:
            volumes:
            - name: secrets
              # 使用secret secret的名称是mysecret
              secret:
                secretName: mysecret
            containers:
            - image: nginx
              name: opaque-nginx
              volumeMounts:
              - name: secrets
                mountPath: /etc/opaque
                # 只读
                readOnly: true
          
        • # 创建Pod
          [root@k8smaster secret]# kubectl apply -f opaque-test.yaml
          pod/opaque-test created
          [root@k8smaster secret]# kubectl get pod
          NAME                               READY   STATUS    RESTARTS   AGE
          hot-update-test-6fd96995b6-jfw2w   1/1     Running   0          60m
          opaque-test                        1/1     Running   0          51s
          
          # 查看挂载目录下的文件
          [root@k8smaster secret]# kubectl exec -it opaque-test -- ls /etc/opaque
          password  username
          
          # 查看挂载目录下的文件内容 自动解码
          [root@k8smaster secret]# kubectl exec -it opaque-test -- cat /etc/opaque/username
          admin
          
    • 将 Secret 导出到环境变量中

      • 资源清单示例

        • apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: opaque-env
          spec:
            replicas: 2
            # 这个版本的Deployment不能省去selector
            selector:
              matchLabels:
                app: opaque-deployment
            template:
              metadata:
                labels:
                  app: opaque-deployment
              spec:
                containers:
                - name: pod-1
                  image: nginx
                  ports:
                  - containerPort: 80
                  # 设置环境变量
                  env:
                  # 环境变量名称
                  - name: TEST_USER
                    # 环境变量值得来源为secret secret的名称是mysecret 用的是key为username的value
                    valueFrom:
                      secretKeyRef:
                        name: mysecret
                        key: username
                  - name: TEST_PASSWORD
                    valueFrom:
                      secretKeyRef:
                        name: mysecret
                        key: password
          
        • # 创建deployment 并查看Pod
          [root@k8smaster secret]# kubectl apply -f opaque-env.yaml
          deployment.apps/opaque-env created
          [root@k8smaster secret]# kubectl get pod
          NAME                               READY   STATUS    RESTARTS   AGE
          opaque-env-54d4fd67f4-9xrrs        1/1     Running   0          11s
          opaque-env-54d4fd67f4-h7689        1/1     Running   0          11s
          
          # 查看两个Pod中的环境变量 均已解码
          [root@k8smaster secret]# kubectl exec -it opaque-env-54d4fd67f4-9xrrs -- env
          
          TEST_USER=admin
          TEST_PASSWORD=123456
          
          [root@k8smaster secret]# kubectl exec -it opaque-env-54d4fd67f4-h7689 -- env
          
          TEST_USER=admin
          TEST_PASSWORD=123456
          
          

    2.3、kubernetes.io/dockerconfigjson

    • 用来存储私有 docker registry 的认证信息

    • 使用命令创建(docker信息换成自己的)

      • kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
        
      • # 查看 myregistrykey 查看具体信息也是编码过的
        [root@k8smaster secret]# kubectl get secret
        NAME                  TYPE                                  DATA   AGE
        default-token-99w8n   kubernetes.io/service-account-token   3      6d20h
        myregistrykey         kubernetes.io/dockerconfigjson        1      10s
        mysecret              Opaque                                2      50m
        
    • 使用docker的登录文件创建

      • cat ~/.docker/config.json 这个docker的登录文件登录docker的仓库后自动生成

      • # 将登录文件的内容进行base64编码
        cat ~/.docker/config.json | base64
        
        # 将编码后的结果写入资源清单中
        cat > myregistrykey.yaml <<EOF
        apiVersion: v1
        kind: Secret
        metadata:
          name: myregistrykey
        data:
          .dockerconfigjson: docker的登录文件内容的base64编码
        type: kubernetes.io/dockerconfigjson
        EOF
        
        # 创建serret
        kubectl create -f myregistrykey.yaml
        
      • 资源清单示例

        • apiVersion: v1
          kind: Secret
          metadata:
            name: myregistrykey
          data:
            .dockerconfigjson: docker的登录文件内容的base64编码
          type: kubernetes.io/dockerconfigjson
          
    • 资源清单示例

      • apiVersion: v1
        kind: Pod
        metadata:
          name: docker-pod
        spec:
          containers:
            - name: foo
              # 这个镜像需要在自己的仓库中 需要身份认证
              image: registry.cn-hangzhou.aliyuncs.com/******/mytomcat:8.1.0
          # 使用镜像拉取的secret 包含镜像仓库的地址 用户名 密码等
          imagePullSecrets:
            - name: myregistrykey
        
      • # 查看pod 已经运行
        [root@k8smaster secret]# kubectl get pod
        NAME                               READY   STATUS    RESTARTS   AGE
        docker-pod                         1/1     Running   0          6m22s
        
  • 相关阅读:
    I/O工作机制
    Apache和Tomcat区别
    jenkins学习和使用
    小程序富文本转化插件
    一个正则表达式的用法
    contenteditable="true"让div可编辑
    JS实现品字布局
    扯扯小程序。
    (canvas)两小球碰撞后的速度问题研究
    canvas画多边形
  • 原文地址:https://www.cnblogs.com/xiaokantianse/p/14261209.html
Copyright © 2020-2023  润新知