秘密

Secret是包含少量敏感数据的对象,例如密码、令牌或密钥。这些信息可能会被放在豆荚规范或在容器图像。使用秘密意味着你不需要在你的应用程序代码。

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

秘密类似于配置映射但专门用于保存机密数据。

请参见机密信息安全了解更多详细信息。

秘密的使用

您可以将“秘密”用于以下目的:

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

用例:秘密卷中的点文件

通过定义以点开头的键,可以将数据“隐藏”。此键表示点文件或“隐藏”文件。例如,当以下秘密装入卷中,分泌量,卷将包含单个文件,打电话.分泌型、和dotfile-测试控制器会有这个文件出现在路径上/etc/secret-volume/.secret-file等.

api版本: 第1版
友善的: 秘密
元数据:
  名称: 点文件机密
数据:
  .分泌型: dmFsdWUtMg0KDQo=
---
api版本: 第1版
友善的: 豆荚
元数据:
  名称: secret-dotfiles-pod文件
规格:
  :
    -名称: 分泌量
      秘密:
        秘书姓名: dotfile机密
  容器:
    -名称: dotfile-测试控制器
      形象: 注册表.k8s.io/busybox
      命令:
        -最小二乘法
        -“-l”
        -“/etc/secret-volume”
      卷装载数:
        -名称: 分泌量
          只读: 真的
          装载路径: “/etc/secret-volume”

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

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

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

使用这种分区方法,攻击者现在必须欺骗应用程序服务器执行某些相当随意的操作,这可能比执行更困难它可以读取文件。

秘密的替代方案

您可以从其他选项中选择,而不是使用“秘密”来保护机密数据。

以下是您的一些选择:

  • 如果云主动组件需要向另一个应用程序进行身份验证know在同一个Kubernetes集群中运行,您可以使用服务帐户及其标识来识别您的客户。
  • 您可以在集群内部或外部运行第三方工具,管理敏感数据的。例如,Pods通过HTTPS访问的服务,如果客户端正确进行身份验证(例如,使用ServiceAccount),则会显示Secret标记)。
  • 对于身份验证,您可以为X.509证书实现自定义签名者,并使用证书签名请求让自定义签名者向需要证书的Pods颁发证书。
  • 您可以使用设备插件向特定Pod公开节点本地加密硬件。例如,您可以安排将受信任的Pod连接到提供受信任平台模块的节点上,该模块是在带外配置的。

您还可以组合两个或多个这些选项,包括使用Secret对象本身的选项。

例如:实现(或部署)操作人员从外部服务获取短期会话令牌,然后创建基于机密的在那些短暂的会话令牌上。集群中运行的Pod可以使用会话令牌,操作员确保它们有效。这种分离意味着您可以运行不知道发出和刷新这些会话令牌的确切机制。

秘密的类型

创建机密时,可以使用类型的字段这个秘密资源或某些同等资源库贝特尔命令行标志(如果可用)。Secret类型用于促进Secret数据的编程处理。

Kubernetes为一些常见的使用场景提供了几种内置类型。这些类型因执行的验证和约束而异库伯内特斯强加给他们。

内置式用法
不透明任意用户定义数据
kubernetes.io/service-account-tokenServiceAccount令牌
kubernetes.io/dockercfg序列化的~/.码头管理文件
kubernetes.io/dockerconfigjson公司序列化的~/.docker/config.json文件
kubernetes.io/basic-授权基本身份验证的凭据
kubernetes.io/ssh-auth公司SSH身份验证的凭据
kubernetes.io/tlsTLS客户端或服务器的数据
bootstrap.kubernetes.io/token引导令牌数据

通过将非空字符串指定为类型Secret对象的值(空字符串被视为不透明类型)。

Kubernetes不会对类型名称施加任何约束。然而,如果您正在使用一种内置类型,则必须满足定义的所有要求对于该类型。

