kubernetes-the-hard-way 实践指南:生成数据加密配置与加密密钥(etcd 静态加密)
文档/教程【免费下载链接】kubernetes-the-hard-wayBootstrap Kubernetes the hard way on Vagrant on Local Machine. No scripts.项目地址https://gitcode.com/gh_mirrors/kub/kubernetes-the-hard-way点击查看免费下载Kubernetes 将集群状态、应用配置与 Secret 等敏感数据持久化在 etcd 中本指南演示在 kubernetes-the-hard-way 本地集群搭建流程的第 06 步生成一个 32 字节的加密密钥与一份encryption-config.yaml加密配置文件并把该文件分发到两台控制平面节点为后续 kube-apiserver 启用「静态加密encryption at rest」做好准备。读完本节你将掌握 EncryptionConfig 的完整结构、aescbc与identityprovider 的协作语义以及如何在 smoke test 阶段用hexdump验证 Secret 确实以密文形式落盘。本节在整套实验中的位置kubernetes-the-hard-way 的引导流程严格按序推进每一节的产物都会被后续步骤消费。本节第 06 步处于如下位置前序步骤本节内容后续步骤生成 Kubernetes 认证配置文件kubeconfigs生成数据加密密钥与encryption-config.yaml引导 etcd 集群 → 引导 Kubernetes 控制平面本节的产出encryption-config.yaml会在第 08 步被kube-apiserver通过--encryption-provider-config/var/lib/kubernetes/encryption-config.yaml参数引用见 引导 Kubernetes 控制平面并在第 16 步的 smoke test 中接受密文验证见 冒烟测试数据加密验证。因此本节虽然只有寥寥几条命令却是集群数据安全的关键一环。为什么需要加密 etcd 中的数据Kubernetes 会在 etcd 中持久化多种数据集群整体状态、应用配置ConfigMap、以及敏感程度最高的Secret。默认情况下这些数据以明文形式存储——任何能读取 etcd 数据文件或通过 etcd 客户端查询的人都能直接看到 Secret 的原始内容。Kubernetes 原生支持「数据静态加密encryption at rest」即在数据写入 etcd 之前由 kube-apiserver 加密、读取时再解密从而使落盘的数据始终以密文形态存在。本节生成的内容正是为了让 kube-apiserver 具备这一能力一个加密密钥——32 字节随机数据base64 编码后作为对称加密密钥一份加密配置文件——声明「哪些资源需要加密」以及「使用哪个 provider、哪把密钥加密」。注意执行位置为controlplane01本实验将其设定为管理客户端节点即文档内[//]: # (host:controlplane01)注释所标识的主机。前置条件已完成 证书颁发机构与 TLS 证书生成第 04 步与 kubeconfigs 生成第 05 步已通过vagrant sshVirtualBox 环境或multipass shellApple Silicon 环境登录到controlplane01已按 安装客户端工具 配置好节点间的免密 SSH使controlplane01能对controlplane02执行scp/ssh。第一步生成加密密钥在controlplane01上执行ENCRYPTION_KEY$(head -c 32 /dev/urandom | base64)这条命令做了两件事head -c 32 /dev/urandom从 Linux 内核的随机源/dev/urandom中读取32 字节随机数据。32 字节即 256 比特是 AES 等对称加密算法的主密钥长度标准base64将二进制随机数编码为可打印的 base64 字符串使其能安全嵌入 YAML 文件。结果保存在 shell 环境变量ENCRYPTION_KEY中供下一步 heredoc 写文件时直接引用。该变量仅存在于当前 shell 会话重新登录后需要重新生成——这也是本实验刻意采用「裸命令」而非脚本的原因让每一步都可复现、可理解。第二步创建加密配置文件使用 heredoc 将加密配置写入encryption-config.yamlcat encryption-config.yaml EOF kind: EncryptionConfig apiVersion: v1 resources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: ${ENCRYPTION_KEY} - identity: {} EOF生成的文件内容如下其中secret字段为 base64 随机串kind: EncryptionConfig apiVersion: v1 resources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: 32字节随机数据的base64编码 - identity: {}配置字段逐项解析字段取值含义kindEncryptionConfig声明这是一份 Kubernetes 静态加密配置kube-apiserver 通过该 kind 识别文件apiVersionv1配置文件的 API 版本resources数组声明对哪些 API 资源启用加密。这里只列了secrets即仅对 Secret 生效ConfigMap、Event 等仍按默认行为存储providers数组声明加密 provider 及其优先级列表。列表顺序是有语义的见下文aescbc.keys[].namekey1密钥的标识名。它会在 etcd 中随密文一同记录形如k8s:enc:aescbc:v1:key1用于告诉 kube-apiserver 解密时应选用哪把密钥也是后续做密钥轮换的关键锚点aescbc.keys[].secret${ENCRYPTION_KEY}真正的对称加密密钥base64 编码的 32 字节随机数identity: {}空对象透传 provider不加密直接存储作为兜底解密 provideraescbc 与 identity 的协作语义aescbc使用 AES-CBC 模式对资源数据进行对称加密并附带密钥标识前缀。本实验把它放在providers列表的第一位意味着新建/写入的 Secret 一律先用key1这把密钥加密identity不加密、原样存储数据。它被放在第二位充当解密兜底当读取到历史上以明文写入的旧数据例如在启用加密之前就已经存在的 Secret时kube-apiserver 会沿 provider 列表向下寻找能解密的 provider最终由identity原样放行避免老数据因「无法解密」而变得不可读。这正是「第一 provider 用于加密新数据、其余 provider 用于解密存量数据」这一顺序语义在本配置中的体现。如果调换顺序把identity放在第一位新写入的 Secret 将不会加密验证阶段见下文就观察不到k8s:enc:aescbc前缀了。顺带一提密钥轮换的扩展思路本节只创建了key1一把密钥。生产环境中做密钥轮换的通用做法是在aescbc.keys数组的首位新增一把key2同时保留key1providers: - aescbc: keys: - name: key2 # 新密钥新写入数据用它加密 secret: key2 的 base64 - name: key1 # 旧密钥仍保留用于解密存量密文 secret: key1 的 base64这样新数据立即使用新密钥加密而旧数据在轮换过渡期内仍可被解密读取。待存量数据全部重写或主动重加密之后再移除旧密钥条目。本实验的key1命名与验证输出中的前缀一致正是为了演示这一机制而设计的。第三步分发加密配置文件到两台控制平面节点for instance in controlplane01 controlplane02; do scp encryption-config.yaml ${instance}:~/ done这里将encryption-config.yaml同时复制到controlplane01与controlplane02。原因是本实验搭建的是双控制平面高可用集群两台节点各自运行一个 kube-apiserver都可能承担 Secret 的写入或读取请求。只有两台节点的 apiserver 持有同一把key1和同一份 provider 顺序配置才能保证「节点 A 加密写入的数据节点 B 能够解密读取」否则会出现跨节点读写失败或密文不可识别的问题。第四步移动到 apiserver 约定的配置目录for instance in controlplane01 controlplane02; do ssh ${instance} sudo mkdir -p /var/lib/kubernetes/ ssh ${instance} sudo mv encryption-config.yaml /var/lib/kubernetes/ done两步分别完成mkdir -p /var/lib/kubernetes/——创建 Kubernetes 主数据目录。该目录之后还会承载pki/子目录证书与私钥以及各控制面组件的 kubeconfig见 引导 Kubernetes 控制平面 中的sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/等步骤sudo mv encryption-config.yaml /var/lib/kubernetes/——把配置文件从家目录移动到上述目录路径恰好对应后续 kube-apiserver 单元文件中的--encryption-provider-config/var/lib/kubernetes/encryption-config.yaml。安全建议encryption-config.yaml内含对称加密密钥base64 明文等同敏感凭据。生产实践中建议进一步收紧其访问权限例如sudo chmod 600 /var/lib/kubernetes/encryption-config.yaml并仅允许 apiserver 运行账户读取同时密钥本身应纳入密钥管理机制保护。本实验出于教学目的未显式 chmod但你应知晓该文件不应被普通用户可读。与后续步骤的衔接kube-apiserver 如何启用加密本节生成的配置文件本身不会自动生效必须由 kube-apiserver 显式加载。在第 08 步「引导 Kubernetes 控制平面」中两台控制平面节点会创建kube-apiserver.servicesystemd 单元文件其ExecStart中包含见 docs/08-bootstrapping-kubernetes-controllers.md--encryption-provider-config/var/lib/kubernetes/encryption-config.yaml该参数让 apiserver 在启动时读取/var/lib/kubernetes/encryption-config.yaml此后每一条 Secret 的写入都会按 provider 列表执行加密。整个调用链可以概括为kubectl create secret → kube-apiserver → 读取 /var/lib/kubernetes/encryption-config.yaml → 命中第一个 provider aescbc / key1 加密 → 写入 etcd键值带 k8s:enc:aescbc:v1:key1 前缀同理apiserver 也依赖本配置读取旧数据读取时按 provider 列表顺序尝试密文前缀决定实际使用哪把密钥最终由aescbc或identity完成解密返回。验证加密是否真正生效Smoke Test 中的做法配置正确与否在集群跑通后可以用第 16 步 smoke test 的方法直接验证详见 冒烟测试数据加密。核心思路是创建一个 Secret然后直接从 etcd 中把它读出来看是否已是密文。在controlplane01上先创建一个测试 Secretkubectl create secret generic kubernetes-the-hard-way \ --from-literalmykeymydata再通过 etcd 客户端读取并转储十六进制内容sudo ETCDCTL_API3 etcdctl get \ --endpointshttps://127.0.0.1:2379 \ --cacert/etc/etcd/ca.crt \ --cert/etc/etcd/etcd-server.crt \ --key/etc/etcd/etcd-server.key \ /registry/secrets/default/kubernetes-the-hard-way | hexdump -C输出中关键的一行十六进制转储的 ASCII 列为00000030 79 0a 6b 38 73 3a 65 6e 63 3a 61 65 73 63 62 63 |y.k8s:enc:aescbc|也就是说etcd 中该键对应的值以k8s:enc:aescbc:v1:key1前缀开头hexdump里能看到明文的人类可读部分只有/registry/secrets/...键路径与加密元数据前缀mykeymydata的真实内容已被aescbcprovider 用key1加密成不可读的随机字节。这段前缀k8s:enc:aescbc:v1:key1本身就是一份「自描述」enc表示静态加密开启aescbc表示所用 provider 算法v1表示 provider 版本key1表示加密所用密钥的名称——与你在本节配置文件中定义的name: key1一一对应。验证完毕后清理测试资源kubectl delete secret kubernetes-the-hard-way若在 smoke test 中看到identity前缀k8s:enc:identity或完全没有前缀说明 Secret 未加密写入应回头检查本节的 provider 顺序与 apiserver 的--encryption-provider-config参数是否生效。关键要点小结加密密钥32 字节256 位随机数据经 base64 编码保存在ENCRYPTION_KEY变量中用于 AES-CBC 对称加密加密配置kind: EncryptionConfig、apiVersion: v1对secrets资源启用加密provider 列表首位的aescbc负责加密新数据第二位的identity负责解密存量明文数据高可用一致性encryption-config.yaml必须同时部署到controlplane01与controlplane02保证两个 apiserver 用同一把密钥读写 Secret落地位置/var/lib/kubernetes/encryption-config.yaml与 kube-apiserver 的--encryption-provider-config参数路径严格一致见 docs/08-bootstrapping-kubernetes-controllers.md生效时机本步仅完成「生成与分发」加密在 apiserver 启动后才会实际生效最终通过 smoke test 中 etcd 键值前缀k8s:enc:aescbc:v1:key1验证见 docs/16-smoke-test.md。下一步进入 引导 etcd 集群将两台控制平面节点上的 etcd 组装为高可用存储后端上一步回顾可查看 生成 Kubernetes 认证配置文件。赞分享文档/教程【免费下载链接】kubernetes-the-hard-wayBootstrap Kubernetes the hard way on Vagrant on Local Machine. No scripts.项目地址https://gitcode.com/gh_mirrors/kub/kubernetes-the-hard-way点击查看免费下载相关推荐12 个 Doctrine ORM 常见坑与解决方案新手必看的 FAQ 排错指南12 个 Doctrine ORM 常见坑与解决方案新手必看的 FAQ 排错指南 如果你正在使用 Doctrine ORM PHP 生态最流行的对象关系映射云原生教程3步替换游戏里的DLSS版本DLSS Swapper上手指南3步替换游戏里的DLSS版本DLSS Swapper上手指南 朋友的游戏和你的硬件一模一样画面却锐利一圈、帧数也更稳。问了一圈答案不是新显卡而是游戏里那桌面应用Kubernetes The Hard Way 项目中的加密配置问题解析Kubernetes The Hard Way 项目中的加密配置问题解析 在Kubernetes集群部署过程中数据加密是一个至关重要的安全环节。Kuberne教程云原生上一篇照片一键转手绘handraw-style SC-021双拼照片转译图型原理全解析下一篇DeepSeek-V4.1-Flash Prompt 编码全指南解读 encoding.py 的消息格式、工具调用与多模态输入创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考