如何旋转所有密钥/凭据 ¶
kOps 管理两种类型的凭据
-
"密钥" 是对称凭据。
-
"密钥对" 是 X.509 证书及其对应私钥的配对。例外是“服务账户”密钥对,它们存储为证书和私钥对,但不使用证书的任何部分,除了公钥。
密钥对根据其用途分组到名为“密钥集”的命名空间中。例如,“kubernetes-ca”密钥集用于集群的 Kubernetes 通用 CA。每个密钥集都有一个主密钥对,即使用其私钥的密钥对。其余的次要密钥对要么是受信任的,要么是不受信任的。受信任的密钥对(包括主密钥对)的证书包含在相关的信任存储中。
旋转密钥对 ¶
引入 |
---|
kOps 1.22 |
您可以通过执行以下过程来优雅地旋转是证书颁发机构或“服务账户”的密钥集的密钥对。当其颁发 CA 旋转时,其他密钥对将通过非干预运行的 kops update cluster
自动重新颁发。
1. 创建并暂存新的密钥对 ¶
为要旋转的每个密钥集创建一个新的密钥对。然后更新集群并执行滚动更新。要暂存所有可旋转密钥集,请运行
kops create keypair all
kops update cluster --yes
kops rolling-update cluster --yes
回滚过程 ¶
此阶段出现故障的可能性很小。要回滚此更改
- 使用
kops get keypairs
获取新创建密钥集的 ID。 - 然后使用
kops distrust keypair
按密钥集和 ID 不信任每个密钥集。 - 然后使用
kops update cluster --yes
- 然后使用
kops rolling-update cluster --yes
2. 导出并分发新的 kubeconfig 证书颁发机构数据 ¶
如果您正在旋转 Kubernetes 通用 CA(“kubernetes-ca”或“all”),并且您没有使用带有其自身独立证书的 Kubernetes API 的负载均衡器,请导出一个新的 kubeconfig,其中包含在集群的 certificate-authority-data
字段中包含的新的 CA 证书
kops export kubecfg
将新的 certificate-authority-data
分发到该集群的 Kubernetes API 的所有客户端。
回滚过程 ¶
要回滚此更改,请分发之前的 kubeconfig certificate-authority-data
。
3. 提升新的密钥对 ¶
使用以下命令将新的密钥对提升为主密钥对
kops promote keypair all
kops update cluster --yes
kops rolling-update cluster --yes
在使用 kops-controller 引导工作节点的云提供商(如 AWS)上,在 kops update cluster --yes
步骤之后,存在一个暂时的节点扩展阻碍。使用新启动模板的实例将无法从旧的 kops-controller 启动。同样,使用旧启动模板且尚未启动的实例将无法从新的 kops-controller 启动。随后的滚动更新最终将替换所有使用旧启动模板的实例。
回滚过程 ¶
此阶段出现故障的最可能原因是 Kubernetes API 的客户端没有获取新的 certificate-authority-data
,因此不信任新的 TLS 服务器证书。
要回滚此更改
- 使用
kops get keypairs
获取之前主密钥集的 ID,最有可能通过识别发行日期来获取。 - 然后使用
kops promote keypair
按密钥集和 ID 提升每个密钥集。 - 然后使用
kops update cluster --yes
- 然后使用
kops rolling-update cluster --yes
4. 导出并分发新的 kubeconfig 管理员凭据 ¶
如果您正在旋转 Kubernetes 通用 CA(“kubernetes-ca”或“all”)并拥有包含集群管理员凭据的 kubeconfig,请导出包含该集群的新管理员凭据的新 kubeconfig
kops export kubecfg --admin=DURATION
其中 DURATION
是管理员凭据的所需生命周期。
将新的凭据分发到需要它们的客户端。
回滚过程 ¶
要回滚此更改,请分发之前的 kubeconfig 管理员凭据。
5. 不信任之前的密钥对 ¶
使用以下命令删除对之前密钥对的信任
kops distrust keypair all
kops update cluster --yes
kops rolling-update cluster --yes
回滚过程 ¶
此阶段出现故障的最可能原因是 Kubernetes API 的客户端仍在使用之前密钥对颁发的凭据。
要回滚此更改
- 使用
kops get keypairs --distrusted
获取之前受信任密钥集的 ID,最有可能通过识别不信任日期来获取。 - 然后使用
kops trust keypair
按密钥集和 ID 信任每个密钥集。 - 然后使用
kops update cluster --yes
- 然后使用
kops rolling-update cluster --force --yes
6. 导出并分发新的 kubeconfig 证书颁发机构数据 ¶
如果您正在旋转 Kubernetes 通用 CA(“kubernetes-ca”或“all”),并且您没有使用带有其自身独立证书的 Kubernetes API 的负载均衡器,请导出一个新的 kubeconfig,其中从集群的 certificate-authority-data
字段中删除了之前的 CA 证书
kops export kubecfg
将新的 certificate-authority-data
分发到该集群的 Kubernetes API 的所有客户端。
回滚过程 ¶
要回滚此更改,请分发之前的 kubeconfig certificate-authority-data
。
旋转 API 服务器加密配置 ¶
有关如何优雅地旋转加密配置中的密钥的信息,请参阅 Kubernetes 文档。
使用 kops create secret encryptionconfig --force
更新加密配置密钥。之后,使用 kops update cluster --yes
和 kops rolling-update cluster --yes
。
旋转 Cilium IPSec 密钥 ¶
有关如何优雅地旋转 Cilium IPSec 密钥的信息,请参阅 Cilium 文档。
使用 kops create secret ciliumpassword --force
更新 cilium-ipsec-keys 密钥。之后,使用 kops update cluster --yes
和 kops rolling-update cluster --yes
。
旋转 Docker 密钥 ¶
[待办事项]
使用 kops create secret dockerconfig --force
更新 Docker 密钥。之后,使用 kops update cluster --yes
和 kops rolling-update cluster --yes
。
旧版过程 ¶
以下是 1.22 之前的 kOps 版本中旋转密钥和密钥对的过程。
这是一个破坏性过程。
1. 删除所有密钥 ¶
删除 kOps 持有的所有密钥和密钥对
kops get secrets | grep '^Secret' | awk '{print $2}' | xargs -I {} kops delete secret secret {}
kops get secrets | grep '^Keypair' | awk '{print $2}' | xargs -I {} kops delete secret keypair {}
2. 重新创建所有密钥 ¶
现在运行 kops update
来重新生成密钥和密钥对。
kops update cluster
kops update cluster --yes
kOps 可能会在第一次尝试时无法重新创建所有密钥。如果遇到关于 'ca' 的 ca 密钥未找到的错误,请再次运行 kops update cluster --yes
。
3. 强制集群使用新密钥 ¶
现在您需要从每个 master 中删除 etcd 证书。
找到所有 master IP。一个简单的方法是运行
kops toolbox dump
然后 SSH 到每个节点并运行
sudo find /mnt/ -name server.* | xargs -I {} sudo rm {}
sudo find /mnt/ -name me.* | xargs -I {} sudo rm {}
您需要重新启动每个节点(使用滚动更新)。您必须使用 --cloudonly
,因为密钥对不再匹配。
kops rolling-update cluster --cloudonly --force --yes
使用新设置重新导出 kubecfg
kops export kubecfg
4. 重新创建所有服务帐户 ¶
现在需要在集群内部重新生成服务帐户令牌
kops toolbox dump
并找到一个 master IP
然后 ssh admin@${IP}
并运行此命令删除所有服务帐户令牌
# Delete all service account tokens in all namespaces
NS=`kubectl get namespaces -o 'jsonpath={.items[*].metadata.name}'`
for i in ${NS}; do kubectl get secrets --namespace=${i} --no-headers | grep "kubernetes.io/service-account-token" | awk '{print $1}' | xargs -I {} kubectl delete secret --namespace=$i {}; done
# Allow for new secrets to be created
sleep 60
# Bounce all pods to make use of the new service tokens
pkill -f kube-controller-manager
kubectl delete pods --all --all-namespaces
5. 验证集群已恢复 ¶
上一节的最后一个命令需要一些时间。同时,您可以检查验证以查看集群正在逐渐恢复在线状态。
kops validate cluster --wait 10m