如果要定义一种供公众使用的Secret类型,请遵循约定并构造Secret类型,使域名位于名称之前,分隔开/例如:cloud-hosting.example.net/cloud-api-credentials.

不透明的秘密

不透明如果未在中显式指定类型,则为默认的Secret类型a秘密舱单。当您使用创建秘密时库贝特尔,您必须使用通用的子命令指示不透明秘密类型。例如以下命令创建类型为的空Secret不透明:

kubectl创建秘密通用空秘密kubectl获取机密空机密

输出如下:

名称类型数据年龄空秘密不透明0 2m6s

这个数据列显示存储在机密中的数据项数。在这种情况下,0表示您创建了一个空的秘密。

ServiceAccount令牌机密

A类kubernetes.io/service-account-token机密类型用于存储标识服务帐户.这个是一种遗留机制,为豆荚。

在Kubernetes v1.22及更高版本中,建议的方法是获得使用令牌请求而是API。您可以使用以下方法获取这些短期标记:

使用此机密类型时,需要确保kubernetes.io/service-account.name公司注释设置为现有ServiceAccount名称。如果您同时创建ServiceAccount和如果是Secret对象,则应首先创建ServiceAccount对象。

秘密被创造出来后,一个Kubernetes控制器填写一些其他字段,例如kubernetes.io/服务帐户.uid注释,以及代币键入数据字段,其中填充了身份验证令牌。

以下示例配置声明ServiceAccount令牌Secret:

api版本: 第1版
友善的: 秘密
元数据:
  名称: 分泌物样品
  注释:
    kubernetes.io/服务帐户名称: “sa-name”
类型: kubernetes.io/service-account-token
数据:
  额外的: 年FyCg==

创建秘密后,等待Kubernetes填充代币键入数据字段。

请参阅服务帐户有关ServiceAccounts如何工作的更多信息的文档。您还可以检查automountServiceAccountToken字段和服务帐户名称的字段豆荚有关从Pods中引用ServiceAccount凭据的信息。

Docker配置机密

如果要创建Secret来存储访问容器映像注册表的凭据,您必须使用以下选项之一类型该机密的值:

  • kubernetes.io/dockercfg:存储已序列化的~/.dockercfg公司哪个是用于配置Docker命令行的传统格式。秘密数据字段包含.dockercfg公司值为base64编码~/.dockercfg公司文件。
  • kubernetes.io/dockerconfigjson公司:存储遵循与相同的格式规则~/.docker/config.json文件,这是一种新格式对于~/.dockercfg公司.秘密数据字段必须包含.docker配置值是base64内容的键编码的~/.docker/config.json文件。

下面是一个示例kubernetes.io/dockercfg机密类型:

api版本: 第1版
友善的: 秘密
元数据:
  名称: secret-dockercfg公司
类型: kubernetes.io/dockercfg
数据:
  .dockercfg公司: |
eyJhdXRocy6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=    

使用清单创建Docker config Secrets时,API服务器检查预期的密钥是否存在于数据字段,以及它验证提供的值是否可以解析为有效的JSON。API服务器不会验证JSON是否是Docker配置文件。

您还可以使用库贝特尔创建用于访问容器的密码注册表,例如当您没有Docker配置文件时:

kubectl创建秘密docker-registry秘密docker\--码头-电子邮件=tiger@acme.example\--docker-用户名=老虎\--docker-密码=通过1234\--码头服务器=my-registry。示例:5000

此命令创建类型为的机密kubernetes.io/dockerconfigjson公司.

检索.data.docker配置新秘密的字段并解码数据:

库贝特尔得到了秘密密探蒂格·多克勒-ojson路径=“{.data.*}”|以64为基数-d

输出相当于以下JSON文档(这也是一个有效的Docker配置文件):

{  “身份验证”: {    “my-registry。示例:5000”: {      “用户名”:“老虎”,      “密码”:“通过1234”,      “电子邮件”:"tiger@acme.example",      “授权”:“dGlnZXI6cGFzczEyMzQ=”
}}}

