秘密

Kubernetes Secrets允许您存储和管理敏感信息,如密码、OAuth令牌和ssh密钥。将机密信息存储在“秘密”中比将其逐字存储在“秘密”中更安全、更灵活圆荚体定义或在一个容器的形象.看到秘密设计文档为更多的信息。

Secret是包含少量敏感数据(如密码、令牌或密钥)的对象。这样的信息可以放在Pod规范或图像中。用户可以创建秘密,系统也可以创建一些秘密。

警告:

默认情况下,Kubernetes秘密存储为未加密的base64编码字符串。默认情况下,任何具有API访问权限的人,或者任何能够访问Kubernetes底层数据存储的人,都可以以纯文本的形式检索它们。为了安全使用Secrets,建议你(至少):

  1. 启用Rest加密的秘密。
  2. 启用或配置RBAC规则限制人们阅读和写作《秘密》请注意,任何人都可以获得秘密的许可,以创建一个Pod。

秘密概述

要使用秘密,花苞必须引用秘密。A Secret可以通过三种方式与Pod一起使用:

Secret对象的名称必须有效DNS域名.你可以指定数据和/或stringData字段创建一个Secret的配置文件时。的数据stringData字段是可选的。中的所有键的值数据字段必须是base64编码的字符串。如果不希望转换为base64字符串,则可以选择指定stringData字段,它接受任意字符串作为值。

的钥匙数据stringData必须由字母数字字符组成,-_.中的所有键值对stringData域内部合并为数据字段。如果一个键出现在数据stringData字段中指定的值stringData领域优先。

类型的秘密

创建Secret时,可以使用类型场的秘密资源,或某种等价物kubectl命令行标志(如果可用)。Secret类型用于促进Secret数据的编程处理。

Kubernetes为某些常见使用方案提供了多种内置类型。这些类型在执行的验证方面变化,并且约束kubernetes对它们施加。

内装式类型 使用
不透明的 任意用户定义的数据
www.mariaabreu.com / service-account-token 服务帐户令牌
www.mariaabreu.com / dockercfg 序列化~ / .dockercfg文件
www.mariaabreu.com / dockerconfigjson 序列化~ / .docker / json文件
www.mariaabreu.com /基本认证 用于基本身份验证的凭据
www.mariaabreu.com / ssh-auth SSH身份验证凭据
www.mariaabreu.com / tls 数据用于TLS客户端或服务器
bootstrap.www.mariaabreu.com /令牌 引导标记数据

属性指定一个非空字符串,从而定义和使用自己的Secret类型类型Secret对象的值。空字符串被视为不透明的类型。Kubernetes对类型名没有任何限制。但是,如果您正在使用其中一种内置类型,则必须满足为该类型定义的所有要求。

不透明的秘密

不透明的是默认的Secret类型,如果在Secret配置文件中省略。当你创建一个秘密使用kubectl,您将使用通用的子命令来指示不透明的秘密的类型。例如,下面的命令创建了类型为空的Secret不透明的

Kubectl create secret generic empty-secret

输出如下所示:

NAME TYPE DATA AGE empty-secret不透明0 2m6

数据列显示存储在Secret中的数据项的数量。在这种情况下,0意味着我们创造了一个空的秘密。

服务帐户令牌

一个www.mariaabreu.com / service-account-token秘密类型用于存储标识服务帐户的令牌。使用此秘密类型时,您需要确保www.mariaabreu.com / service-account.name注释设置为现有服务帐户名称。Kubernetes控制器填充其他一些字段,例如www.mariaabreu.com / service-account.uid注释和令牌的关键数据字段设置为实际的令牌内容。

下面的示例配置声明了一个服务帐户令牌Secret:

apiVersionv1种类秘密元数据名称secret-sa-sample注释www.mariaabreu.com / service-account.name“sa-name”类型www.mariaabreu.com / service-account-token数据#你可以像使用Opaque Secrets一样包含额外的键值对额外的YmFyCg = =

当创建一个圆荚体, Kubernetes自动创建一个服务帐户Secret,并自动修改您的Pod使用这个秘密。服务帐户令牌Secret包含访问API的凭据。

