![如何确保 Kubernetes 中的 Pod 具有相同的密钥?](https://linux22.com/image/744267/%E5%A6%82%E4%BD%95%E7%A1%AE%E4%BF%9D%20Kubernetes%20%E4%B8%AD%E7%9A%84%20Pod%20%E5%85%B7%E6%9C%89%E7%9B%B8%E5%90%8C%E7%9A%84%E5%AF%86%E9%92%A5%EF%BC%9F.png)
我们在 Kubernetes 上部署了安全服务,需要使用相同的私钥来加密和解密我们发送给客户端的 API 令牌。
目前,所有 Pod 都需要具有相同的私钥。例如:
- Pod A 向 Alice 颁发 API 密钥
- 然后 Alice 想要访问一个安全资源
- Alice 发出请求,该请求被路由到 Pod B
- 如果 Pod B 没有与 Pod A 相同的私钥,那么 Pod B 将无法解密密钥进行验证,这意味着 Alice 被错误地锁定
我们希望在 Kubernetes 中找到一种方法来调节与其他 Pod 具有相同私钥的 Pod 的 Pod 活跃度。我意识到如果失败,这可能会造成死亡螺旋的情况,但没关系。我们进行的是蓝绿部署,因此在退化部署启动并运行之前,实时流量永远不会切换到退化部署。
我目前的想法是编写一个脚本,作为活性探测器运行,将私钥文件的校验和与所有其他 pod 的校验和进行比较,从 Kubernetes 内部 API 中提取同级 pod 的列表。
这是因为,在设置镜像拉取策略IfNotPresent
后,在 Pod 部署之间更新了具有相同标签的镜像,因此我们最终破坏了服务,因为不同的私钥位于不同的地方。显然,我们可以将检查添加到我们的部署清单中,但如果有一种方法可以通过实际的部署工具自动执行策略,我觉得这会更强大。
出于某种原因,我也愿意相信这种让多个 Pod 都拥有相同密钥的方法是一种错误的方法。如果有更好的方法来实现这一目标,那么这也将是这个问题的一个有用答案。
答案1
为此秘密已经存在:
Kubernetes
secret
对象可让您存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。将这些信息放在一个文件中secret
比将其逐字放在一个文件中更安全、更灵活荚定义或容器镜像。 看机密设计文档了解更多信息。
如何创造秘密:
使用 kubectl create secret 创建 Secret
假设一些 pod 需要访问数据库。pod 应使用的用户名和密码位于文件中
./username.txt
以及./password.txt
本地计算机上。# Create files needed for rest of example. echo -n 'admin' > ./username.txt echo -n '1f2d1e2e67df' > ./password.txt
该
kubectl create secret
命令将这些文件打包成一个 Secret,并在 Apiserver 上创建对象。kubectl create secret generic db-user-pass --from-file=./username.txt --from file=./password.txt
secret "db-user-pass" created
如何使用秘密:
使用 Secrets
机密可以作为数据卷安装,也可以作为 环境变量 供 pod 中的容器使用。它们也可以由系统的其他部分使用,而无需直接暴露给 pod。例如,它们可以保存系统的其他部分应该用来代表您与外部系统交互的凭据。
在 Pod 中使用 Secrets 作为文件
要使用 Pod 中卷中的 Secret,请执行以下操作:
- 创建一个 secret 或使用现有的 secret。多个 pod 可以引用同一个 secret。
- 修改您的 Pod 定义以在 下添加一个卷
.spec.volumes[]
。将卷命名为任意名称,并使其具有.spec.volumes[].secret.secretName
与 secret 对象名称相等的字段。.spec.containers[].volumeMounts[]
向每个需要机密的容器 添加 。将.spec.containers[].volumeMounts[].readOnly = true
和 指定.spec.containers[].volumeMounts[].mountPath
到您希望机密出现的未使用的目录名称。- 修改您的图像和/或命令行,以便程序在该目录中查找文件。秘密
data
映射中的每个键都将成为下的文件名mountPath
。这是一个在卷中挂载 secret 的 pod 示例:
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo secret: secretName: mysecret
请注意,secret 位于命名空间中。它们只能由同一命名空间中的 pod 引用。完整列表限制位于这里。