基本身份验证密钥

这个kubernetes.io/basic-授权类型用于存储所需的凭据用于基本身份验证。使用此机密类型时数据的字段机密必须包含以下两个密钥之一:

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

上述两个键的值都是base64编码的字符串。你可以或者使用字符串数据中的字段秘密舱单。

以下清单是基本身份验证密码的示例:

api版本: 第1版
友善的: 秘密
元数据:
  名称: 秘书基础认证
类型: kubernetes.io/basic-授权
字符串数据:
  用户名: 管理员 #kubernetes.io/basic-auth的必填字段
  密码: t0p-机密 #kubernetes.io/basic-auth的必填字段

提供基本身份验证密钥类型只是为了方便。您可以创建不透明用于基本身份验证的凭据的类型。但是,使用定义的和公共机密类型(kubernetes.io/basic-auth公司)帮助他人让人们了解你的秘密的目的,并为密钥名称设置约定期待。

SSH身份验证机密

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

以下清单是用于SSH公共/私有的Secret的示例密钥身份验证:

api版本: 第1版
友善的: 秘密
元数据:
  名称: secret-ssh-auth公司
类型: kubernetes.io/ssh-auth公司
数据:
  #本例中数据被缩写
  ssh密钥: |
UG91cmluZzYlRW1vdGljb24lU2N1YmE型=    

提供SSH身份验证密钥类型只是为了方便。您可以创建不透明用于SSH身份验证的凭据的类型。但是,使用定义的和公共机密类型(kubernetes.io/ssh-auth公司)帮助他人让人们了解你的秘密的目的,并为密钥名称设置约定以期待。Kubernetes API验证是否为此类型的Secret设置了所需的密钥。

TLS机密

这个kubernetes.io/tls机密类型用于存储通常用于TLS的证书及其关联密钥。

TLS Secrets的一个常见用法是为配置传输中的加密一个进入,但您也可以使用它使用其他资源或直接在您的工作负载中。使用此类型的机密时tls.键薄层扫描阴极射线管必须提供密钥数据(或字符串数据)尽管API服务器实际上并不验证每个键的值。

作为使用字符串数据,您可以使用数据要提供的字段base64编码的证书和私钥。有关详细信息,请参阅对机密名称和数据的限制.

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

api版本: 第1版
友善的: 秘密
元数据:
  名称: 分泌型tls
类型: kubernetes.io/tls
数据:
  #值是base64编码的,这会模糊它们,但不会提供
  #任何有用的保密级别
  薄层扫描阴极射线管: |
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVakNDQWJzQ0FnMytNQTBHQ1NxR1NJYjNE公司UUVCQlFVQU1JR2JNUXN3Q1FZRFZRUUdFd0pLVURFT01Bd0cKQTFVRUNCTUZWRzlyZVc4eEVEQU9C无人机Z05WQkFjVEIwTm9kVzh0YTNVeEVUQVBCZ05WQkFvVENFWnlZVzVyTkVSRQpNUmd3RmdZRFZRUUxFdzlYWldKRFpYSjBJRk4xY0hCdmNuUXhHREFXQmdOVkJBTVREMFp5WVc1ck5UkVJRmRsCllpQkRRVEVqTUNFR0NTcUdTSWIzRFFFSkFSWVVjM1Z3Y0c5eWRFQm1jbUZ1YXpSa1pDNWpiMjB3SGhjTk1UTXcKTVRFeE1EUTFNVE01V2hjTk1UZ3dNVEV3TURRMU1UTVXakJMTVFzd0NRWURWUVHFHREFKS1VERVBNQTBHQTFVRQpDQXdHWEZSdmEzbHZNUkV3RHdZRFZRUUtEQWhHY21GdWF6UkVSREVZTUJZR0ExVUVBd3dQZDNkM0xtVjRZVzF3CmJHVSVZMjl0TUlHYU1BMEDDU3FHU0liM0RRRUJBUVVBQTRHSUFE公司Q0JoQUo5WThFaUhmeHhNL25PbjJTbkkxWHgKRHdPdEJEVDFKRjBReTliMVlKanV2YjdjaTEwZjVNVm1UQllqMUZTVWZNOU1vejJDVVFZdW4yRFljV29IcFA4ZQpqSG1BUVrNVd5cDJRN1Armjh1bkli公司QkphVGZlQ09 PekZSUFY2MedTWWUzNmFScG04L3dVVm16eGFLOGTCOWVaCmhPN3F1TjdtSWQxL2pWcTNKODhDQXdFQUFQUQU5CZ2txaGtpRzl3MEJBUVVGQUFPQmdRQU1meTQzeE15OHh3QTUKVjF2T2NSOEtyNWNaSXdtbFhCUU8xeFEzazlxSGtyNFlUY1JxTVQ5WjVKTm1rWHYxK2VSaGcwTi9WMW5NUTRZRgpnWXcxbnlESnBnOTduZUV4VzQyeXVLHSDYyV1hYUUhyOVNVREGrRlowVnQvRGZsdklVTWRjUUFEZjM4aU9zCjlQbG1kb3YrcE0vNCs5ah5aDhSUEkzZXZ6OS9NQT09Ci0tLS0tRU5EIENFULRJRklDQVRFLS0tLS0K型    
  #在本例中,密钥数据不是真正的PEM编码私钥
  tls.键: |
