概念

Kubernetes v1.16 文档不再得到积极维护。您当前正在查看的版本是静态快照。有关最新文档,请参见 最新版本。

编辑这个页面

机密

Kubernetes secret objects let you store 一个d manage sensitive information, such 作为密码,OAuth令牌和ssh密钥。将此信息放入 secret 比逐字逐句地将其更安全,更灵活 最小和最简单的Kubernetes对象。 荚代表集群上一组正在运行的容器。 定义或 容器图片容器的存储实例,其中包含运行应用程序所需的一组软件。 。看到 秘密设计文件 想要查询更多的信息。

机密概述

机密是包含少量敏感数据的对象,例如 密码,令牌或密钥。否则,此类信息可能会放在 吊舱规格或图像;将其放在Secret对象中可以 更好地控制使用方式,并降低意外暴露的风险。

用户可以创建秘密,系统也可以创建一些秘密。

要使用机密,吊舱需要引用该机密。 秘密可以通过两种方式与吊舱一起使用:作为文件中的文件 包含数据的目录,容器中的容器可以访问该目录。 安装在一个或多个 它的容器,或在为吊舱提取图像时由kubelet使用。

内置秘密

服务帐户使用API​​凭据自动创建和附加机密

Kubernetes自动创建包含以下凭证的机密 访问API,它会自动修改您的广告连播,以使用此类 secret.

可以禁用或覆盖API凭据的自动创建和使用 如果需要的话。但是,如果您需要做的只是安全地访问apiserver, 这是推荐的工作流程。

服务帐号 有关更多文档 有关服务帐户工作方式的信息。

创建自己的秘密

使用kubectl创建秘密创建秘密

假设某些Pod需要访问数据库。的 文件中应使用Pod的用户名和密码 ./username.txt 一个d ./password.txt on your local machine.

# Create files needed for rest of example.
echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt

The kubectl create secret command 将这些文件打包成一个Secret并创建 Apiserver上的对象。

kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
注意:

Special characters 如 $, \, *, 一个d ! will be interpreted by your 贝壳 一个d require escaping. In most common 贝壳s, the easiest way to escape the password is to surround it with single quotes (')。 For example, if your actual password is S!B\*d$zDsb, you 应该 execute the command this way:

kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb'

You do 不 need to escape special characters in passwords from files (--from-file)。

您可以检查机密是否是这样创建的:

kubectl get secrets
NAME                  TYPE                                  DATA      AGE
db-user-pass          Opaque                                2         51s
kubectl describe secrets/db-user-pass
Name:            db-user-pass
Namespace:       default
Labels:          <none>
Annotations:     <none>

Type:            Opaque

Data
====
password.txt:    12 bytes
username.txt:    5 bytes
注意: kubectl get 一个d kubectl describe avoid showing the contents of a secret by default. 这是为了防止机密被意外地暴露给旁观者, 或存储在终端日志中。

看到 解密秘密 有关如何查看秘密内容的信息。

手动创建秘密

您还可以先在文件中以json或yaml格式创建一个Secret, 然后创建该对象。的 秘密 包含两个地图: 数据和字符串数据。数据字段用于存储任意数据,使用 base64。提供stringData字段是为了方便起见,它允许您提供 机密数据作为未编码的字符串。

例如,要使用数据字段将两个字符串存储在Secret中,请转换 他们到base64如下:

echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm

写一个像下面这样的秘密:

apiVersion: v1
kind: 秘密
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

现在使用创建秘密 kubectl apply:

kubectl apply -f ./secret.yaml
secret "mysecret" created

对于某些情况,您可能希望改用stringData字段。这个 字段可让您将非base64编码的字符串直接放入Secret中, 并且在创建或更新“机密”时将为您编码该字符串。

一个实际的例子可能是您在哪里部署应用程序 使用秘密存储配置文件的文件,并且您想填充 在部署过程中该配置文件的一部分。

如果您的应用程序使用以下配置文件:

apiUrl: "//my.api.com/api/v1"
username: "user"
password: "password"

您可以使用以下方法将其存储在Secret中:

apiVersion: v1
kind: 秘密
metadata:
  name: mysecret
type: Opaque
stringData:
  config.yaml: |-
    apiUrl: "//my.api.com/api/v1"
    username: {{username}}
    password: {{password}}

Your deployment tool could then replace the {{username}} 一个d {{password}} template variables before running kubectl apply.

stringData是只写的便利字段。永远不会输出 检索秘密。例如,如果您运行以下命令:

kubectl get secret mysecret -o yaml

输出将类似于:

apiVersion: v1
kind: 秘密
metadata:
  creationTimestamp: 2018-11-15T20:40:59Z
  name: mysecret
  命名空间: default
  resourceVersion: "7225"
  uid: c280ad2e-e916-11e8-98f2-025000000001
type: Opaque
data:
  config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19

如果在data和stringData中都指定了字段,则stringData中的值 用来。例如,以下秘密定义:

apiVersion: v1
kind: 秘密
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
stringData:
  username: administrator

结果为以下秘密:

apiVersion: v1
kind: 秘密
metadata:
  creationTimestamp: 2018-11-15T20:46:46Z
  name: mysecret
  命名空间: default
  resourceVersion: "7579"
  uid: 91460ecb-e917-11e8-98f2-025000000001
type: Opaque
data:
  username: YWRtaW5pc3RyYXRvcg==

Where YWRtaW5pc3RyYXRvcg== decodes to administrator.

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

编码注意: 秘密数据的序列化JSON和YAML值是 编码为base64字符串。换行符在这些字符串中无效,并且必须 be omitted. When using the base64 utility on Darwin/macOS users 应该 avoid using the -b option to split long lines. Conversely Linux users 应该 加 the option -w 0 to base64 commands 要么 the pipeline base64 | tr -d '\n' if -w 选项不可用。

从生成器创建秘密

Kubectl支持 使用Kustomize管理对象 从1.14开始。有了这项新功能, 您还可以从生成器创建一个Secret,然后将其应用于在 Apiserver。发电机 should be specified in a kustomization.yaml inside a directory.

For example, to generate a 秘密 from files ./username.txt 一个d ./password.txt

# Create a kustomization.yaml file with 秘密Generator
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
  files:
  - username.txt
  - password.txt
EOF

应用kustomization目录创建Secret对象。

$ kubectl apply -k .
secret/db-user-pass-96mffmfh4k created

您可以检查机密是否是这样创建的:

$ kubectl get secrets
NAME                             TYPE                                  DATA      AGE
db-user-pass-96mffmfh4k          Opaque                                2         51s

$ 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

For example, to generate a 秘密 from literals username=admin 一个d password=secret, you can specify the secret generator in kustomization.yaml as

# Create a kustomization.yaml file with 秘密Generator
$ cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
  literals:
  - username=admin
  - password=secret
EOF

应用kustomization目录创建Secret对象。

$ kubectl apply -k .
secret/db-user-pass-dddghtt9b5 created
注意: 生成的Secrets名称具有通过对内容进行散列而附加的后缀。这样可以确保 每次修改内容时都会生成秘密。

解密秘密

机密 can be retrieved via the kubectl get secret command. For example, to retrieve the secret created in the previous section:

kubectl get secret mysecret -o yaml
apiVersion: v1
kind: 秘密
metadata:
  creationTimestamp: 2016-01-22T18:41:56Z
  name: mysecret
  命名空间: default
  resourceVersion: "164619"
  uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

解码密码字段:

echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df

编辑秘密

可以使用以下命令来编辑现有机密:

kubectl edit secrets mysecret

This will open the default configured editor 一个d allow for updating the base64 encoded secret values in the data field:

# Please edit the object below. Lines beginning with a '#' will be ignored,
# 一个d 一个 empty file will abort the edit. If 一个 error occurs 而 saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
kind: 秘密
metadata:
  一个notations:
    kubectl.kubernetes.io/last-applied-configuration: { ... }
  creationTimestamp: 2016-01-22T18:41:56Z
  name: mysecret
  命名空间: default
  resourceVersion: "164619"
  uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque

使用秘密

机密可以作为数据卷挂载,也可以作为 环境变量容器环境变量是名称=值对,可为在Pod中运行的容器提供有用的信息。 由容器中的容器使用。它们也可以被其他部分使用 系统,而无需直接暴露在吊舱中。例如,他们可以 系统其他部分用于与外部交互的凭据 系统代表您。

将机密用作Pod中的文件

要在Pod中的某个卷中使用秘密,请执行以下操作:

  1. 创建一个秘密或使用现有的秘密。多个Pod可以引用同一秘密。
  2. Modify your 荚 definition to 加 a 卷 under .spec.volumes[]. Name the 卷 任何thing, 一个d have a .spec.volumes[].secret.secretName field equal to the name of the secret object.
  3. Add a .spec.containers[].volumeMounts[] to each container 那 needs the 秘密。 Specify .spec.containers[].volumeMounts[].readOnly = true 一个d .spec.containers[].volumeMounts[].mountPath to 一个 unused directory name where you would like the secrets to appear.
  4. Modify your image 一个d/or command line so 那 the program looks for files in 那 directory. Each key in the secret data map becomes the filename under mountPath.

这是在卷中装入机密的pod的示例:

apiVersion: v1
kind: 
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    卷Mounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  卷s:
  - name: foo
    secret:
      secretName: mysecret

Each secret you want to use needs to be referred to in .spec.volumes.

如果吊舱中有多个容器,则每个容器都需要 own 卷Mounts block, but only one .spec.volumes is needed per 秘密。

您可以将许多文件打包为一个秘密,也可以使用许多秘密,以方便为准。

将密钥投影到特定路径

我们还可以控制投影秘密密钥的卷中的路径。 You can use .spec.volumes[].secret.items field to change target path of each key:

apiVersion: v1
kind: 
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    卷Mounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  卷s:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username

会发生什么:

  • username secret is stored under /etc/foo/my-group/my-username file instead of /etc/foo/username.
  • password 没有秘密

If .spec.volumes[].secret.items is used, only keys specified in items are projected. To consume all keys from the secret, all of them must be listed in the items field. 所有列出的密钥必须存在于相应的秘密中。否则,不会创建该卷。

秘密文件权限

您还可以指定秘密模式一部分将具有的许可模式位文件。 If you don’t specify 任何, 0644 is used by 默认。 You can specify a default 整个秘密卷的密码模式,并在需要时覆盖每个密钥。

例如,您可以指定如下默认模式:

apiVersion: v1
kind: 
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    卷Mounts:
    - name: foo
      mountPath: "/etc/foo"
  卷s:
  - name: foo
    secret:
      secretName: mysecret
      defaultMode: 256

Then, the secret will be mounted on /etc/foo 一个d all the files created by the secret 卷 mount will have permission 0400.

请注意,JSON规范没有’t支持八进制表示法,因此将值256用于 0400权限。如果您使用yaml而不是json作为Pod,则可以使用八进制 以更自然的方式指定权限的符号。

您还可以像前面的示例一样使用映射,并指定不同的 像这样的不同文件的权限:

apiVersion: v1
kind: 
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    卷Mounts:
    - name: foo
      mountPath: "/etc/foo"
  卷s:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username
        mode: 511

In this case, the file resulting in /etc/foo/my-group/my-username will have permission value of 0777. Owing to JSON limitations, you must specify the mode in decimal 不ation.

请注意,如果您将此权限值显示为十进制 read it later.

从卷中消费秘密值

在安装秘密卷的容器内,秘密密钥显示为 文件和秘密值经过base-64解码后存储在这些文件中。 这是命令的结果 从上面的示例在容器内部执行:

ls /etc/foo/
username
password
cat /etc/foo/username
admin
cat /etc/foo/password
1f2d1e2e67df

容器中的程序负责从 files.

安装的机密会自动更新

当卷中已使用的机密被更新时,投影的密钥最终也会被更新。 Kubelet正在检查是否在每个定期同步中都重新装入已安装的机密。 但是,它正在使用其本地缓存来获取Secret的当前值。 The type of the cache is configurable using the (ConfigMapAndSecretChangeDetectionStrategy field in KubeletConfiguration结构)。 它可以通过监视(默认),基于ttl的传播或直接重定向 所有直接发送到kube-apiserver的请求。 结果,从秘密更新到更新的总延迟 新密钥投射到Pod的时间可以与kubelet同步周期+缓存一样长 传播延迟,其中缓存传播延迟取决于所选的缓存类型 (等于观看传播延迟,缓存ttl或相应地零核心)。

注意: 使用Secret作为容器的容器 子路径 卷安装将不会收到 Secret updates.

将机密用作环境变量

环境变量容器环境变量是名称=值对,可为在Pod中运行的容器提供有用的信息。 在吊舱中:

  1. 创建一个秘密或使用现有的秘密。多个Pod可以引用同一秘密。
  2. 在每个您希望使用密钥值的容器中修改Pod定义,以为您希望使用的每个密钥添加一个环境变量。使用秘密密钥的环境变量应填充秘密’s name 一个d key in env[].valueFrom.secretKeyRef.
  3. 修改图像和/或命令行,以便程序在指定的环境变量中查找值

这是一个使用环境变量的机密的示例:

apiVersion: v1
kind: 
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

从环境变量中消费秘密值

在消耗环境变量秘密的容器内,秘密密钥显示为 包含机密数据的base-64解码值的常规环境变量。 这是上述示例在容器内部执行命令的结果:

echo $SECRET_USERNAME
admin
echo $SECRET_PASSWORD
1f2d1e2e67df

使用imagePullSecrets

imagePullSecret是一种传递包含Docker(或其他)映像注册表的机密的方法 Kubelet的密码,以便它可以代表您的Pod提取私有图像。

手动指定imagePullSecret

imagePullSecrets的用法在 图像文件

安排自动挂载imagePullSecrets

您可以手动创建imagePullSecret,并从中引用它 一个serviceAccount。使用该服务创建的任何吊舱 或使用该serviceAccount的默认值,将获取其imagePullSecret 字段设置为服务帐户的字段。 See 将ImagePullSecrets添加到服务帐户 有关该过程的详细说明。

自动挂载手动创建的机密

手动创建的机密(例如,包含用于访问github帐户的令牌的机密) 可以根据其服务帐户自动附加到Pod。 See 使用PodPreset将信息注入Pod 有关该过程的详细说明。

细节

限制条件

秘密卷源经过验证以确保指定的对象 reference actually points to 一个 object of type 秘密. Therefore, a secret 需要在依赖它的任何pod之前创建。

秘密API对象驻留在 命名空间Kubernetes用于支持同一物理集群上的多个虚拟集群的抽象。 . 它们只能由同一名称空间中的pod引用。

个人机密的大小上限为1MiB。这是为了阻止创作 非常大的秘密,将耗尽apiserver和kubelet内存。 但是,创建许多较小的机密也会耗尽内存。更多 由于机密性,对内存使用的全面限制是一项计划内的功能。

Kubelet仅支持对从API服务器获取的Pod使用机密。 这包括使用kubectl或通过复制间接创建的所有pod 控制器。它不包括通过kubelet创建的吊舱 --manifest-url flag, its --config flag, 要么 its REST API (these are 创建豆荚的常见方法。)

必须先创建机密,然后才能在机舱中使用机密 变量,除非它们被标记为可选。引用确实存在的秘密 不存在会阻止pod启动。

References via secretKeyRef to keys 那 do 不 exist in a named 秘密 将阻止豆荚启动。

机密 used to populate 环境变量 via envFrom 那 have keys 被认为无效的环境变量名称将具有这些键 跳过了。吊舱将被允许启动。会有一个事件 reason is InvalidVariableNames 一个d the message will contain the list of 被跳过的无效键。该示例显示了一个指向 default / mysecret包含2个无效密钥,即1badkey和2alsobad。

kubectl get events
LASTSEEN   FIRSTSEEN   COUNT     NAME            KIND      SUBOBJECT                         TYPE      REASON
0s         0s          1         dapi-test-pod   荚                                         Warning   InvalidEnvironmentVariableNames   kubelet, 127.0.0.1      Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid 环境变量 names.

秘密与Pod一生的互动

通过API创建广告连播时,不会检查是否已引用 秘密存在。安排好广告连播后,kubelet将尝试获取 秘密价值。如果由于秘密不存在而无法获取该秘密,或者 由于暂时缺乏与API服务器的连接,kubelet将 定期重试。它将报告有关吊舱的事件,解释 原因尚未开始。获取秘密后,kubelet将 创建并安装包含它的卷。没有一个豆荚’s containers will 开始直到所有豆荚’已装入s个卷。

用例

用例:带有ssh键的Pod

使用SecretGenerator创建一个包含一些ssh密钥的kustomization.yaml:

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
secret "ssh-key-secret" created
警告: 在发送您自己的ssh密钥之前,请仔细考虑:群集的其他用户可能可以访问该机密。使用一个服务帐户,您希望与之共享Kubernetes群集的所有用户都可以访问该服务帐户,并且如果这些帐户受到威胁,可以将其撤消。

现在,我们可以创建一个通过ssh密钥引用机密的pod, 大量消耗它:

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

当容器’s命令运行后,密钥片段将在以下位置可用:

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

然后,容器可以自由使用秘密数据来建立ssh连接。

用例:具有产品/测试凭证的容器

本示例说明了一个使用包含产品的机密的吊舱 凭据和另一个在测试环境中消耗秘密的Pod credentials.

使用SecretGenerator制作kustomization.yaml

kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret "prod-db-secret" created
kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
secret "test-db-secret" created
注意:

Special characters 如 $, \, *, 一个d ! will be interpreted by your 贝壳 一个d require escaping. In most common 贝壳s, the easiest way to escape the password is to surround it with single quotes (')。 For example, if your actual password is S!B\*d$zDsb, you 应该 execute the command this way:

kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb'

You do 不 need to escape special characters in passwords from files (--from-file)。

现在制作豆荚:

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

将豆荚添加到相同的kustomization.yaml

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

通过以下方式将所有这些对象应用于Apiserver

kubectl apply -k .

这两个容器在其文件系统上都将具有以下文件,其中包含每个容器的值’s environment:

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

请注意,两个Pod的规格仅在一个字段中有何不同?这有利于 从通用的pod配置模板创建具有不同功能的pod。

您可以通过使用两个服务帐户来进一步简化基本pod规范: one called, say, prod-user with the prod-db-secret, 一个d one called, say, test-user with the test-db-secret. Then, the pod spec can be shortened to, for example:

apiVersion: v1
kind: 
metadata:
  name: prod-db-client-pod
  labels:
    name: prod-db-client
spec:
  serviceAccount: prod-db-client
  containers:
  - name: db-client-container
    image: myClientImage

用例:秘密卷中的点文件

为了制作数据‘hidden’(即,文件名以点字符开头),只需 使该键以点开头。例如,将以下机密装入卷中时:

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

The secret-volume will contain a single file, called .secret-file, 一个d the dotfile-test-container will have this file present at the path /etc/secret-volume/.secret-file.

注意: Files beginning with dot characters are 隐 from the output of ls -l; you must use ls -la to see them when listing directory contents.

用例:对机舱中的一个容器可见的秘密

考虑一个需要处理HTTP请求的程序,做一些复杂的事情 逻辑,然后使用HMAC对某些消息进行签名。因为它很复杂 应用程序逻辑中,可能存在不被注意的远程文件读取漏洞 服务器,可能会将私钥暴露给攻击者。

这可以在两个容器中分为两个过程:前端容器 处理用户交互和业务逻辑,但看不到 私钥;以及可以查看私钥并进行响应的签名者容器 到来自前端的简单签名请求(例如通过localhost网络)。

通过这种分区方法,攻击者现在必须欺骗应用程序 服务器做一些相当随意的事情,这可能比做起来更难 it to read a file.

最佳实践

使用Secrets API的客户端

部署与Secrets API交互的应用程序时,应进行访问 limited using 授权政策RBAC.

机密通常具有跨越一系列重要价值的价值观,其中许多可以 导致Kubernetes内部升级(例如服务帐户令牌),并导致 外部系统。即使单个应用程序可以推断出 期望与之交互的秘密,同一名称空间中的其他应用程序可以 使这些假设无效。

For these reasons watch 一个d list requests for secrets within a 命名空间 are 极其强大的功能,应避免使用,因为列出机密可以 客户端检查该名称空间中所有机密的值。的能力 watch 一个d list all secrets in a cluster 应该 be reserved for only the most 特权的系统级组件。

Applications 那 need to access the secrets API 应该 perform get requests on 他们需要的秘密。这使管理员可以限制对所有机密的访问 while 将单个实例列入白名单 那 the app needs.

For improved performance over a looping get, clients can design resources 那 reference a secret then watch the resource, re-requesting the secret when the 参考更改。此外, “bulk watch” API to let clients watch individual resources has also been proposed, 一个d will likely 在将来的Kubernetes版本中可用。

安全性

保护装置

Because secret objects can be created independently of the pods 那 use 他们,在工作流程中暴露秘密的风险较小 创建,查看和编辑广告连播。该系统还可以采取其他措施 precautions with secret objects, 如 avoiding writing them to disk where possible.

仅当节点上的Pod需要秘密时,该秘密才会发送到该节点。 Kubelet stores the secret into a tmpfs so 那 the secret is 不 written 到磁盘存储。删除依赖于机密的Pod之后,kubelet 还将删除其秘密数据的本地副本。

同一节点上的多个Pod可能存在秘密。但是,只有 Pod请求的机密可能在其容器中可见。 因此,一个Pod无法访问另一Pod的秘密。

吊舱中可能有多个容器。但是,吊舱中的每个容器都有 to request the secret 卷 in its 卷Mounts for it to be visible within 容器。这可以用来构造有用的 的安全分区 Pod level.

在大多数Kubernetes项目维护的发行版中,用户之间的通信 到apiserver,以及从apiserver到kubelet,均受SSL / TLS保护。 通过这些渠道传输时,机密会受到保护。

功能状态: Kubernetes v1.13 贝塔
该功能当前位于 贝塔 状态,含义:

  • 版本名称包含beta(例如v2beta3)。
  • 代码已经过测试。启用该功能被认为是安全的。默认启用。
  • 尽管细节可能会更改,但不会放弃对整体功能的支持。
  • 对象的架构和/或语义可能会在随后的Beta或稳定版本中以不兼容的方式更改。发生这种情况时,我们将提供有关迁移到下一个版本的说明。这可能需要删除,编辑和重新创建API对象。编辑过程可能需要一些思考。对于依赖该功能的应用程序,可能需要停机。
  • 建议仅用于非关键业务用途,因为在后续版本中可能会发生不兼容的更改。如果您有多个可以独立升级的群集,则可以放宽此限制。
  • 请尝试使用我们的Beta功能,并提供有关它们的反馈!他们退出测试版后,对我们进行更多更改可能不切实际。

您可以启用 静态加密 用于机密数据,以使机密不会以明文形式存储到 一致且高度可用的键值存储用作Kubernetes’所有群集数据的后备存储。 .

风险性

  • 在API服务器中,机密数据存储在 一致且高度可用的键值存储用作Kubernetes’所有群集数据的后备存储。 ; therefore:
    • 管理员应为群集数据启用静态加密(需要v1.13或更高版本)
    • 管理员应将对etcd的访问权限限制为管理员用户
    • 管理员可能想在不再使用etcd时擦除/粉碎磁盘
    • 如果在集群中运行etcd,则管理员应确保使用SSL / TLS 用于etcd对等通信。
  • 如果您通过清单文件(JSON或YAML)配置密码, 编码为base64的机密数据,共享该文件或将其签入到 源存储库意味着秘密已被泄露。 Base64编码是 一个 加密方法,被认为与纯文本相同。
  • 从卷中读取密码后,应用程序仍然需要保护密码的值, 例如不会意外登录或将其传输给不受信任的一方。
  • 可以创建使用机密的Pod的用户也可以看到该机密的值。甚至 如果apiserver策略不允许该用户读取机密对象,则该用户可以 运行一个暴露秘密的吊舱。
  • 当前,任何节点上具有root用户的任何人都可以读取 任何 apiserver的秘密 通过模仿小玩意。仅将机密发送到 实际需要它们的节点,以限制根漏洞对 single node.

反馈