网页
综合
更新时间 2026-11-13 16:49:35
Secret | Kubernetes
自动蜘蛛
kubernetes.io
正文约 3455 字
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。使用 Secret 意味着你不需要在应用程序代码中包含机密数据。
由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将敏感数据写入非易失性存储。
Secret 类似于 ConfigMap 但专门用于保存机密数据。
默认情况下,Kubernetes Secret 未加密地存储在 API 服务器的底层数据存储(etcd)中。 任何拥有 API 访问权限的人都可以检索或修改 Secret,任何有权访问 etcd 的人也可以。 此外,任何有权限在命名空间中创建 Pod 的人都可以使用该访问权限读取该命名空间中的任何 Secret; 这包括间接访问,例如创建 Deployment 的能力。
为了安全地使用 Secret,请至少执行以下步骤:
有关管理和提升 Secret 安全性的指南,请参阅 Kubernetes Secret 良好实践。
参见 Secret 的信息安全了解详情。
Kubernetes 控制面也使用 Secret; 例如,引导令牌 Secret 是一种帮助自动化节点注册的机制。
通过定义以句点(.)开头的主键,你可以“隐藏”你的数据。 这些主键代表的是以句点开头的文件或“隐藏”文件。 例如,当以下 Secret 被挂载到 secret-volume 卷上时,该卷中会包含一个名为 .secret-file 的文件,并且容器 dotfile-test-container 中此文件位于路径 /etc/secret-volume/.secret-file 处。
以句点开头的文件会在 ls -l 的输出中被隐藏起来; 列举目录内容时你必须使用 ls -la 才能看到它们。
考虑一个需要处理 HTTP 请求,执行某些复杂的业务逻辑,之后使用 HMAC 来对某些消息进行签名的程序。因为这一程序的应用逻辑很复杂, 其中可能包含未被注意到的远程服务器文件读取漏洞, 这种漏洞可能会把私钥暴露给攻击者。
这一程序可以分隔成两个容器中的两个进程:前端容器要处理用户交互和业务逻辑, 但无法看到私钥;签名容器可以看到私钥,并对来自前端的简单签名请求作出响应 (例如,通过本地主机网络)。
采用这种划分的方法,攻击者现在必须欺骗应用服务器来做一些其他操作, 而这些操作可能要比读取一个文件要复杂很多。
除了使用 Secret 来保护机密数据,你也可以选择一些替代方案。
你还可以将如上选项的两种或多种进行组合,包括直接使用 Secret 对象本身也是一种选项。
例如:实现(或部署)一个 Operator, 从外部服务取回生命期很短的会话令牌,之后基于这些生命期很短的会话令牌来创建 Secret。 运行在集群中的 Pod 可以使用这些会话令牌,而 Operator 则确保这些令牌是合法的。 这种责权分离意味着你可以运行那些不了解会话令牌如何发放与刷新的确切机制的 Pod。
创建 Secret 时,你可以使用 Secret 资源的 type 字段,或者与其等价的 kubectl 命令行参数(如果有的话)为其设置类型。 Secret 类型有助于对 Secret 数据进行编程处理。
Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。
通过为 Secret 对象的 type 字段设置一个非空的字符串值,你也可以定义并使用自己 Secret 类型(如果 type 值为空字符串,则被视为 Opaque 类型)。
Kubernetes 并不对类型的名称作任何限制。不过,如果你要使用内置类型之一, 则你必须满足为该类型所定义的所有要求。
如果你要定义一种公开使用的 Secret 类型,请遵守 Secret 类型的约定和结构, 在类型名前面添加域名,并用 / 隔开。 例如:cloud-hosting.example.net/cloud-api-credentials。
当你未在 Secret 清单中显式指定类型时,默认的 Secret 类型是 Opaque。 当你使用 kubectl 来创建一个 Secret 时,你必须使用 generic 子命令来标明要创建的是一个 Opaque 类型的 Secret。 例如,下面的命令会创建一个空的 Opaque 类型的 Secret:
DATA 列显示 Secret 中保存的数据条目个数。 在这个例子中,0 意味着你刚刚创建了一个空的 Secret。
类型为 kubernetes.io/service-account-token 的 Secret 用来存放标识某 ServiceAccount 的令牌凭据。这是为 Pod 提供长期有效 ServiceAccount 凭据的传统机制。
在 Kubernetes v1.22 及更高版本中,推荐的方法是通过使用 TokenRequest API 来获取短期自动轮换的 ServiceAccount 令牌。你可以使用以下方法获取这些短期令牌:
只有在你无法使用 TokenRequest API 来获取令牌, 并且你能够接受因为将永不过期的令牌凭据写入到可读取的 API 对象而带来的安全风险时, 才应该创建 ServiceAccount 令牌 Secret。 更多细节参阅为 ServiceAccount 手动创建长期有效的 API 令牌。
使用这种 Secret 类型时,你需要确保对象的注解 kubernetes.io/service-account-name 被设置为某个已有的 ServiceAccount 名称。 如果你同时创建 ServiceAccount 和 Secret 对象,应该先创建 ServiceAccount 对象。
当 Secret 对象被创建之后,某个 Kubernetes 控制器会填写 Secret 的其它字段,例如 kubernetes.io/service-account.uid 注解和 data 字段中的 token 键值(该键包含一个身份认证令牌)。
下面的配置实例声明了一个 ServiceAccount 令牌 Secret:
创建了 Secret 之后,等待 Kubernetes 在 data 字段中填充 token 主键。
参考 ServiceAccount 文档了解 ServiceAccount 的工作原理。你也可以查看 Pod 资源中的 automountServiceAccountToken 和 serviceAccountName 字段文档, 进一步了解从 Pod 中引用 ServiceAccount 凭据。
如果你要创建 Secret 用来存放用于访问容器镜像仓库的凭据,则必须选用以下 type 值之一来创建 Secret:
下面是一个 kubernetes.io/dockercfg 类型 Secret 的示例:
如果你不希望执行 base64 编码转换,可以使用 stringData 字段代替。
当你使用清单文件通过 Docker 配置来创建 Secret 时,API 服务器会检查 data 字段中是否存在所期望的主键, 并且验证其中所提供的键值是否是合法的 JSON 数据。 不过,API 服务器不会检查 JSON 数据本身是否是一个合法的 Docker 配置文件内容。
你还可以使用 kubectl 创建一个 Secret 来访问容器仓库时, 当你没有 Docker 配置文件时你可以这样做:
此命令创建一个类型为 kubernetes.io/dockerconfigjson 的 Secret。
从这个新的 Secret 中获取 .data.dockerconfigjson 字段并执行数据解码:
输出等价于以下 JSON 文档(这也是一个有效的 Docker 配置文件):
auths 值是 base64 编码的,其内容被屏蔽但未被加密。 任何能够读取该 Secret 的人都可以了解镜像库的访问令牌。
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。