使用KMS对etcd数据加密
更新时间:2025-05-23
您可以使用密钥管理服务(Key Management Service,简称:KMS)中创建的密钥加密 Kubernetes Secret 数据。本文主要介绍如何使用 KMS 服务对存储在 etcd 中的 Kubernetes Secret 数据进行加密。
前提条件
- 在 KMS 控制台创建用户主密钥,只支持使用 BAIDU_AES_256 类型的主密钥,详细介绍请参见 密钥管理服务KMS
- 配置 KMS 多用户访问控制 配置 KMS 多用户访问控制
- 使用 KMS 服务会收取费用, CCE 不额外收取费用 KMS产品定价
配置 KMS 多用户访问控制并获取 AKSK
创建子用户
- 主账号用户登录后在控制台选择“多用户访问控制”进入用户管理页面。
- 在左侧导航栏点击“用户管理”,在“用户管理 > 子用户”列表页,点击“创建子用户”,勾选编程访问。
- 下载并保存 AKSK,KMS 插件部署时需使用该 AKSK。
配置策略
- 创建策略:页面左侧选择"策略管理",在新的页面中点击"创建策略",选择"按策略生成器创建"。
- 添加权限:点击添加权限,选择"密钥管理服务 KMS"、"加解密",填写完成后确认。
配置子用户权限
左侧导航栏点击“用户管理 -> 子用户”列表页,在对应子用户右侧点击 "编辑权限",勾选策略并确认。
安装 k8s-cloudkms-plugin 插件
下列操作需要在每台 master 节点上依次执行
下载 k8s-cloudkms-plugin 二进制文件。
Plain Text
1wget -O /opt/kube/bin/k8s-cloudkms-plugin https://cce-plugin.bj.bcebos.com/kms-plugin/v1.0.0/k8s-cloudkms-plugin
2
3chmod +x /opt/kube/bin/k8s-cloudkms-plugin
创建 k8s-cloudkms-plugin 配置文件,并填入必要信息(AKSK 建议使用上文中保存的值),内容如下:
Plain Text
1vim /etc/systemd/system/k8s-cloudkms-plugin.service
2
3[Unit]
4Description=Kubernetes kms plugin
5After=network.target
6
7[Service]
8ExecStart=/opt/kube/bin/k8s-cloudkms-plugin \
9--region={{region}} \
10--key-id={{Kms Key ID}} \
11--access-key={{Access Key ID}} \
12--secret-key={{Secret Access Key}} \
13--kms-endpoint={{Kms Endpoint}}
14Restart=always
15Type=simple
16LimitNOFILE=65536
17
18[Install]
19WantedBy=multi-user.target
北京地域配置如下:
Plain Text
1[Unit]
2Description=Kubernetes kms plugin
3After=network.target
4
5[Service]
6ExecStart=/opt/kube/bin/k8s-cloudkms-plugin \
7--region=bj \
8--key-id=your-kms-key-id \
9--access-key=your-ak-id \
10--secret-key=your-sk-id \
11--kms-endpoint=https://bkm.bj.baidubce.com
12Restart=always
13Type=simple
14LimitNOFILE=65536
15
16[Install]
17WantedBy=multi-user.target
启动 k8s-cloudkms-plugin
Plain Text
1systemctl daemon-reload && systemctl enable k8s-cloudkms-plugin.service && systemctl restart k8s-cloudkms-plugin.service
创建 kms-encryption-config.yaml 例子如下:
Plain Text
1vim /etc/kubernetes/kms-encryption-config.yaml
2
3kind: EncryptionConfiguration
4apiVersion: apiserver.config.k8s.io/v1
5resources:
6 - resources:
7 - secrets
8 providers:
9 - kms:
10 name: cceKMSPlugin
11 endpoint: unix:///var/run/kmsplugin/socket.sock
12 cachesize: 1000
13 timeout: 3s
14 - identity: {}
增加 kube-apiserver启动参数: --encryption-provider-config 开启 etcd 落盘加密:
- kube-apiserver 二进制启动,由 systemd 托管,则按如下方式修改
Plain Text
1# 判断是否为二进制启动, 能看到进程 running
2systemctl status kube-apiserver.service
3
4# 修改 kube-apiserver 启动文件
5vim /etc/systemd/system/kube-apiserver.service
6
7# 新增参数 encryption-provider-config
8--encryption-provider-config=/etc/kubernetes/kms-encryption-config.yaml \
9
10# 重启 kube-apiserver
11systemctl daemon-reload && systemctl restart kube-apiserver.service
- kube-apiserver 容器化部署,则按如下方式修改
Plain Text
1# 判断是否为容器化部署,能看到 apiserver pod
2kubectl get pod -n kube-system | grep kube-apiserver
3
4# 修改 kube-apiserver manifests 文件
5vim /etc/kubernetes/manifests/kube-apiserver.yaml
6
7# 启动参数新增 encryption-provider-config
8- --encryption-provider-config=/etc/kubernetes/kms-encryption-config.yaml
9
10# 将 kmsplugin 挂载到容器内, volumeMounts、volumes 新增 kmsplugin
11volumeMounts:
12 - mountPath: /var/run/kmsplugin
13 name: kmsplugin
14
15volumes:
16 - hostPath:
17 path: /var/run/kmsplugin
18 type: Directory
19 name: kmsplugin
依次操作完所有master节点即可。
验证
-
在集群中新建 Secret
Plain Text1kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
-
执行下列命令,验证 Secret 已正确解密。
Plain Text1# 输出结果为 mydata 2kubectl get secret secret1 -o=jsonpath='{.data.mykey}' | base64 -d
-
(可选)验证 etcd 中数据是否已加密,登录master节点,替换下列命令中的IP为机器IP,并执行:
Plain Text1ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem --endpoints=https://{hostIP}:2379 get /registry/secrets/default/secret1 | hexdump -C 2# 输出结果包含:cceKMSPlugin,且没有明文数据, 则加密成功
-
如需对所有 secret 加密落盘,可执行:
Plain Text1kubectl get secrets --all-namespaces -o json| kubectl replace -f -