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,有效值为aescbc和secretbox,默认是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,同时
prepare、rotate、reencrypt被标记为 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_finished且All hashes match(见 secretsencryption_test.go)。也就是说,HA 部署中 hashes 短暂不一致是轮换过程中的正常现象,以最终全部节点 hash 一致作为完成判据。
命令参数说明
secrets-encrypt各子命令(status、enable、disable、prepare、rotate、reencrypt、rotate-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:强制当前阶段,prepare、rotate、reencrypt支持;--skip:reencrypt专用,跳过移除旧 key;-o/--output:status专用,取值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 仅限
aescbc和secretbox,且该参数仍标记为 experimental; - 轮换期间 HA etcd 各 server 的加密哈希短暂不一致属于流程中间状态,不要据此判断失败;
- 每步都以 status 的阶段名作为判断依据,而不是命令是否无报错返回:
start→prepare→rotate→reencrypt_finished; - 旧命令的退役时间表以 secrets-encryption-v3.md 为准,升级到 v1.32/v1.33 时不要再依赖
prepare/rotate/reencrypt单独执行。
【免费下载链接】k3sLightweight Kubernetes项目地址: https://gitcode.com/GitHub_Trending/k3/k3s
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考