RXhhbXBsZSBkYXRhIGZvciB0aGUgVExTIGNydCBmaWVsZA==    

提供TLS机密类型只是为了方便。您可以创建不透明用于TLS身份验证的凭据的类型。但是,使用定义的和公共机密类型(kubernetes.io/tls)有助于确保项目中Secret格式的一致性。API服务器验证是否为此类型的密码设置了所需的密钥。

使用创建TLS密钥库贝特尔,使用tls公司子命令:

库贝特尔创造秘密tls my-tls-secret\--证书=路径/到/证书/文件\--钥匙=路径/目标/密钥/文件

公钥/私钥对必须先存在。的公钥证书--证书必须是。PEM编码并且必须与的给定私钥匹配--钥匙.

引导令牌秘密

这个bootstrap.kubernetes.io/token密码类型用于节点引导过程中使用的令牌。它存储用于签名的令牌著名的ConfigMaps。

引导令牌Secret通常在库贝体系命名空间和在表单中命名bootstrap-token-<标记-id>哪里<标记-id>是6个字符令牌ID的字符串。

作为Kubernetes的清单,引导令牌Secret可能看起来像以下内容:

api版本: 第1版
友善的: 秘密
元数据:
  名称: bootstrap-token-5emitj
  命名空间: 库贝体系
类型: bootstrap.kubernetes.io/token
数据:
  身份验证额外组: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4=
  到期: MjAyMC0wOS0xM1QwNDozOToxMFo=
  标记id: NWVtaXRq公司
  标记机密: a3E0Z2lodnN6emduMXAwcg==
  usage-bootstrap-身份验证: dHJ1ZQ公司==
  使用引导签名: dHJ1ZQ公司==

引导令牌Secret在下指定了以下密钥数据:

  • 标记id:一个随机的6字符字符串作为令牌标识符。必修的。
  • 象征性秘密:作为实际标记Secret的随机16个字符字符串。必修的。
  • 描述:描述令牌是什么的可读字符串用于。可选。
  • 到期:绝对UTC时间使用RFC3339协议指定标记的时间应过期。可选。
  • usage-bootstrap-<用法>:布尔标志,指示的其他用法引导标记。
  • 身份验证额外组:以逗号分隔的组名列表作为除系统:引导程序组。

您也可以在字符串数据秘密领域不使用base64编码:

