kubernetes secret使用详解(2)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: kubernetes secret使用详解(2)

6. 编辑 Secret

kubectl edit secrets mysecret

7. 使用 Secret

7.1 Pod Access Secrets Loaded in a Volume

创建一个 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

7.2 将 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

将会发生什么呢:

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

7.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

之后,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

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

8. 挂载的 Secret 会被自动更新

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


FEATURE STATE: Kubernetes v1.18 [alpha]

Kubernetes 的 alpha 特性 不可变的 Secret 和 ConfigMap 提供了一种可选配置, 可以设置各个 Secret 和 ConfigMap 为不可变的。 对于大量使用 Secret 的集群(至少有成千上万各不相同的 Secret 供 Pod 挂载), 禁止变更它们的数据有下列好处:


防止意外(或非预期的)更新导致应用程序中断

通过将 Secret 标记为不可变来关闭 kube-apiserver 对其的监视,从而显著降低 kube-apiserver 的负载,提升集群性能。

使用这个特性需要启用 ImmutableEmphemeralVolumes 特性开关 并将 Secret 或 ConfigMap 的 immutable 字段设置为 true. 例如:

apiVersion: v1
kind: Secret
metadata:
  ...
data:
  ...
immutable: true

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

9. 以环境变量的形式使用 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 
echo $SECRET_USERNAME
输出类似于:
admin
echo $SECRET_PASSWORD
输出类似于:
1f2d1e2e67df

10. 案例

10.1 以环境变量的形式使用 Secret

创建一个 Secret 定义:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  USER_NAME: YWRtaW4=
  PASSWORD: MWYyZDFlMmU2N2Rm

生成 Secret 对象:

kubectl apply -f mysecret.yaml

使用 envFrom 将 Secret 的所有数据定义为容器的环境变量。 Secret 中的键名称为 Pod 中的环境变量名称:

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - secretRef:
          name: mysecret
  restartPolicy: Never

10.2 包含 SSH 密钥的 Pod

创建一个包含 SSH 密钥的 Secret:

kubectl create secret generic ssh-key-secret \
  --from-file=ssh-privatekey=/path/to/.ssh/id_rsa \
  --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub

注意: 发送自己的 SSH 密钥之前要仔细思考:集群的其他用户可能有权访问该密钥。 你可以使用一个服务帐户,分享给 Kubernetes 集群中合适的用户,这些用户是你要分享的。 如果服务账号遭到侵犯,可以将其收回。

现在我们可以创建一个 Pod,令其引用包含 SSH 密钥的 Secret,并通过存储卷来使用它:

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
  labels:
    name: secret-test
spec:
  volumes:
  - name: secret-volume
    secret:
      secretName: ssh-key-secret
  containers:
  - name: ssh-test-container
    image: mySshImage
    volumeMounts:
    - name: secret-volume
      readOnly: true
      mountPath: "/etc/secret-volume"

容器中的命令运行时,密钥的片段可以在以下目录找到:

/etc/secret-volume/ssh-publickey
/etc/secret-volume/ssh-privatekey

然后容器可以自由使用 Secret 数据建立一个 SSH 连接。

10.3 包含生产/测试凭据的 Pod

下面的例子展示的是两个 Pod。 一个 Pod 使用包含生产环境凭据的 Secret,另一个 Pod 使用包含测试环境凭据的 Secret。


你可以创建一个带有 secretGenerator 字段的 kustomization.yaml 文件,或者执行 kubectl create secret:

kubectl create secret generic prod-db-secret \
  --from-literal=username=produser \
  --from-literal=password=Y4nys7f11
kubectl create secret generic test-db-secret \
  --from-literal=username=testuser \
  --from-literal=password=iluvtests
