K3s 如何启用 secrets 静态加密并完成 prepare、rotate、reencrypt 密钥轮换流程
2026/9/12 8:46:40 网站建设 项目流程

K3s 如何启用 secrets 静态加密并完成 prepare、rotate、reencrypt 密钥轮换流程

【免费下载链接】k3sLightweight Kubernetes项目地址: https://gitcode.com/GitHub_Trending/k3/k3s

本文面向已部署 K3s 集群的运维人员,任务是完成两件事:启用 secrets 静态加密(encryption at rest),并在需要时完成一次完整的加密密钥轮换。轮换支持单 server(sqlite)和 HA etcd 两种部署形态。整个流程通过k3s server--secrets-encryption参数和k3s secrets-encrypt子命令完成,每一步都有k3s secrets-encrypt status输出的阶段名(stage)可以作为判断依据。

第一步:用 --secrets-encryption 启动 server 启用静态加密

在 server 节点启动 K3s 时加上--secrets-encryption参数:

k3s server --secrets-encryption

该参数在 server.go 中的说明是 "Enable secret encryption at rest"。加密 provider 可选:

k3s server --secrets-encryption --secrets-encryption-provider aescbc

--secrets-encryption-provider标记为 experimental,有效值为aescbcsecretbox,默认是aescbc(见 server.go)。provider 逻辑上支持 AESCBC、SecretBox 和 Identity 三类,其中 Identity 只表示加密开/关;遇到 AES-GCM 或 KMS 配置会直接报 "unsupported encryption keys found"(见 config.go)。

启动完成后,用 status 子命令确认加密已生效:

k3s secrets-encrypt status

输出中应包含以下三行(下面为示例结果,key 名中的年份和阶段名来自测试断言):

Encryption Status: Enabled Current Rotation Stage: start Server Encryption Hashes: All hashes match

如果集群此前从未配置过加密,输出会是Encryption Status: Disabled, no configuration file found;集成测试中,新启用加密的 server 状态是Enabled且阶段为start(见 secretsencryption_int_test.go)。HA 部署时建议在每台 server 上分别执行 status,Server Encryption Hashes一行显示All hashes match表示各 server 的加密配置哈希一致。

执行 prepare → rotate → reencrypt 轮换流程

完整流程为:prepare→ 重启 server →rotate→ 重启 server →reencrypt(见 secrets-encryption-v3.md)。两种部署形态的差异只在重启次数:

  • 单 server(sqlite):中间各重启一次 server;
  • HA etcd:每步之后重启所有k3s server,且reencrypt之后还要再重启一次所有 k3s server。

1. prepare:申请新的加密 key

k3s secrets-encrypt prepare

命令成功时输出prepare completed successfully。随后查状态:

k3s secrets-encrypt status

此时Current Rotation Stage变为prepare,且 status 会列出 2 把 AES-CBC key:当前激活的aescbckey,以及新加入的aescbckey-<年份>(集成测试按此断言,见 secretsencryption_int_test.go)。

2. 重启 server

单 server 重启该 server;HA etcd 重启所有 k3s server(仓库根目录随附 k3s.service,systemd 部署下即重启 k3s 服务)。重启后确认 status 阶段仍为prepare,且集群内 Pod 恢复正常。

3. rotate:切换激活 key

k3s secrets-encrypt rotate

成功输出rotate completed successfully。status 中Current Rotation Stage变为rotate,且激活 key(带*标记)变为aescbckey-<年份>,旧 key 退居 inactive(测试断言见 secretsencryption_int_test.go)。

4. 再次重启 server

与第 2 步相同:单 server 重启一次;HA etcd 重启所有 k3s server。重启后 status 阶段为rotate

5. reencrypt:用新 key 重加密存量数据

k3s secrets-encrypt reencrypt

命令返回reencryption started表示任务已提交,重加密是后台异步进行的。轮询 status 直到:

Current Rotation Stage: reencrypt_finished

完成后 status 中只剩 1 把 key(aescbckey-<年份>),旧 key 已被移除。HA etcd 部署在此之后再重启一次所有 k3s server(这是 secrets-encryption-v3.md 中 HA etcd 流程的第 6 步)。

可选分支:rotate-keys 一步轮换

如果 K3s 版本较新,可以不走上面 5 步流程。k3s secrets-encrypt rotate-keys会动态轮换 key 并自动完成重加密,按 secrets-encryption-v3.md 的版本计划:

  • v1.28 起引入,标记为 experimental;
  • v1.29 起 GA,同时preparerotatereencrypt被标记为 deprecated,执行时会给出警告并建议使用rotate-keys
  • 最终在 v1.32 或 v1.33 执行时变为致命错误,v1.34 从代码中移除。

rotate-keys的流程:

  • 单 server(sqlite):只需在 server 上执行一次k3s secrets-encrypt rotate-keys
  • HA etcd:执行rotate-keys后仍需重启所有 k3s server。

e2e 测试展示了 HA 3 server 场景下的状态演变:在 server 0 上执行rotate-keys后,该节点阶段会到达reencrypt_finished,其余节点停留在start,且Server Encryption Hashes显示hash does not match;重启全部 server 后,所有节点都达到reencrypt_finishedAll hashes match(见 secretsencryption_test.go)。也就是说,HA 部署中 hashes 短暂不一致是轮换过程中的正常现象,以最终全部节点 hash 一致作为完成判据。

命令参数说明

secrets-encrypt各子命令(statusenabledisablepreparerotatereencryptrotate-keys)在 secrets_encrypt.go 中定义,常用参数:

  • -d/--data-dir:数据目录。如果你用非默认目录启动 server,执行子命令时必须带上同一目录,例如k3s secrets-encrypt status -d /tmp/k3sse(集成测试即如此使用);
  • --server/-s:要连接的 server,默认https://127.0.0.1:6443,可用环境变量K3S_URL覆盖;
  • --token:server token。不带时命令会读取数据目录下的token文件;
  • -f/--force:强制当前阶段,preparerotatereencrypt支持;
  • --skipreencrypt专用,跳过移除旧 key;
  • -o/--outputstatus专用,取值text(默认)或json

另外两个与开关相关的子命令:k3s secrets-encrypt enable/disable输出secrets-encryption enabled/secrets-encryption disabled。关闭加密后如需把存量数据恢复为明文存储,集成测试中的做法是:

k3s secrets-encrypt disable k3s secrets-encrypt reencrypt -f --skip

然后重启 server,status 应显示Encryption Status: Disabled(见 secretsencryption_int_test.go)。注意--skip的用途是"跳过移除旧 key",-f用于强制该阶段,两者在此组合中用于在已禁用状态下触发 reencrypt。

边界与限制

  • 加密 provider 仅限aescbcsecretbox,且该参数仍标记为 experimental;
  • 轮换期间 HA etcd 各 server 的加密哈希短暂不一致属于流程中间状态,不要据此判断失败;
  • 每步都以 status 的阶段名作为判断依据,而不是命令是否无报错返回:startpreparerotatereencrypt_finished
  • 旧命令的退役时间表以 secrets-encryption-v3.md 为准,升级到 v1.32/v1.33 时不要再依赖prepare/rotate/reencrypt单独执行。

【免费下载链接】k3sLightweight Kubernetes项目地址: https://gitcode.com/GitHub_Trending/k3/k3s

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询