api版本: 第1版
友善的: 秘密
元数据:
  #注意秘密是如何命名的
  名称: bootstrap-token-5emitj
  #引导标记Secret通常位于kube-system命名空间中
  命名空间: 库贝系统
类型: bootstrap.kubernetes.io/token
字符串数据:
  身份验证额外组: “系统:引导程序:kubeadm:default-node-token”
  到期: “2020-09-13T04:39:10Z”
  #名称中使用了此令牌ID
  标记id: “5emitj”
  象征性秘密: “kq4gihvszzgn1p0r”
  #此令牌可用于身份验证
  usage-bootstrap-身份验证: “正确”
  #可以用来签名
  usage-bootstrap-signing: “正确”

处理秘密

创造秘密

创建密码有几个选项:

对机密名称和数据的限制

Secret对象的名称必须是有效的DNS子域名.

您可以指定数据和/或字符串数据创建时的字段机密的配置文件。这个数据字符串数据字段是可选的。中所有键的值数据字段必须是以base64编码的字符串。如果不希望转换为base64字符串,可以选择指定这个字符串数据字段,它接受任意字符串作为值。

的键数据字符串数据必须由字母数字字符组成,-,_.。中的所有键值对字符串数据字段在内部合并到数据字段。如果两个数据字符串数据字段中指定的值字符串数据野外拍摄优先。

大小限制

个人秘密的大小限制为1MiB。这是为了阻止创造可能会耗尽API服务器和kubelet内存的非常大的秘密。然而,创建许多较小的秘密也可能耗尽内存。你可以使用资源配额以限制命名空间中机密(或其他资源)的数量。

编辑秘密

您可以编辑现有机密,除非它是不可变的.至编辑密码,请使用以下方法之一:

您还可以使用Kustomize工具然而,这方法创建新的秘密具有编辑数据的对象。

取决于您如何创建秘密,以及如何在中使用秘密您的播客,现有更新秘密对象自动传播到使用数据的吊舱。有关更多信息,请参阅将Secrets用作Pod中的文件第节。

使用秘密

秘密可以作为数据卷装载,也可以作为环境变量供吊舱中的容器使用。秘密也可以被其他部分使用系统,而不直接暴露于Pod。例如,Secrets可以容纳系统其他部分应用于与外部交互的凭据代表您的系统。

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

如果无法获取秘密(可能是因为它不存在,或由于暂时缺乏与API服务器的连接)kubelet定期重试运行该Pod。kubelet也报道了一个事件包括获取机密问题的详细信息。

可选机密

当你在播客中引用秘密时,可以将秘密标记为可选择的,如以下示例中所示。如果可选密码不存在,库伯内特斯对此视而不见。

api版本: 第1版
友善的: 豆荚
元数据:
  名称: 我的豆荚
规格:
  容器:
  -名称: 我的豆荚
    形象: 再贴现
    卷装载数:
    -名称: foo公司
      装载路径: “/etc/foo”
      只读: 真的
  :
  -名称: foo公司
    秘密:
      秘书姓名: 我的秘密
      可选择的: 真的

默认情况下,需要机密。Pod的任何容器都不会启动,直到所有非可选的秘密都可用。

如果Pod引用了非可选Secret和该Secret中的特定密钥不存在,但缺少命名密钥,则Pod在启动过程中失败。

将Secrets用作Pod中的文件

如果你想访问Pod中Secret的数据,一种方法是让Kubernetes把这个秘密的价值作为一个文件放在里面一个或多个Pod容器的文件系统。

有关说明,请参阅使用机密安全地分发凭据.

当卷包含来自Secret的数据并且该Secret被更新时,Kubernetes会跟踪并使用最终一致的方法更新卷中的数据。

kubelet保存中使用的Secrets的当前密钥和值的缓存该节点上pods的卷。您可以配置kubelet检测缓存值更改的方式。这个配置映射和机密更改检测策略中的字段kubelet配置控制库贝莱使用的策略。默认策略是观看.