如果需要,可以禁用或覆盖API凭据的自动创建和使用。但是,如果您所需要做的只是安全地访问API服务器,那么这就是推荐的工作流。

看到ServiceAccount乐动体育是干嘛的关于服务帐户如何工作的更多信息的文档。您还可以查看automountServiceAccountToken场和serviceAccountName场的圆荚体获取有关从pod引用服务帐户的信息。

码头工人配置的秘密

你可以使用下面的一种方法类型值来创建一个Secret来存储访问Docker图像注册表的凭证。

  • www.mariaabreu.com / dockercfg
  • www.mariaabreu.com / dockerconfigjson

www.mariaabreu.com / dockercfg类型保留用于存储序列化~ / .dockercfg这是用于配置Docker命令行的遗留格式。当使用这种Secret类型时,您必须确保Secret数据字段包含一个.dockercfg的值为content的键~ / .dockercfg以base64格式编码的文件。

www.mariaabreu.com / dockerconfigjsontype用于存储序列化的JSON,它遵循与~ / .docker / json文件的新格式~ / .dockercfg.使用此秘密类型时,数据秘密对象的字段必须包含一个.dockerconfigjson.的内容~ / .docker / jsonFile作为base64编码的字符串提供。

下面是一个例子www.mariaabreu.com / dockercfg类型的秘密:

apiVersionv1种类秘密元数据名称secret-dockercfg类型www.mariaabreu.com / dockercfg数据.dockercfg|“< base64编码的~ /。dockercfg文件>”
注意:如果不希望执行base64编码,可以选择使用stringData字段。

当您使用清单创建这些类型的Secrets时,API服务器将检查所期望的密钥是否存在于数据字段,它验证提供的值是否可以解析为有效的JSON。如果JSON实际上是Docker配置文件,API服务器不会验证。

当你没有Docker配置文件,或者你想使用kubectl要创建Docker注册表秘密,您可以执行以下操作:

Kubectl创建secret docker-registry secret-tiger docker——docker-username老虎--docker-password.pass113——docker-emailtiger@acme.com

此命令创建类型为Secret的文件www.mariaabreu.com / dockerconfigjson.如果你把.dockerconfigjson.的内容数据字段,你会得到以下JSON内容,这是一个有效的Docker配置动态创建:

“auths”:{“https://index.docker.io/v1/”:{“用户名”“老虎”“密码”“pass113”“电子邮件”“tiger@acme.com”“auth”“dGlnZXI6cGFzczExMw = = "}}}

基本身份验证的秘密

www.mariaabreu.com /基本认证提供类型用于存储基本身份验证所需的凭据。使用此秘密类型时,数据Secret字段必须包含以下两个密钥:

  • 用户名:用于认证的用户名;
  • 密码:认证密码或令牌。

以上两个键的值都是base64编码的字符串。当然,您可以使用stringData用于创建秘密。

下面的YAML是一个基本认证Secret的配置示例:

apiVersionv1种类秘密元数据名称secret-basic-auth类型www.mariaabreu.com /基本认证stringData用户名管理密码t0p-Secret

基本身份验证类型Secret仅为方便用户而提供。你可以创建一个不透明的用于基本身份验证的凭据。但是,使用内置的Secret类型有助于统一凭证的格式,并且API服务器会验证Secret配置中是否提供了所需的密钥。

SSH身份验证的秘密

内装式类型www.mariaabreu.com / ssh-auth用于存储SSH身份验证中使用的数据。当使用此Secret类型时,您将必须指定ssh-privatekey的键值对数据(或stringData)字段作为要使用的SSH凭据。

下面的YAML是SSH认证Secret的配置示例:

apiVersionv1种类秘密元数据名称secret-ssh-auth类型www.mariaabreu.com / ssh-auth数据#数据在本例中缩写ssh-privatekey|MIIEpQIBAAKCAQEAulqb / Y……

SSH的Secret认证方式只是为了方便用户使用。你可以创建一个不透明的用于SSH身份验证的凭据。但是,使用内置的Secret类型有助于统一凭证的格式,并且API服务器会验证Secret配置中是否提供了所需的密钥。

警告:SSH私钥不能单独在SSH客户端和主机服务器之间建立可信的通信。为了减少“中间人”攻击,还需要一种建立信任的第二种方法known_hosts文件添加到ConfigMap。

TLS的秘密

Kubernetes提供了一个内置的Secret类型www.mariaabreu.com / tls用于存储通常用于TLS的证书及其关联密钥。此数据主要用于Ingress资源的TLS终止,但也可以与其他资源一起使用或直接由工作负载使用。当使用这种类型的秘密tls.keytls.crt必须提供钥匙数据(或stringData),尽管API服务器并不实际验证每个密钥的值。

下面的YAML包含一个TLS Secret的配置示例:

apiVersionv1种类秘密元数据名称secret-tls类型www.mariaabreu.com / tls数据#数据在本例中缩写tls.crt|MIIC2DCCAcCgAwIBAgIBATANBgkqh……tls.key|MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ……

为方便用户,提供了TLS Secret类型。你可以创建一个不透明的用于TLS服务器和/或客户机的凭据。然而,使用内置的Secret类型有助于确保项目中的Secret格式的一致性;API服务器会验证Secret配置中是否提供了所需的密钥。

当创建一个TLS秘密使用kubectl,你可以使用tls子命令,示例如下:

Kubectl创建秘密TLS my-tls-secret——证书路径/ /证书/文件——关键/ /键/文件

公钥/私钥对必须预先存在。的公钥证书——证书必须为。pem编码(base64编码DER格式),并且匹配——关键.私钥必须符合普遍称为PEM私钥格式,未加密。在两种情况下,初始和来自PEM的最后一行(例如,--------开始证书-----——结束证书为证书)不是包括在内。

自举牌的秘密

可以通过显式指定Secret来创建引导令牌Secret类型bootstrap.www.mariaabreu.com /令牌.这种类型的Secret是为节点引导过程中使用的令牌设计的。它存储用于为众所周知的ConfigMaps签名的令牌。

引导令牌Secret通常是在kube-system命名空间和在表单中命名bootstrap-token——< token-id >在哪里为6个字符的token ID字符串。

作为Kubernetes的清单,一个引导令牌Secret看起来像这样:

apiVersionv1种类秘密元数据名称bootstrap-token-5emitj名称空间kube-system类型bootstrap.www.mariaabreu.com /令牌数据auth-extra-groupsc3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4 =过期MjAyMC0wOS0xM1QwNDozOToxMFo =token-idNWVtaXRq令牌机密a3E0Z2lodnN6emduMXAwcg = =usage-bootstrap-authenticationdHJ1ZQ = =usage-bootstrap-signingdHJ1ZQ = =

引导类型Secret具有下面指定的键数据

  • token-id:作为令牌标识的随机字符串,长度为6。必需的。
  • 令牌机密:一个随机的16个字符串作为实际的令牌秘密。必需的。
  • 描述:一个人类可读的字符串,它描述了标记的用途。可选的。
  • 过期:使用RFC3339指定令牌何时到期的UTC绝对时间。可选的。
  • usage-bootstrap——<用法>:一个布尔标志,指示引导令牌的额外用法。
  • auth-extra-groups:将被验证的组名的逗号分隔列表系统:Bootstrappers.组。

上面的YAML可能看起来令人困惑,因为这些值都是base64编码的字符串。事实上,你可以使用下面的YAML创建一个相同的Secret:

apiVersionv1种类秘密元数据#注意Secret的名称名称bootstrap-token-5emitj引导令牌Secret通常位于kube-system命名空间中名称空间kube-system类型bootstrap.www.mariaabreu.com /令牌stringDataauth-extra-groups”系统引导程序:kubeadm: default-node-token”过期“2020 - 09 - 13 - t04:39:10z”#此token ID用于名称中token-id“5 emitj”令牌机密“kq4gihvszzgn1p0r”#此令牌可用于身份验证usage-bootstrap-authentication“真正的”#,可以用于签名usage-bootstrap-signing“真正的”

创建一个秘密

创建一个秘密有几个选择:

编辑一个秘密

现有的Secret可以使用以下命令进行编辑:

Kubectl编辑秘密我的秘密

这将打开默认配置的编辑器,并允许更新Base64编码的秘密值数据场地:

#请在下面编辑对象。从'#'开始的行将被忽略,#和空文件将中止编辑。如果在保存此文件时发生错误将是#与相关失败重新开放。apiVersionv1数据用户名YWRtaW4 =密码mwyyzdflmmmu2n2rm种类秘密元数据注释kubectl.www.mariaabreu.com / last-applied-configuration...}creationTimestamp2016-01-22T18:41:56z名称mysecret名称空间默认resourceVersion“164619”uidcfee02d6 c137 - 11 - e5 8 - d73 af00002——42010类型不透明的

使用的秘密

秘密可以作为数据卷挂载,也可以作为环境变量在一个容器中使用。秘密也可以被系统的其他部分使用,而不直接暴露在豆荚。例如,Secrets可以持有系统的其他部分应该用来代表您与外部系统交互的凭证。

把秘密当作豆荚里的文件

在豆荚中消耗一卷秘密:

  1. 创建一个秘密或使用一个现有的。多个豆荚可以引用相同的秘密。
  2. 修改您的Pod定义以在下面添加音量.spec.volumes [].将卷命名为任意名称,并拥有.spec.volumes []。secret.secretname字段等于Secret对象的名称。
  3. 添加一个.spec.containers [] .volumeMounts []给每个需要秘密的容器。指定.spec.containers [] .volumeMounts[]。只读的= true.spec.containers [] .volumeMounts [] .mountPath到一个您希望秘密显示在其中的未使用的目录名。
  4. 修改图像或命令行,以便程序在该目录中查找文件。每一把钥匙中都有秘密数据Map成为文件名下mountPath

这是一个豆荚的例子,在一个卷安装一个秘密:

apiVersionv1种类圆荚体元数据名称mypod.规范容器-名称mypod.图像redis.volumeMounts-名称喷火mountPath“/ etc / foo”只读的真正的-名称喷火秘密secretNamemysecret

你想要使用的每个秘密都需要在.spec.volumes

如果在Pod中有多个容器,那么每个容器需要自己的容器volumeMounts但只有一个.spec.volumes每个Secret都需要。

您可以将许多文件打包成一个秘密文件,或者使用多个秘密文件,以方便的方式选择。

密钥到特定路径的投影

您还可以控制投影秘密密钥的卷内的路径。你可以使用.spec.volumes [] .secret.items字段更改每个键的目标路径:

apiVersionv1种类圆荚体元数据名称mypod.规范容器-名称mypod.图像redis.volumeMounts-名称喷火mountPath“/ etc / foo”只读的真正的-名称喷火秘密secretNamemysecret项目-关键用户名路径我的小组/用户名

会发生什么:

  • 用户名秘密被储存在/etc/foo/my-group/my-username文件而不是/ etc / foo /用户名
  • 密码秘密不是计划。

如果.spec.volumes [] .secret.items中指定的键项目预计。要使用来自秘密的所有密钥,它们必须在项目字段。所有列出的密钥必须存在于相应的密钥中。否则无法创建卷。

秘密文件权限

您可以为单个秘钥设置文件访问权限位。如果您没有指定任何权限,0644.默认为。您还可以为整个Secret卷设置默认模式,并在需要时覆盖每个密钥。

例如,你可以这样指定一个默认模式:

apiVersionv1种类圆荚体元数据名称mypod.规范容器-名称mypod.图像redis.volumeMounts-名称喷火mountPath“/ etc / foo”-名称喷火秘密secretNamemysecretdefaultMode0400.

然后,秘密就会被隐藏起来/etc/foo秘密卷挂载创建的所有文件都将拥有权限0400.

注意JSON规范不支持八进制表示法,所以0400权限使用值256。如果对Pod使用YAML而不是JSON,则可以使用八进制表示法以更自然的方式指定权限。

注意如果你kubectl执行进入Pod后,您需要按照符号链接找到所需的文件模式。例如,

检查吊舱上的机密文件模式。

Kubectl exec mypod -it sh CD /etc/foo ls -l

输出如下所示:

total 0 lrwxrwxrwx 1 root root 15 May 18 00:18 password -> ..数据/password lrwxrwxrwx 1 root root 15 May 18 00:18 username -> ..data/username

按照符号链接找到正确的文件模式。

cd /etc/foo/..ls - l的数据

输出如下所示:

total 8 -r-------- 1 root root 12 May 18 00:18 password -r-------- 1 root root 5 May 18 00:18用户名

你也可以使用映射,就像前面的例子一样,为不同的文件指定不同的权限,就像这样:

apiVersionv1种类圆荚体元数据名称mypod.规范容器-名称mypod.图像redis.volumeMounts-名称喷火mountPath“/ etc / foo”-名称喷火秘密secretNamemysecret项目-关键用户名路径我的小组/用户名模式0777

在本例中,生成的文件/etc/foo/my-group/my-username会有权限值吗0777.如果您使用JSON,由于JSON的限制,您必须指定十进制格式的模式,511

注意,如果稍后读取该权限值,可能会以十进制形式显示。

使用卷中的Secret值

在装载秘密卷的容器中,秘密密钥以文件的形式出现,秘密值以base64解码并存储在这些文件中。这是上面例子中容器内执行命令的结果:

ls /etc/foo/

输出类似于:

用户名密码
猫/etc/foo/username

输出类似于:

管理
猫/etc/foo/password

输出类似于:

1 f2d1e2e67df

容器中的程序负责读取文件中的秘密。

安装的秘密自动更新

当当前在卷中使用的密钥被更新时,投影的密钥最终也会被更新。kubelet会在每个周期同步中检查挂载的秘密是否新鲜。然而,kubelet使用它的本地缓存来获取Secret的当前值。缓存的类型可以使用ConfigMapAndSecretChangeDetectionStrategy田野KubeletConfiguration结构.Secret可以通过watch(默认)、基于ttl或将所有请求直接重定向到API服务器来传播。结果,当秘密的总延迟更新的时候新键将舱可以只要kubelet同步周期+缓存传播延迟,缓存的传播延迟取决于所选择的高速缓存类型(等于看传播延迟,ttl的缓存,或相应的零)。

注意:使用Secret作为子路径卷挂载将不会接收机密更新。

使用Secrets作为环境变量

在。中使用秘密环境变量就象一个豆荚里的:

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

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

apiVersionv1种类圆荚体元数据名称secret-env-pod规范容器-名称mycontainer图像redis.env-名称SECRET_USERNAMEvalueFromsecretKeyRef名称mysecret关键用户名-名称secret_password.valueFromsecretKeyRef名称mysecret关键密码重新启动从来没有

从环境变量中消耗秘密值

在使用环境变量中的秘密的容器中,秘密密钥以普通环境变量的形式出现,其中包含秘密数据的base64解码值。这是上面例子中容器内执行命令的结果:

回声SECRET_USERNAME美元

输出类似于:

管理
回声SECRET_PASSWORD美元

输出类似于:

1 f2d1e2e67df

在进行秘密更新之后,环境变量不会被更新

如果容器已经使用了环境变量中的Secret,则除非重新启动,否则容器不会看到Secret更新。有第三方解决方案可以在秘密改变时触发重启。

不可变的秘密

功能状态: Kubernetes v1.21(稳定)

Kubernetes特性不可变的秘密和配置映射提供了一个选项,可以将单独的Secrets和ConfigMaps设置为不可变。对于广泛使用Secrets的集群(至少有数万个独特的Secret to Pod安装),防止对其数据的更改具有以下优点:

  • 保护您免受可能导致应用程序中断的意外(或不需要的)更新
  • 通过关闭对标记为不可变的秘密的监视,显著降低kube-apiserver上的负载,从而提高集群的性能。

控件控制该特性ImmutableEphemeralVolumes功能门,它从v1.19开始默认启用。属性创建一个不可变的Secret不可变的字段真正的.例如,

apiVersionv1种类秘密元数据...数据...不可变的真正的
注意:一旦秘密或configmap被标记为不可变,就是不是可以恢复此更改,也无法突变数据字段。您只能删除并重新创建秘密。现有的豆荚维护一个挂载点到删除的秘密-建议重新创建这些豆荚。

使用imagePullSecrets

imagePullSecrets字段是同一名称空间中秘密的引用列表。你可以使用imagePullSecrets传递一个包含Docker(或其他)图像注册表密码的秘密给kubelet。kubelet利用这些信息为你的豆荚提取私人图像。看到PodSpec API的详细信息imagePullSecrets字段。

手动指定一个imagePullSecret

你可以学习如何指定imagePullsecrets.集装箱的图片文档乐动体育是干嘛的

安排imagePullSecrets被自动附加

您可以手动创建imagePullSecrets,并从ServiceAccount引用它。任何使用该ServiceAccount创建或默认使用该ServiceAccount创建的Pods,将获得它们的imagePullSecrets字段设置为服务帐户的字段。看到将ImagePullSecrets添加到服务帐户以获得对该过程的详细解释。

细节

限制

对秘密卷源进行验证,以确保指定的对象引用实际指向Secret类型的对象。因此,需要在依赖于它的任何Pods之前创建一个秘密。

秘密资源驻留在名称空间.秘密只能由同一名称空间中的Pods引用。

个人秘密的大小限制为1MiB。这是为了阻止创建非常大的秘密,因为这会耗尽API服务器和kubelet内存。然而,创建许多小秘密也会耗尽内存。由于秘密而对内存使用进行更全面的限制是计划中的特性。

kubelet只支持在从API服务器获取秘密的pod中使用秘密。这包括任何使用创建的Podskubectl,或间接通过复制控制器。它不包括由于kubelet而创建的豆荚——manifest-url国旗,——配置标志,或它的REST API(这些不是创建Pods的常用方法)。

秘密必须在作为环境变量在Pods中使用之前创建,除非它们被标记为可选。提及不存在的秘密会阻止豆荚的启动。

引用(secretKeyRef字段)的密钥不存在在一个命名的秘密将阻止Pod开始。

控件用于填充环境变量的秘密envFrom具有被视为无效环境变量名的键的字段将跳过这些键。荚果可以启动了。会有一个事件,其原因是InvalidVariableNames该消息将包含被跳过的无效键的列表。这个例子显示了一个引用默认/mysecret包含2个无效密钥的pod:1 badkey2 alsobad

kubectl得到事件

输出类似于:

来自EnvFrom秘密default/mysecret的Keys [1badkey, 2alsobad]被跳过了,因为它们被认为是无效的环境变量名。

Secret和Pod终生互动

当调用Kubernetes API创建Pod时,没有检查引用的秘密是否存在。一旦"豆荚"被安排好,库贝莱特就会试图取回秘密价值。如果秘密不能被获取,因为它不存在,或者因为暂时缺少到API服务器的连接,kubelet会定期重试。它会报告一个关于Pod的事件,解释它还没有开始的原因。一旦获取了秘密,kubelet将创建并挂载一个包含它的卷。没有一个豆荚的容器将启动,直到所有豆荚的卷安装。

用例

用例:作为容器环境变量

创建一个秘密

apiVersionv1种类秘密元数据名称mysecret类型不透明的数据用户名YWRtaW4 =密码mwyyzdflmmmu2n2rm

创建一个秘密:

Kubectl应用-f mysecret.yaml

使用envFrom将Secret的所有数据定义为容器环境变量。Secret中的密钥成为Pod中的环境变量名。

apiVersionv1种类圆荚体元数据名称secret-test-pod规范容器-名称测试容器图像k8s.gcr.io/busybox.命令“/ bin / sh”“c”“env”envFrom-secretRef名称mysecret重新启动从来没有

用例:带有ssh密钥的Pod

创建一个包含一些ssh密钥的秘密:

Kubectl创建秘密的通用ssh-key-secret——from-filessh-privatekey/ /路径。ssh / id_rsa——从文件ssh-publickey/ / . ssh / id_rsa . pub /路径

输出类似于:

秘密的“ssh-key-secret”创建

您还可以创建kustomization.yaml与A.secretGeneratorSSH密钥字段。

警告:在发送您自己的ssh密钥之前,请仔细考虑:集群的其他用户可能有权访问这个秘密。使用一个您希望与您共享Kubernetes集群的所有用户都可以访问的服务帐户,如果用户受到威胁,可以撤销该帐户。

现在你可以创建一个Pod,它使用ssh密钥引用秘密,并在卷中消耗它:

apiVersionv1种类圆荚体元数据名称secret-test-pod标签名称secret-test规范-名称secret-volume秘密secretNamessh-key-secret容器-名称ssh-test-container图像mySshImagevolumeMounts-名称secret-volume只读的真正的mountPath“/ etc / secret-volume”

当容器的命令运行时,键的片段将在:

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

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

用例:带有产品/测试凭据的Pods

这个示例演示了一个使用包含生产凭据的秘密的Pod和另一个使用包含测试环境凭据的秘密的Pod。

你可以创建一个kustomization.yaml与A.secretGenerator场或运行熊克创造秘密

Kubectl创建秘密的通用prodd -db-secret -from-literal用户名本公司——从字面密码Y4nys7f11

输出类似于:

秘密的“prod-db-secret”创建

您还可以为测试环境凭据创建一个秘密。

kubectl创建秘密通用测试 - 秘密 - 从文字用户名testuser——从字面密码iluvtests

输出类似于:

秘密的“test-db-secret”创建
注意:

特殊字符,如,将被你解释壳牌并需要逃脱。在大多数shell中,逃避密码的最简单方法是用单引号括起来().例如,您的实际密码为S!B \ * D $ ZDSB =,您应该以这种方式执行命令:

Kubectl创建秘密的通用的dev-db-secret——从字面上用户名devuser——从字面密码“年代!B \ * d zDsb美元= '

您不需要从文件转义密码中的特殊字符(——从文件).

现在制作豆荚:

< < EOF > pod.yamlapiVersion: v1列表:项目:类型:豆荚apiVersion: v1元数据:名称:prod-db-client-pod标签:名称:prod-db-client规范:卷:——名称:secret-volume秘密:secretName: prod-db-secret容器:——名称:db-client-container图片:myClientImagevolumeMounts:——名称:secret-volume只读的:真mountPath:“/ etc / secret-volume”类型:豆荚apiVersion: v1元数据:名称:test-db-client-pod标签:名称:test-db-client规范:卷:——名称:secret-volume秘密:secretName: test-db-secret容器:——名称:db-client-container图片:myClientImagevolumeMounts:——名称:secret-volume只读的:真mountPath:“/ etc / secret-volume”EOF

将POD添加到同一个Kustomization.yaml:

< < EOF > > kustomization.yaml资源:——pod.yamlEOF

通过运行在API服务器上应用所有这些对象:

Kubectl应用-k。

这两个容器的文件系统中都有以下文件,每个容器的环境值如下:

/etc/secret-volume /etc/secret-volume /用户名/密码

注意两个豆荚的规格如何仅在一个字段中不同;这有助于从公共窗格模板创建具有不同功能的POD。

你可以通过使用两个服务帐户来进一步简化基本Pod规范:

  1. prod-user刺激秘密
  2. 测试用户test-db-secret

豆荚规格简称为:

apiVersionv1种类圆荚体元数据名称prod-db-client-pod标签名称prod-db-client规范serviceAccountprod-db-client容器-名称db-client-container图像myClientImage

用例:秘密卷中的dotfiles

您可以通过定义一个以点开头的键来“隐藏”数据。这个密钥表示一个dotfile或“隐藏”文件。例如,当下面的秘密被挂载到一个卷中时,secret-volume

apiVersionv1种类秘密元数据名称dotfile-secret数据.secret-filedmfsdwutmg0kdqo =---apiVersionv1种类圆荚体元数据名称secret-dotfiles-pod规范-名称secret-volume秘密secretNamedotfile-secret容器-名称dotfile-test-container图像k8s.gcr.io/busybox.命令-  ls.-“-l”-“/ etc / secret-volume”volumeMounts-名称secret-volume只读的真正的mountPath“/ etc / secret-volume”

卷将包含单个文件,称为.secret-file,dotfile-test-container这个文件会出现在路径上吗/etc/secret-volume / .secret-file

注意:的输出隐藏以点字符开头的文件ls - l;你必须使用ls -la.在列出目录内容时查看它们。

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

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

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

使用这种分区方法,攻击者现在必须欺骗应用服务器,让它做一些相当随意的事情,这可能比让它读取文件要困难。

最佳实践

使用Secret API的客户机

当部署与Secret API交互的应用程序时,您应该限制使用授权政策RBAC

秘密通常包含一些重要的值,其中许多值可能导致Kubernetes内部(例如服务帐户令牌)和外部系统的升级。即使一个单独的应用程序可以推理出它期望与之交互的秘密的力量,同一名称空间中的其他应用程序也可以使这些假设无效。

由于这些原因手表列表对名称空间内秘密的请求是非常强大的功能,应该避免,因为列出秘密允许客户机检查该名称空间中所有秘密的值。的能力手表列表集群中的所有秘密应该只保留给最有特权的系统级组件。

需要访问Secret API的应用程序应该执行得到他们需要的秘密请求。这使得管理员可以限制访问所有的秘密对单个实例的白名单访问这是应用程序所需要的。

以提高循环的性能得到,客户就可以设计引用秘密的资源手表资源,在引用更改时重新请求秘密。此外,一个“大部分手表”API让客户手表还提出了一些单独的资源,这些资源很可能会在Kubernetes的未来版本中使用。

安全属性

保护

因为可以独立于使用它们的Pods来创建秘密,所以在创建、查看和编辑Pods的工作流中暴露秘密的风险更小。系统还可以对secret采取额外的预防措施,比如尽可能避免将它们写入磁盘。

如果该节点上的POD需要它,则仅发送到节点的秘密。kubelet将秘密存储成一个TMPFS.这样秘密就不会写入磁盘存储。一旦依赖秘密的Pod被删除,kubelet也会删除秘密数据的本地副本。

同一个节点上可能存在多个Pods的秘密。然而,只有Pod请求的秘密可能在其容器中可见。因此,一个荚体不能接触到另一个荚体的秘密。

一个豆荚里可能有几个容器。然而,Pod中的每个容器都必须请求其内部的秘密卷volumeMounts让它在容器中可见。这可以用来构造有用的在Pod级别的安全分区

在大多数Kubernetes发行版上,用户和API服务器之间的通信以及从API服务器到kubelet之间的通信都受到SSL/TLS的保护。秘密在通过这些渠道传输时受到保护。

功能状态: Kubernetes v1.13(β)

您可以启用加密在休息对于秘密数据,使秘密不被存储在清楚中etcd

风险

  • 在API服务器中,存储秘密数据etcd;因此:
    • 管理员应该为集群数据启用静态加密(需要v1.13或更高版本)。
    • 管理员应该限制管理用户对etcd的访问。
    • 管理员可能希望在不再使用时擦除/分解etcd使用的磁盘。
    • 如果在集群中运行etcd,管理员应该确保使用SSL/TLS进行etcd点对点通信。
  • 如果您通过清单(JSON或YAML)文件配置秘密,该文件将秘密数据编码为base64,共享该文件或将其签入到源存储库意味着秘密被破坏了。Base64编码是不是一种加密方法,被认为与纯文本相同。
  • 应用程序仍需要在从卷读取后保护秘密的值,例如不小心记录或将其传输给不受信任的派对。
  • 可以创建使用秘密的Pod的用户还可以看到该秘密的价值。即使API服务器策略不允许用户读取秘密,用户也可以运行Pod来公开秘密。
  • 目前,在任何节点上具有root权限的任何人都可以读取任何秘密从API服务器,通过模拟kubelet。它计划只向实际需要秘密的节点发送秘密,以限制根攻击对单个节点的影响。

接下来是什么

上次修改的2021年5月18日上午10:29太平洋标准时间:修复错误(5 bb726ba1)