说明:
特殊字符(例如 $、\、*、= 和 !)会被你的 Shell解释,因此需要转义。 在大多数 Shell 中,对密码进行转义的最简单方式是用单引号(')将其括起来。 例如,如果您的实际密码是 S!B\*d$zDsb,则应通过以下方式执行命令:
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb='
注意:您无需对文件中的密码(--from-file)中的特殊字符进行转义。

创建 pod :

$ cat <<EOF > pod.yaml
apiVersion: v1
kind: List
items:
- kind: Pod
  apiVersion: v1
  metadata:
    name: prod-db-client-pod
    labels:
      name: prod-db-client
  spec:
    volumes:
    - name: secret-volume
      secret:
        secretName: prod-db-secret
    containers:
    - name: db-client-container
      image: myClientImage
      volumeMounts:
      - name: secret-volume
        readOnly: true
        mountPath: "/etc/secret-volume"
- kind: Pod
  apiVersion: v1
  metadata:
    name: test-db-client-pod
    labels:
      name: test-db-client
  spec:
    volumes:
    - name: secret-volume
      secret:
        secretName: test-db-secret
    containers:
    - name: db-client-container
      image: myClientImage
      volumeMounts:
      - name: secret-volume
        readOnly: true
        mountPath: "/etc/secret-volume"
EOF

将 Pod 添加到同一个 kustomization.yaml 文件

$ cat <<EOF >> kustomization.yaml
resources:
- pod.yaml
EOF

通过下面的命令应用所有对象

kubectl apply -k .

两个容器都会在其文件系统上存在以下文件,其中包含容器对应的环境的值:

/etc/secret-volume/username
/etc/secret-volume/password

10.4 Secret 卷中以句点号开头的文件

你可以通过定义以句点开头的键名,将数据“隐藏”起来。 例如,当如下 Secret 被挂载到 secret-volume 卷中:

apiVersion: v1
kind: Secret
metadata:
  name: dotfile-secret
data:
  .secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
  name: secret-dotfiles-pod
spec:
  volumes:
  - name: secret-volume
    secret:
      secretName: dotfile-secret
  containers:
  - name: dotfile-test-container
    image: k8s.gcr.io/busybox
    command:
    - ls
    - "-l"
    - "/etc/secret-volume"
    volumeMounts:
    - name: secret-volume
      readOnly: true
      mountPath: "/etc/secret-volume"

卷中将包含唯一的叫做 .secret-file 的文件。 容器 dotfile-test-container 中,该文件处于 /etc/secret-volume/.secret-file 路径下。


说明: 以点号开头的文件在 ls -l 的输出中会被隐藏起来; 列出目录内容时,必须使用 ls -la 才能看到它们

参考资料:


kubernetes secret/

Google Kubernetes Engine (GKE) secret

Kubernetes Secrets – How to Create, Use and Access Secrets

Kubernetes Secrets | How To Create, Use, and Access

https://www.containiq.com/post/kubernetes-secrets



相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
运维 Kubernetes 容器
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
|
1月前
|
存储 Kubernetes 数据安全/隐私保护
k8s学习笔记之ConfigMap和Secret
k8s学习笔记之ConfigMap和Secret
|
1月前
|
存储 Kubernetes 安全
在k8S中,Secret 有哪些使用方式?
在k8S中,Secret 有哪些使用方式?
|
1月前
|
Kubernetes 数据安全/隐私保护 容器
Kubernetes(K8S) 配置管理 Secret 介绍
Kubernetes(K8S) 配置管理 Secret 介绍
35 1
|
1月前
|
Prometheus Kubernetes 数据安全/隐私保护
使用kubeseal加密和管理k8s集群的secret
使用kubeseal加密和管理k8s集群的secret
46 2
|
1月前
|
Kubernetes 容器 Perl
在K8S中,请问harbor的secret创建能否直接创建资源清单?
在K8S中,请问harbor的secret创建能否直接创建资源清单?
|
1月前
|
存储 Kubernetes 安全
在k8S中,Kubernetes Secret 作用是什么?
在k8S中,Kubernetes Secret 作用是什么?
|
4月前
|
存储 Kubernetes 数据安全/隐私保护
Kubernetes的ConfigMap和Secret
Kubernetes的ConfigMap和Secret
85 0
|
4月前
|
Kubernetes 数据安全/隐私保护 Docker
云原生|kubernetes|关于secret的一些使用
云原生|kubernetes|关于secret的一些使用
139 0
|
4月前
|
Kubernetes 容器
k8s学习-CKS真题-secret创建、使用
k8s学习-CKS真题-secret创建、使用
83 0