对Secrets的更新可以通过API监视机制(默认)传播,基于具有定义的生存时间的缓存,或从每个kubelet上的集群API服务器轮询同步回路。

因此,从秘密更新到现在的总延迟当新密钥被投影到Pod时,可以将kubelet同步周期+缓存传播延迟,其中缓存传播延迟取决于所选的缓存类型(按照上一段中列出的相同顺序,这些是:监视传播延迟、配置的缓存TTL或零(用于直接轮询)。

使用Secrets作为环境变量

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

  1. 对于Pod规范中的每个容器,添加一个环境变量对于要用于环境[].valueFrom.secretKeyRef字段。
  2. 修改图像和/或命令行,以便程序查找值在指定的环境变量中。

有关说明,请参阅使用Secret数据定义容器环境变量.

需要注意的是,环境变量允许的字符范围pods中的名称是受限制的.但是,如果有任何键不符合规则,那么这些键就不能用于您的容器允许启动吊舱。

集装箱图片拉秘密

如果要从私有存储库中获取容器图像,需要一种方法每个节点上的kubelet以向该存储库进行身份验证。您可以配置图片拉动秘密使之成为可能。这些秘密在吊舱中配置级别。

使用imagePullSecrets

这个imagePullSecrets图片字段是同一命名空间中对Secrets的引用列表。您可以使用imagePullSecrets图片传递包含Docker(或其他)映像注册表的Secretkubelet的密码。kubelet使用此信息代表您的播客拉取一个私人图像。请参阅PodSpec API有关imagePullSecrets图片字段。

手动指定imagePullSecret

您可以学习如何指定imagePullSecrets图片来自容器图像文档。

安排自动附加imagePullSecrets

您可以手动创建imagePullSecrets图片,并从ServiceAccount引用这些。任何吊舱使用该ServiceAccount创建或默认情况下使用该ServiceAccount创建,将获得其imagePullSecrets图片字段设置为服务帐户的字段。请参见将ImagePullSecrets添加到服务帐户以获得对该过程的详细解释。

在静态吊舱中使用Secrets

您不能将ConfigMaps或Secrets用于静态吊舱.

永恒的秘密

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

Kubernetes允许您将特定的秘密(和ConfigMaps)标记为不可变的.防止更改现有机密的数据有以下好处:

  • 保护您免受可能导致应用程序中断的意外(或不需要的)更新
  • (对于广泛使用Secrets的集群-至少有成千上万个独特的Secret切换到Pod挂载),切换到不可变的Secrets可以提高集群的性能通过显著降低kube-apiserver的负载。kubelet无需维护关注任何标记为不可变的秘密。

将秘密标记为不可变

您可以通过设置不可变的字段到真的例如,

api版本: 第1版
友善的: 秘密
元数据: ...
数据: ...
不可变的: 真的

您还可以更新任何现有的可变Secret以使其不可变。

机密信息安全

虽然ConfigMap和Secret的工作原理类似,但Kubernetes应用了一些额外的保护秘密物品。

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

只有在节点上的Pod需要时,才会向该节点发送Secret。为了将Secrets安装到Pods中,kubelet将数据的副本存储到临时文件系统这样机密数据就不会写入持久存储。一旦依赖秘密的Pod被删除,kubelet就会删除其本地副本秘密中的机密数据。

一个吊舱中可能有几个容器。默认情况下,您定义的容器只能访问默认ServiceAccount及其相关Secret。必须显式定义环境变量或将卷映射到容器以提供对任何其他机密的访问。

同一节点上可能有多个Pod的秘密。然而,只有Pod请求在其容器中可能可见的秘密。因此,一个播客无法访问其他播客的秘密。

配置对机密的最小权限访问

为了加强围绕Secrets的安全措施,Kubernetes提供了一种机制:您可以将ServiceAccount注释为kubernetes.io/enferce-mountable-secrets:“真”.

有关更多信息,请参阅有关此注释的文档.

接下来是什么