• k8s 配置存储之 Configmap & secret


    在这里插入图片描述
    这篇比较轻松,因为我这会儿的时间被称之为“碎片时间”。

    configmap

    ConfigMap是一个或多个key/value的形式保存在k8s中,内部可以管理变量也可以管理完整的配置文件内容。

    示例

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: configmap
      namespace: dev
    data:
      info: |
        username:admin
        password:123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-configmap
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        volumeMounts: # 将configmap挂载到目录
        - name: config
          mountPath: /configmap/config
      volumes: # 引用configmap
      - name: config
        configMap:
          name: configmap
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    更新

    kubectl edit cm cm-test01
    
    • 1

    这个我比较关心,因为这个是真的用得到。

    通过kubectl describe cm cm-test01查看更新是否生效。

    方式二:直接更改yaml文件里面的值,通过kubectl apply -f configmap-test01.yaml重新发布一遍进行更新。

    不过目前我对二者细节还没把握到位。这个系列过去我会着手做一个社群,集思广益。


    Secret

    在kubernetes中,还存在一种和ConfigMap非常类似的对象,称为Secret对象。它主要用于存储敏感信息,例如密码、秘钥、证书等等。这样的信息可能会被放在 Pod 规约中或者镜像中。 用户可以创建 Secret,同时系统也创建了一些 Secret。

    要使用 Secret,Pod 需要引用 Secret。

    Pod 用使用 Secret三种方式

    • 作为挂载到一个或多个容器上的 卷 中的文件。
    • 作为容器的环境变量
    • 由 kubelet 在为 Pod 拉取镜像时使用

    使用 kubectl 创建 Secret

    # 创建本例中要使用的文件
    echo -n 'admin' > ./username.txt
    echo -n '1f2d1e2e67df' > ./password.txt
    
    #第一种
    # kubectl create secret 命令将这些文件打包到一个 Secret 中并在 API server 中创建了一个对象。 Secret 对象的名称必须是合法的 DNS 子域名。
    kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
    
    # 默认的键名是文件名。你也可以使用 [--from-file=[key=]source] 参数来设置键名。
    #第二种
    kubectl create secret generic db-user-pass \
      --from-file=username=./username.txt \
      --from-file=password=./password.txt
    
    #第三种
    kubectl create secret generic dev-db-secret \
      --from-literal=username=devuser \
      --from-literal=password='S!B\*d$zDsb='
    
    kubectl get secrets
    kubectl describe secrets/db-user-pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    特殊字符(例如 $、\、*、= 和 !)可能会被你的 Shell 解析,因此需要转义。 在大多数 Shell 中,对密码进行转义的最简单方式是使用单引号(’)将其扩起来。
    您无需对文件中保存(–from-file)的密码中的特殊字符执行转义操作。


    手动创建 Secret

    data

    $ echo -n 'admin' | base64
    YWRtaW4=
    $ echo -n '1f2d1e2e67df' | base64
    MWYyZDFlMmU2N2Rm
    
    • 1
    • 2
    • 3
    • 4

    编写一个yaml

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque
    data:
      username: YWRtaW4=
      password: MWYyZDFlMmU2N2Rm
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    kubectl apply -f ./secret.yaml
    
    • 1

    在某些情况下,你可能希望改用 stringData 字段。 此字段允许您将非 base64 编码的字符串直接放入 Secret 中, 并且在创建或更新 Secret 时将为您编码该字符串。

    stringData

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque
    stringData:
      config.yaml: |-
        apiUrl: "https://my.api.com/api/v1"
        username: {{username}}
        password: {{password}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    $ kubectl get secret mysecret -o yaml
    apiVersion: v1
    kind: Secret
    metadata:
      creationTimestamp: 2018-11-15T20:40:59Z
      name: mysecret
      namespace: default
      resourceVersion: "7225"
      uid: c280ad2e-e916-11e8-98f2-025000000001
    type: Opaque
    data:
      config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    如果在 data 和 stringData 中都指定了某一字段,则使用 stringData 中的值:

    data 和 stringData 的键必须由字母数字字符 ‘-’, ‘_’ 或者 ‘.’ 组成.


    从生成器创建 Secret

    Kubectl 从 1.14 版本开始支持使用 Kustomize 管理对象。 Kustomize 提供资源生成器创建 Secret 和 ConfigMaps。 Kustomize 生成器要在当前目录内的 kustomization.yaml 中指定。 生成 Secret 之后,使用 kubectl apply 在 API 服务器上创建对象。

    从文件生成 Secret

    cat <<EOF >./kustomization.yaml
    secretGenerator:
    - name: db-user-pass
      files:
      - username.txt
      - password.txt
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    应用包含 kustomization.yaml 目录以创建 Secret 对象。

    kubectl apply -k .
    kubectl get secrets
    
    • 1
    • 2

    输出类似于:

    NAME                             TYPE                                  DATA      AGE
    db-user-pass-96mffmfh4k          Opaque                                2         51s
    
    • 1
    • 2
    $ kubectl describe secrets/db-user-pass-96mffmfh4k
    Name:            db-user-pass
    Namespace:       default
    Labels:          <none>
    Annotations:     <none>
    
    Type:            Opaque
    
    Data
    ====
    password.txt:    12 bytes
    username.txt:    5 bytes
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    基于字符串值来创建 Secret

    cat <<EOF >./kustomization.yaml
    secretGenerator:
    - name: db-user-pass
      literals:
      - username=admin
      - password=secret
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    应用包含 kustomization.yaml 目录以创建 Secret 对象。

    kubectl apply -k .
    kubectl get secret mysecret -o yaml
    
    • 1
    • 2

    解码 Secret

    输出类似于:

    apiVersion: v1
    kind: Secret
    metadata:
      creationTimestamp: 2016-01-22T18:41:56Z
      name: mysecret
      namespace: default
      resourceVersion: "164619"
      uid: cfee02d6-c137-11e5-8d73-42010af00002
    type: Opaque
    data:
      username: YWRtaW4=
      password: MWYyZDFlMmU2N2Rm
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    解码 password 字段:

    echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
    
    • 1

    输出类似于:

    1f2d1e2e67df
    
    • 1

    编辑 Secret

    kubectl edit secrets mysecret
    
    • 1

    使用 Secret

    在 Pod 中使用存放在卷中的 Secret

    • 创建一个 Secret 或者使用已有的 Secret。多个 Pod 可以引用同一个 Secret。
    • 修改你的 Pod 定义,在 spec.volumes[] 下增加一个卷。可以给这个卷随意命名, 它的spec.volumes[].secret.secretName 必须是 Secret 对象的名字。
    • 将 spec.containers[].volumeMounts[] 加到需要用到该 Secret 的容器中。 指定 spec.containers[].volumeMounts[].readOnly = true 和spec.containers[].volumeMounts[].mountPath 为你想要该 Secret 出现的尚未使用的目录。
    • 修改你的镜像并且/或者命令行,让程序从该目录下寻找文件。 Secret 的 data 映射中的每一个键都对应 mountPath 下的一个文件名。
    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
          readOnly: true
      volumes:
      - name: foo
        secret:
          secretName: mysecret
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    将 Secret 键名映射到特定路径

    你可以使用 spec.volumes[].secret.items 字段修改每个键对应的目标路径:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
          readOnly: true
      volumes:
      - name: foo
        secret:
          secretName: mysecret
          items:
          - key: username
            path: my-group/my-username
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    将会发生什么呢:

    username Secret 存储在 /etc/foo/my-group/my-username 文件中而不是
    /etc/foo/username 中。
    password Secret 没有被映射
    
    • 1
    • 2
    • 3

    Secret 文件权限

    你还可以指定 Secret 将拥有的权限模式位。如果不指定,默认使用 0644
    示例:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
      volumes:
      - name: foo
        secret:
          secretName: mysecret
          defaultMode: 256
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    之后,Secret 将被挂载到 /etc/foo 目录,而所有通过该 Secret 卷挂载 所创建的文件的权限都是 0400。

    你还可以使用映射,如上一个示例,并为不同的文件指定不同的权限,如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
      volumes:
      - name: foo
        secret:
          secretName: mysecret
          items:
          - key: username
            path: my-group/my-username
            mode: 511
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里,位于 /etc/foo/my-group/my-username 的文件的权限值为 0777。 由于 JSON 限制,必须以十进制格式指定模式,即 511。


    挂载的 Secret 会被自动更新

    当已经存储于卷中被使用的 Secret 被更新时,被映射的键也将终将被更新。 组件 kubelet 在周期性同步时检查被挂载的 Secret 是不是最新的。 但是,它会使用其本地缓存的数值作为 Secret 的当前值。

    通过将 Secret 标记为不可变来关闭 kube-apiserver 对其的监视,从而显著降低 kube-apiserver 的负载,提升集群性能。
    使用这个特性需要启用 ImmutableEmphemeralVolumes 特性开关 并将 Secret 或 ConfigMap 的 immutable 字段设置为 true. 例如:

    apiVersion: v1
    kind: Secret
    metadata:
      ...
    data:
      ...
    immutable: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    说明: 一旦一个 Secret 或 ConfigMap 被标记为不可变,撤销此操作或者更改 data 字段的内容都是 不可能的。 只能删除并重新创建这个 Secret。现有的 Pod 将维持对已删除 Secret 的挂载点 - 建议重新创建这些 Pod。


    以环境变量的形式使用 Secrets

    将 Secret 作为 Pod 中的环境变量使用:

    • 创建一个 Secret 或者使用一个已存在的 Secret。多个 Pod 可以引用同一个 Secret。
    • 修改 Pod 定义,为每个要使用 Secret 的容器添加对应 Secret 键的环境变量。 使用 Secret 键的环境变量应在 env[x].valueFrom.secretKeyRef 中指定 要包含的 Secret 名称和键名。
    • 更改镜像并/或者命令行,以便程序在指定的环境变量中查找值。
     apiVersion: v1
    kind: Pod
    metadata:
      name: secret-env-pod
    spec:
      containers:
      - name: mycontainer
        image: redis
        env:
          - name: SECRET_USERNAME
            valueFrom:
              secretKeyRef:
                name: mysecret
                key: username
          - name: SECRET_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysecret
                key: password
      restartPolicy: Never 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    echo $SECRET_USERNAME
    
    • 1

    输出类似于:

    admin
    
    • 1
    echo $SECRET_PASSWORD
    
    • 1

    输出类似于:

    1f2d1e2e67df
    
    • 1
  • 相关阅读:
    重入攻击和 DAO 被黑事件
    介绍一下js垃圾回收机制
    Java非Spring框架下的单元测试
    Qt中INI 配置文件的读写操作
    前端智能化实践——可微编程
    高效+灵活+安全=低代码的三位一体解决方案
    什么是BDD测试(行为驱动开发测试)?
    浅谈Vue中的$nextTick方法
    MySQL集群高可用架构之MHA
    Linux常见命令手册
  • 原文地址:https://blog.csdn.net/qq_43762191/article/details/125984225