秘密

秘密是包含少量敏感数据(如密码、令牌或密钥)的对象。否则,这些信息可能会放入圆荚体说明或在容器的形象。使用机密意味着您不需要在应用程序代码中包含机密数据。

因为机密可以独立于使用它们的pod创建,所以在创建、查看和编辑pod的工作流中,机密(及其数据)被暴露的风险较小。Kubernetes和集群中运行的应用程序还可以采取额外的保密措施,例如避免将机密数据写入非易失性存储。

秘密类似于配置映射而是专门用来保存机密数据的。

警告:

默认情况下,Kubernetes Secrets未加密存储在API服务器的底层数据存储(etcd)中。任何可以访问API的人都可以检索或修改Secret,任何可以访问etcd的人也可以。此外,任何被授权在名称空间中创建Pod的人都可以使用该访问权限读取该名称空间中的任何Secret;这包括间接访问,例如创建部署的能力。

为了安全使用Secrets,至少要采取以下步骤:

  1. 启用休眠加密的秘密。
  2. 启用或配置RBAC规则限制秘密读取数据(包括通过间接方式)。
  3. 在适当的情况下,还可以使用RBAC等机制来限制允许哪些主体创建新的Secrets或替换现有的Secrets。

秘密的概述

要使用机密,Pod需要引用机密。机密可以通过三种方式与Pod一起使用:

Kubernetes的控制飞机也使用了Secrets;例如,自举牌的秘密是一种帮助自动化节点注册的机制。

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

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

类型的秘密

在创建Secret时,可以使用类型秘密资源的领域,或某些等效的领域kubectl命令行标志(如果可用)。的类型保密性用于促进对不同类型保密数据的程序化处理。

Kubernetes为一些常见的使用场景提供了几个内置类型。这些类型根据所执行的验证和Kubernetes对它们施加的约束而有所不同。

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

可以通过将一个非空字符串赋值为类型Secret对象的值。空字符串被视为不透明类型。Kubernetes没有对类型名施加任何约束。但是,如果您正在使用一种内置类型,则必须满足为该类型定义的所有要求。

不透明的秘密

不透明如果从机密配置文件中省略,则为默认机密类型。使用kubectl,你将使用通用的子命令表示不透明秘密的类型。例如,以下命令创建一个类型为空的Secret不透明

Kubectl create secret generic empty-secret

输出如下所示:

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

数据列显示存储在机密中的数据项的数量。在本例中,0意味着我们创造了一个空洞的秘密。

服务账户令牌

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

以下示例配置声明了服务帐户令牌秘密:

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

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

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

看到serviceaccount.德赢是不是大平台有关服务帐户如何工作的更多信息的文档。你也可以检查automountServiceAccountToken领域和田野serviceAccountName场面的领域圆荚体查看有关从Pods引用服务帐户的信息。

码头工人配置的秘密

您可以使用以下方法之一类型值创建一个秘密,以存储访问Docker图像注册表的凭据。

  • www.amasoeur.com / dockercfg
  • www.amasoeur.com / dockerconfigjson

www.amasoeur.com / dockercfg类型被保留以存储序列化的~/.dockercfg这是配置Docker命令行的遗留格式。当使用这个秘密类型时,你必须确保秘密数据字段包含一个.dockercfg属性的值为内容的键~/.dockercfg文件编码为base64格式。

www.amasoeur.com / dockerconfigjson类型用于存储序列化JSON,该JSON遵循与~ / .docker / json文件是一种新格式~/.dockercfg.当使用这个Secret类型时,数据字段必须包含一个.dockerconfigjson键,其中的内容~ / .docker / json文件以base64编码字符串的形式提供。

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

apiVersionv1友善的秘密元数据的名字secret-dockercfg.类型www.amasoeur.com / dockercfg数据.dockercfg|“< base64编码的~ /。dockercfg文件>”
注意:如果不想执行base64编码,可以选择使用字符串数据字段。

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

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

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

这个命令创建一个Secret类型www.amasoeur.com / dockerconfigjson.如果你倾倒了.dockerconfigjson的内容数据字段,你将得到以下JSON内容,这是一个有效的Docker配置创建的动态:

“身份验证”:{“https://index.docker.io/v1/”:{“用户名”“老虎”,“密码”“pass113”,“电子邮件”“tiger@acme.com”,“授权”“dGlnZXI6cGFzczExMw = = "}}}

基本身份验证的秘密

www.amasoeur.com/basic-auth类型用于存储基本身份验证所需的凭据。当使用这个Secret类型时,数据Secret字段必须包含以下两个密钥:

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

上面两个键的值都是base64编码的字符串。控件当然可以提供清晰的文本内容字符串数据用于创建秘密。

以下YAML是基本身份验证密码的示例配置:

apiVersionv1友善的秘密元数据的名字秘密基本授权类型www.amasoeur.com/basic-auth字符串数据用户名管理密码t0p秘密

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

SSH身份验证秘密

内置类型www.amasoeur.com/ssh-auth用于存储SSH身份验证中使用的数据。使用此机密类型时,必须指定ssh-privatekey键值对数据(或字符串数据字段作为要使用的SSH凭据。

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

apiVersionv1友善的秘密元数据的名字secret-ssh-auth类型www.amasoeur.com/ssh-auth数据#在本例中,数据是缩写的ssh-privatekey|MIIEpQIBAAKCAQEAulqb/Y。。。

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

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

TLS的秘密

Kubernetes提供了一个内置的Secret类型www.amasoeur.com/tls用于存储通常用于TLS的证书及其关联密钥。该数据主要用于入口资源的TLS终止,但也可用于其他资源或直接由工作负载使用。使用此类型的机密时tls.keytls.crt必须在数据(或字符串数据)字段,尽管API服务器并不实际验证每个密钥的值。

以下YAML包含TLS机密的示例配置:

apiVersionv1友善的秘密元数据的名字秘密TLS.类型www.amasoeur.com/tls数据#在本例中,数据是缩写的tls.crt|miic2dccaccgawibagibatanbgkqh ...tls.key|Miiepgibaakcaqea7yn3brhq5fhmq ...

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

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

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

公私钥对必须预先存在。的公钥证书--证书必须是.pem编码(base64-encoded der格式),并匹配给定的私钥——关键.私钥必须是通常所说的PEM私钥格式,未加密。在这两种情况下,PEM的初始和最后一行(例如,——开始证书——结束证书用于证书)包括在内。

自举牌的秘密

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

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

作为Kubernetes清单,引导令牌机密可能如下所示:

apiVersionv1友善的秘密元数据的名字bootstrap-token-5emitj名称空间kube-system类型bootstrap.www.amasoeur.com /令牌数据auth-extra-groupsc3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4 =到期MjAyMC0wOS0xM1QwNDozOToxMFo=令牌idNWVtaXRq象征性秘密a3E0Z2lodnN6emduMXAwcg = =用法 - 引导 - 身份验证dHJ1ZQ = =usage-bootstrap-signingdHJ1ZQ = =

引导类型Secret在下面指定了以下密钥数据

  • 令牌id:作为令牌标识符的随机字符串。必需的。
  • 象征性秘密:一个随机的16个字符串作为实际的令牌秘密。必需的。
  • 描述:人类可读的字符串,描述令牌的用途。可选的。
  • 到期:绝对UTC时间,使用RFC3339指定token应该过期的时间。可选的。
  • usage-bootstrap——<用法>:一个布尔标志,指示引导令牌的额外使用。
  • auth-extra-groups:一个用逗号分隔的组名列表,将通过身份验证系统:引导程序组。

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

apiVersionv1友善的秘密元数据#注意秘密是如何命名的的名字bootstrap-token-5emitj#引导令牌Secret通常驻留在kube-system命名空间中名称空间kube-system类型bootstrap.www.amasoeur.com /令牌字符串数据auth-extra-groups”系统引导程序:kubeadm: default-node-token”到期“2020 - 09 - 13 - t04:39:10z”#此令牌ID用于名称令牌id“5 emitj”象征性秘密“kq4ghvszzgn1p0r”#这个令牌可以用于身份验证用法 - 引导 - 身份验证“真正的”#,可用于签名usage-bootstrap-signing“真正的”

创造秘密

创建秘密有几个选项:

编辑秘密

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

Kubectl编辑secrets mysecret

这将打开默认配置的编辑器,并允许更新数据字段:

#请编辑下面的对象。以“#”开头的行将被忽略,#和空文件将终止编辑。如果在保存此文件时发生错误,则#重新与相关的失败。#apiVersionv1数据用户名女青年4=密码MWYyZDFlMmU2N2Rm友善的秘密元数据注释kubectl.www.amasoeur.com/last-applicated-configuration...}CreationTimestamp.2016 - 01 - 22 - t18:41:56z的名字mysecret名称空间默认的resourceVersion“164619”uidCFEE02D6-C137-11E5-8D73-42010AF00002类型不透明

使用的秘密

秘密可以作为数据卷挂载,也可以作为环境变量由Pod中的容器使用。秘密也可以被系统的其他部分使用,而不会直接暴露给Pod。例如,Secrets可以持有凭证,系统的其他部分应该使用这些凭证代表您与外部系统进行交互。

将Secrets作为Pod中的文件使用

要使用Pod中卷中的机密,请执行以下操作:

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

这是一个在卷中装载秘密的Pod的例子:

apiVersionv1友善的圆荚体元数据的名字mypod规范容器-的名字mypod图像雷迪斯volumeMounts-的名字Foo山路“/ etc / foo”只读的真正的-的名字Foo秘密secretNamemysecret

每个你想要使用的秘密需要被引用.spec.volumes

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

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

将密钥投影到特定路径

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

apiVersionv1友善的圆荚体元数据的名字mypod规范容器-的名字mypod图像雷迪斯volumeMounts-的名字Foo山路“/ etc / foo”只读的真正的-的名字Foo秘密secretNamemysecret项目-关键用户名路径我的小组/用户名

会发生什么:

  • 用户名秘密存储在下面/etc/foo/my group/my username文件,而不是/etc/foo/username
  • 密码秘密不是投射出来的。

如果.spec.volumes []。secret.items,只有在项目预计。要使用密钥中的所有密钥,必须在项目字段。列出的所有密钥必须存在于相应的密钥中。否则,不会创建卷。

秘密文件权限

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

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

apiVersionv1友善的圆荚体元数据的名字mypod规范容器-的名字mypod图像雷迪斯volumeMounts-的名字Foo山路“/ etc / foo”-的名字Foo秘密secretNamemysecretdefaultMode0400

然后,秘密将被安装/etc/foo所有由秘密卷挂载创建的文件都将具有权限0400

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

注意如果你kubectl执行在Pod中,您需要按照符号链接查找预期的文件模式。例如,

检查pod上的机密文件模式。

Kubectl执行mypod -it sh CD /etc/foo ls -l

输出与此类似:

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/.data ls-l

输出与此类似:

total 8 -r-------- 1 root root 12 May 18 00:18 password -r-------- 1 root root 5 May 18 00:18 username

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

apiVersionv1友善的圆荚体元数据的名字mypod规范容器-的名字mypod图像雷迪斯volumeMounts-的名字Foo山路“/ etc / foo”-的名字Foo秘密secretNamemysecret项目-关键用户名路径我的小组/用户名模式0777

在本例中,导致/etc/foo/my group/my username权限值为0777.如果您使用JSON,由于JSON的限制,您必须指定十进制格式的模式,511.

请注意,如果稍后阅读它,则此权限值可能以十进制表示法显示。

使用卷中的秘密值

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

ls /etc/foo/

输出类似于:

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

输出类似于:

管理
cat/etc/foo/password

输出类似于:

1 f2d1e2e67df

容器中的程序负责从文件中读取机密信息。

挂载的秘密将自动更新

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

注意:容器使用Secret作为子路径卷mount将不会收到Secret更新。

使用Secrets作为环境变量

在…中使用秘密环境变量在吊舱中:

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

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

apiVersionv1友善的圆荚体元数据的名字秘密环境舱规范容器-的名字霉菌容器图像雷迪斯环境-的名字SECRET_USERNAMEvalueFromsecretKeyRef的名字mysecret关键用户名-的名字密码valueFromsecretKeyRef的名字mysecret关键密码restartPolicy从来没有

使用环境变量的秘密值

在消耗环境变量中的秘密的容器内,秘密密钥显示为包含秘密数据的Base64解码值的正常环境变量。这是从上面的示例中执行的命令在容器内执行的结果:

回声SECRET_USERNAME美元

输出类似于:

管理
回声SECRET_PASSWORD美元

输出类似于:

1 f2d1e2e67df

在秘密更新之后不会更新环境变量

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

不变的秘密

功能状态: Kubernetes v1.21[稳定]

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

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

此功能由此控制ImmutableEphemeralVolumes功能门从V1.19以来默认启用了。您可以通过设置来创建一个不可改变的秘密不可变的字段真正的.例如,

apiVersionv1友善的秘密元数据...数据...不可变的真正的
注意:一旦Secret或ConfigMap被标记为不可变,它就是不可变的可以恢复此更改,也可以改变数据字段。您只能删除和重新创建秘密。现有的pod保持一个挂载点到已删除的Secret—建议重新创建这些pod。

使用imagePullSecrets

图像秘密字段是对同一命名空间中的秘密的引用列表。你可以用图像秘密向kubelet传递一个包含Docker(或其他)映像注册表密码的秘密。kubelet使用这个信息来获取一个代表Pod的私有映像。看到PodSpec API有关的更多信息图像秘密字段。

手动指定imagePullSecret

您可以学习如何指定ImagePullSecrets容器图像文档德赢是不是大平台

安排imagePullSecrets被自动附加

您可以手动创建图像秘密,并从ServiceAccount引用它。默认情况下,使用该ServiceAccount创建或使用该ServiceAccount创建的任何POD都将获得其图像秘密设置为服务帐户的字段。看到将ImagePullSecrets添加到服务帐户有关该过程的详细说明。

细节

限制

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

秘密资源存在于名称空间.只能由相同名称空间中的Pods引用Secrets。

个人秘密的大小限制为1MiB。这是为了防止创建非常大的机密文件,因为这会耗尽API服务器和kubelet内存。然而,创建许多较小的秘密也可能耗尽内存。更全面的内存使用限制是计划中的特性。

kubelet仅支持对从API服务器获得秘密的豆荚的使用。这包括使用的任何窗口kubectl,或间接通过复制控制器。它不包括由于kubelet而创建的Pods--清单url旗,旗——配置标志,或者它的REST API(这些不是创建pod的常用方法)。的规范静态的豆荚无法引用机密或任何其他API对象。

机密必须在作为环境变量在POD中使用之前创建,除非它们标记为可选。引用不存在的秘密将阻止Pod启动。

参考资料(secretKeyRef字段)到名称秘密中不存在的键将阻止POD开始。

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

kubectl得到事件

输出类似于:

LASTSEEN FIRSTSEEN COUNT NAME KIND subbobject TYPE REASON 0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from EnvFrom secret default/mysecret被跳过,因为它们被认为是无效的环境变量名。

秘密和Pod终身互动

当通过调用Kubernetes API创建Pod时,不检查是否存在引用的秘密。一旦预定了Pod, kubelet将尝试获取秘密值。如果由于秘密信息不存在或由于与API服务器暂时缺乏连接而无法获取它,kubelet将定期重试。它会报告一个关于花苞的事件,解释为什么它还没有开始。获取秘密后,kubelet将创建并挂载包含它的卷。在所有Pod的卷被安装之前,Pod的所有容器都不会启动。

用例

用例:作为容器环境变量

制造秘密

apiVersionv1友善的秘密元数据的名字mysecret类型不透明数据USER_NAME女青年4=密码MWYyZDFlMmU2N2Rm

创建秘密:

kubectl应用-f mysecret.yaml

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

apiVersionv1友善的圆荚体元数据的名字secret-test-pod规范容器-的名字测试容器图像busybox k8s.gcr.io /命令/ bin / sh”,“c”,“env”envFrom-secretRef的名字mysecretrestartPolicy从来没有

用例:带有ssh密钥的Pod

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

Kubectl创建秘密通用ssh-key-secret——from-filessh-privatekey/path/to/.ssh/id\u rsa——来自文件ssh-publickey/path/to/.ssh/d_rsa.pub.

输出类似于:

机密“ssh密钥机密”已创建

您还可以创建kustomization.yaml与一个secretGenerator包含SSH键的字段。

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

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

apiVersionv1友善的圆荚体元数据的名字secret-test-pod标签的名字secret-test规范-的名字secret-volume秘密secretNamessh密钥秘密容器-的名字SSH-Test-Container图像MyShimagevolumeMounts-的名字secret-volume只读的真正的山路“/ etc / secret-volume”

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

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

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

用例:带有prod /测试凭证的pod

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

您可以创建kustomization.yaml与一个secretGenerator场或运行kubectl创建秘密

kubectl create secret generic prod db secret--来自文字用户名本公司——从字面密码Y4nys7f11

输出类似于:

秘密“prod-db-cerfic”创造

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

kubectl create secret泛型测试db secret——来自文字用户名testUser  - 从文字密码iluvtests

输出类似于:

机密“测试数据库机密”已创建
注意:

特殊角色如,,,, 和会被你的需要逃跑。在大多数shell中,转义密码的最简单方法是用单引号括起来().例如,如果您的实际密码是S!B\*d$zDsb=,你应该这样执行命令:

Kubectl创建秘密泛型dev-db-secret——from-literal用户名Demuser --from文字密码“年代!B \ * d zDsb美元= '

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

现在制作豆荚:

< < EOF > pod.yamlapierion:v1种类:列表项目:类型:豆荚apierion:v1元数据:名称:prod-db-client-pod标签:名称:prod-db-client规格:卷:-名称:密卷秘密:secretName: prod-db-secret容器:- 名称:DB-Client-Container图片:myClientImage体积数量:-名称:密卷只读的:真装载路径:“/etc/secret卷”类型:豆荚apierion:v1元数据:名称:test-db-client-pod标签:名称:测试数据库客户端规格:卷:-名称:密卷秘密:secretname:test-db-clefis容器:- 名称:DB-Client-Container图片:myClientImage体积数量:-名称:密卷只读的:真装载路径:“/etc/secret卷”EOF.

将豆荚添加到同一个kustomization.yaml中:

kustomization.yaml资源:——pod.yamlEOF.

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

Kubectl应用-k。

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

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

请注意,两个pod的规格仅在一个领域有所不同;这有助于创建具有与普通Pod模板不同功能的Pod。

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

  1. prod-userprod-db-secret
  2. 试用者,test-db-secret

Pod规范简称为:

apiVersionv1友善的圆荚体元数据的名字产品数据库客户端吊舱标签的名字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图像busybox k8s.gcr.io /命令- - - - - - ls-“- l”-“/ etc / secret-volume”volumeMounts-的名字secret-volume只读的真正的山路“/ etc / secret-volume”

该卷将包含一个名为.secret-file,dotfile-test-container将在路径上存在此文件/etc/secret-volume / .secret-file

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

用例:秘密在豆荚中的一个容器可见

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

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

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

最佳实践

使用秘密API的客户端

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

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

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

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

用于提高循环的性能得到,则客户可以设计引用秘密的资源资源,在引用更改时重新请求秘密。此外,一个“批量监视”API让客户单独的资源也被提出了,并且很可能在Kubernetes的未来版本中可用。

安全性质

保护

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

只有当节点上的Pod需要时,才会将秘密发送到该节点。库贝雷把秘密储存在tmpfs这样秘密就没有写入磁盘存储。一旦删除了依赖于秘密的POD,Kubelet也将删除其本地秘密数据副本。

同一节点上的多个吊舱可能有秘密。然而,只有Pod请求的秘密才可能在其容器中可见。因此,一个豆荚无法接触到另一个豆荚的秘密。

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

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

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

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

风险

  • 在API服务器中,秘密数据存储在etcd;因此:
    • 管理员应该为集群数据启用静态加密(需要v1.13或更高版本)。
    • 管理员应该将etcd的访问权限限制在admin用户。
    • 当etcd不再使用时,管理员可能想要擦除/撕碎已使用的磁盘。
    • 如果在集群中运行etcd,管理员应该确保使用SSL/TLS进行etcd点对点通信。
  • 如果通过清单(JSON或YAML)文件配置机密,其中机密数据编码为base64,则共享此文件或将其签入源存储库意味着机密已被泄露。Base64编码是一种加密方法,被认为与纯文本相同。
  • 应用程序在从卷中读取secret值之后仍然需要保护它,例如不要意外地记录它或将它传输给不受信任的一方。
  • 可以创建使用secret的Pod的用户也可以看到该secret的值。即使API服务器策略不允许用户读取Secret,用户也可以运行公开秘密的Pod。

接下来是什么

最后修改时间为2021年8月4日太平洋标准时间晚上10:35:更新从秘密概念到相关API参考(97c35ce77)的链接