跳过至内容

如何旋转所有密钥/凭据

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 --yeskops rolling-update cluster --yes

旋转 Cilium IPSec 密钥

有关如何优雅地旋转 Cilium IPSec 密钥的信息,请参阅 Cilium 文档。

使用 kops create secret ciliumpassword --force 更新 cilium-ipsec-keys 密钥。之后,使用 kops update cluster --yeskops rolling-update cluster --yes

旋转 Docker 密钥

[待办事项]

使用 kops create secret dockerconfig --force 更新 Docker 密钥。之后,使用 kops update cluster --yeskops 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