旋转Kubernetes中的秘密
目前,我正在Kubernetes之上构建多租户SaaS,我们遵循的一个原则是所有秘密都应该定期轮换。 我对如何在Kubernetes中提供此配置的最佳实践文档的明显缺乏感到惊讶。
当然,在证书方面,使用cert-manager来旋转证书相当简单,但是即使这样还不能完全解决-虽然可以旋转服务证书,但没有直接的方法可以为证书旋转证书。它和它通过信任进行身份验证的其他服务的CA。
对于不基于证书的身份验证(例如对称加密密钥,密码或用于JWT的事物的非对称密钥),实际上并没有什么方法可以做到。
当然,绝对有可能做到这一点,而且我可以在不停机的情况下想出多种不同的方法来做到这一点。 还有多种第三方解决方案(例如HashiCorp Vault)使之成为可能。 但是我想使用Kubernetes原生机制–毕竟,Kubernetes确实提供了秘密管理API,应该可以通过支持秘密轮换的方式来使用它。
因此,我将提出一个约定,可能会成为一种最佳实践,以关于如何以与秘密轮换兼容的方式来管理Kubernetes中的秘密。 我提议的全部是手动的,但是围绕这种方法构建工具以使其自动化应该并不难。
一些原则
首先,为了使秘密轮换发挥作用,我需要概述一些原则。
应该从文件系统读取并重新读取机密
Kubernetes机密的一大优点是,当作为文件系统卷挂载时,使用机密的Pod可以立即获得对机密的更新。 无需重新启动或重新部署,您所需要做的就是更新密码。 但是,要利用此优势,使用机密的代码必须从文件系统中读取它。 它不适用于使用环境变量传递的机密。 此外,代码必须至少定期地从文件系统中重新读取机密,否则它将无法接收更改。
在Akka为加密密钥和证书配置它方面,我们已经取得了成功。 读取机密时,我们会跟踪读取机密的时间戳。 下次访问证书时(下次收到或建立新的TLS连接),如果时间戳记早于5分钟,则将重新读取它。 这样,我们可以在不中断服务的情况下旋转秘密。
机密必须由ID标识
对于TLS证书,密钥的ID内置在证书中,并且TLS实现通常可以配置为使用多个受信任证书。 对于JWT,有一个半内置机制,您可以在密钥ID JWT参数中设置密钥ID。 但是,大多数JWT实现不会默认设置您的设置,有时仅提供有限的支持(如果有)支持基于传入的密钥ID动态选择要使用的密钥。
加密任意数据时,通常没有任何内置机制来指示所使用密钥的ID。 就我而言,当我们加密少量数据时,我们使用的格式是<keyid>:<base64ed initialization vector>:<base64ed cypher text>
。 这使我们能够将每个加密数据与用于加密的密钥相关联。
对于密码,这又变得更加困难,因为通常一次只能使用一个密码。 这里的一种可能性是支持多个用户名,并使用用户名作为密钥ID。
旋转机构
设定了遵循使用我们的机密的代码的原则之后,我们现在可以提出一种在Kubernetes中配置和旋转机密的机制。
Kubernetes机密允许多个键值对。 我们可以利用这一点。 当这些秘密作为卷安装时,文件名对应于键值对中的键。 给定秘密密钥和密钥值密钥之间的名称冲突,我将把密钥值密钥称为文件名。
考虑一下您可能有一个对称密钥(可能用于对JWT签名)的情况。 每个密钥都将获得一个标识符,可以简单地是一个计数器,一个时间戳,一个UUID等。当只使用一个密钥时,文件名可能是<key-id>.key
。 当代码加载密钥时,它将在卷装载的目录中查找名为*.key
所有文件,并将全部加载,并将它们存储在密钥ID到实际密钥内容的映射中。
现在,这在验证JWT时非常有用,因为在开始之前您具有密钥ID,而您只需要选择该密钥ID的机密即可。 但是,在创建JWT时,如果您配置了多个键,则使用哪个键? 重要的是,选择正确的密钥,如果机密只是刚刚被更新以添加第二个密钥,则其他Pod可能尚未拿起第二个密钥,因此,如果您使用第二个密钥对JWT进行签名并发送,对于这些吊舱,他们可能无法对其进行验证。 因此,要解决此问题,我们还将支持通过将其命名为<key-id>.key.primary
来指定主要机密。 只能有一个主要机密,并且永远是用于签名或加密数据的机密。
因此,有了这个设置,这就是我们的旋转机制:
- 给定的秘密以配置的单个密钥开始,假设其ID为
r1
。 id可以是任何东西,我们使用r
表示修订,使用1
表示其第一个密钥,但是id可以是UUID或其他任何值。 密钥将放置在Kubernetes机密中,文件r1.key.primary
。 - 当需要旋转密钥时,将生成一个新密钥,并分配一个新的id
r2
。 kubernetes秘密将被更新,以使其现在同时具有两个密钥,其中r1.key.primary
是旧密钥的文件名,而r2.key
是第二个密钥的文件名。 - 一旦确定所有节点都拾取了新密钥,我们现在就可以将新密钥更改为主密钥。 因此,机密将再次更新,其中
r1.key
是旧密钥的文件名,而r2.key.primary
是新密钥的文件名。 - 一段时间之后,例如,一旦确定由旧密钥签名的所有JWT都已过期,我们将删除旧密钥,更新密钥,使其仅包含一个密钥,文件
r2.key.primary
。
当秘密包含多个部分(例如非对称密钥或自签名证书)时,此方法也可以使用,只需将key
替换为事物名称即可,例如,我可能拥有r2.private
和r2.public
或r2.crt
。
何必呢?
某人自己实现上述目标并不难,但是为什么不建议将其作为最佳实践呢? 如果上述方法将被许多不同的人采用,则将打开以下可能性:
秘密消费支持
秘密使用者可以为该约定提供内置支持。 例如,一个JWT实现可能会提供它,用户只需要将目录传递给它来查找密钥,它将使用它们,并定期重新读取和使用新密钥。 HTTP服务器和客户端也可以这样做,数据库驱动程序也可以这样做。 可以提供实现该约定的泛型库,以便任意秘密使用(例如用于加密)可以轻松使用密钥。
自动旋转
如果有足够的使用者使用该约定,则可以实施自动秘密轮换的工具。 这可以像操作员一样简单,它允许您配置要生成和旋转的机密,并提供给定的参数,例如轮播机密的频率,将新机密设为主要机密之前要等待的时间,然后等待多长时间。删除旧机密之前。 这样的工具还可以配置为创建并等待迁移作业,以允许使用新密钥解密和重新加密静态加密的数据。
利弊
优点
在上面的解释中,许多专家都是不言而喻的,但我能想到的还有更多:
不特定于Kubernetes
代码使用密钥的方式根本不是特定于Kubernetes的。 它可以在可以使用文件系统传递密钥的任何平台上工作。 这包括可能使用静态密钥的开发环境。
Kubernetes原生
尽管不特定于Kubernetes,但该机制是Kubernetes工作方式的本机。 它使用内置的秘密机制,无需任何第三方工具即可使用。 它可以在任何Kubernetes发行版上运行,如果您已经了解Kubernetes机密的工作原理,那么直接了解它的工作原理是很直接的。
没有供应商锁定
这还提供了一种供应商中立的方式来轮换和使用证书。 如今,例如,如果使用HashiCorp Vault,则需要在代码中使用Vault客户端连接到Vault服务器以获取密钥,从而将您的代码与Vault绑定。 此约定允许将管理密钥的任何内容与使用者分离。 这在开发和测试环境中也可能是有利的,例如,由于许可或成本原因,您可能无法在本地计算机上运行供应商机密管理器,因此您可以在那些环境中替换为其他设备。
缺点
当然,公约并非没有弊端。
依赖文件系统
某些人可能会反对使用文件系统来分发机密,而宁愿仅通过经过身份验证的连接来传递机密。 当然,有时需要将一些机密传递给代码–如果代码要通过第三方机密管理器进行身份验证以检索机密,则用于身份验证的机密需要存储在某个位置,例如文件系统或环境变量。
信赖或Kubernetes机密
有些人可能会担心Kubernetes自身存储秘密的方式。 据我了解,我认为这是可插入的或可以加密的(例如,我知道GKE支持与Cloud KMS集成以加密Kubernetes存储的秘密)。 但是在某些情况下,这对于人们来说可能不够好。
更改代码使用机密的方式
从文件系统读取机密的要求可能会破坏通常会消耗配置文件或环境变量的机密的库。
结论
那么,这个约定听起来有用吗? 如果您要添加任何内容,请发表评论!
翻译自: https://www.javacodegeeks.com/2020/03/rotating-secrets-in-kubernetes.html
旋转Kubernetes中的秘密相关推荐
- 在每个运行中运行多个查询_在Kubernetes中运行OpenEBS
什么是OpenEBS? 现在,OpenEBS是kubernetes下与容器原生和容器附加存储类型相关通用的领先开源项目之一. 通过为每个工作负载指定专用的存储控制器,OpenEBS遵循容器附加存储或C ...
- pdm vault 使用_如何使用Key Vault连接器更好地保护Logic Apps中的秘密
pdm vault 使用 One of the key challenges that users face while using Logic Apps is managing secret val ...
- Spring Cloud Kubernetes 中文文档
本参考指南介绍了如何使用Spring Cloud Kubernetes. 1.为什么需要Spring Cloud Kubernetes? Spring Cloud Kubernetes提供了使用Kub ...
- e.V4p.C0/index.php,php-fpm进程在Kubernetes中接收SIGKILL信号
我已经在其中配置了Nginx,PHP和php-fpm创建了ubuntu docker镜像 . 当我在Docker实例上运行它时工作正常 . 但是当我在kubernetes中运行相同的图像时,php-f ...
- 一文详解 Kubernetes 中的服务发现,运维请收藏
K8S 服务发现之旅 Kubernetes 服务发现是一个经常让我产生困惑的主题之一.本文分为两个部分: 网络方面的背景知识 深入了解 Kubernetes 服务发现 要了解服务发现,首先要了解背后的 ...
- 万字长文带你全面认识 Kubernetes 中如何实现蓝绿部署、金丝雀发布和滚动更新...
Kubernetes 中的部署策略 在本文中,我们将学习使用 Kubernetes 容器编排系统部署容器时的部署策略.在本文的最后,我们将学习如何在 Kubernetes 集群中使用不同的方式进行部署 ...
- 浅谈 Kubernetes 中的服务发现
原文:https://nigelpoulton.com/blog/f/demystifying-kubernetes-service-discovery Kubernetes 服务发现是一个经常让我产 ...
- CloudBees发布“Jenkins X”:面向部署到Kubernetes中的现代云应用的CI/CD解决方案
\ 看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料! \ \\ James Strachan和CloudBees团队发布了开源的"Jenkins ...
- 如何在 Kubernetes 中对无状态应用进行分批发布
在 Kubernetes 中针对各种工作负载,提供了多种控制器,其中 Deployment 为官方推荐,被用于管理无状态应用的 API 对象.本文将结合 Deployment 的特性,与常见的发布策略 ...
- Rook存储:Kubernetes中最优秀的存储
本文讲的是Rook存储:Kubernetes中最优秀的存储[编者的话]Rook存储集群,其实是在著名的分布式存储系统Ceph的一个封装,以Kubernetes Application的方式运行了监控. ...
最新文章
- UNIX环境高级编程 第12章 线程控制
- golang中strings.ToUpper
- 【正一专栏】贾乃亮发文后李小璐会如何回应?
- android 如何实现无限列表,在Android中解析和创建无限/无限级别的List /子列表中的XML...
- php的配置工具,星外php自动配置工具
- C - Insertion Sort Gym - 101955C
- MATLAB的GUI如何清空坐标轴的图像
- 2018年12月精选文章目录一览
- 【NodeJS 学习笔记03】先运行起来再说
- Oracle 客户端连接server 的方法
- 如何关闭MyEclipse自动更新
- python解释型语言_python是解释型语言吗?会被编译吗?
- armv6, armv7, armv7s, arm64 的区别
- Java根据信用卡号区分国际常用的五大信用卡卡种:VISA,Master,AE,DC,JCB.
- 塞班s60v3手电筒sisx_塞班s60v3 手电筒
- Ubuntu20.04 搭建repo + gitlab的代码管理系统
- 有关rand(),srand()产生随机数学习总结
- IIC方式读驱动AT24C16芯片
- python笔记打卡
- 前百度总裁陆奇:我给有梦想的年轻人9点建议
热门文章
- 多旅行商问题(MTSP)的相关论文总结
- python判断图片相似度_图像检索系列——利用 Python 检测图像相似度!
- Win10锁屏壁纸位置在哪?默认锁屏壁纸怎么提取
- 在线SVG转换,支持SVG to PNG、SVG to JPEG、SVG to WEBP 图片转换操作-toolfk程序员在线工具网
- 计算机病毒如何彻底去除,电脑中病毒最彻底的清除方法 彻底清理删除电脑病毒的几种简单方法...
- android获取手机信息的权限,如何开启获取手机信息权限
- python读取csv最后一行_用Python读取CSV文件行的最后一个非空单元格
- 智能音箱---TAS5754M 音频DSP 到Android
- 怎么下载正版java7_Java7中jdk的下载和安装
- 猴子摘桃c语言程序,猴子摘桃c语言