使用KMS对etcd数据加密
更新时间:2022-12-01
您可以使用密钥管理服务(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 二进制文件。
wget -O /opt/kube/bin/k8s-cloudkms-plugin https://cce-plugin.bj.bcebos.com/kms-plugin/v1.0.0/k8s-cloudkms-plugin
chmod +x /opt/kube/bin/k8s-cloudkms-plugin
创建 k8s-cloudkms-plugin 配置文件,并填入必要信息(AKSK 建议使用上文中保存的值),内容如下:
vim /etc/systemd/system/k8s-cloudkms-plugin.service
[Unit]
Description=Kubernetes kms plugin
After=network.target
[Service]
ExecStart=/opt/kube/bin/k8s-cloudkms-plugin \
--region={{region}} \
--key-id={{Kms Key ID}} \
--access-key={{Access Key ID}} \
--secret-key={{Secret Access Key}} \
--kms-endpoint={{Kms Endpoint}}
Restart=always
Type=simple
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
北京地域配置如下:
[Unit]
Description=Kubernetes kms plugin
After=network.target
[Service]
ExecStart=/opt/kube/bin/k8s-cloudkms-plugin \
--region=bj \
--key-id=your-kms-key-id \
--access-key=your-ak-id \
--secret-key=your-sk-id \
--kms-endpoint=https://bkm.bj.baidubce.com
Restart=always
Type=simple
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
启动 k8s-cloudkms-plugin
systemctl daemon-reload && systemctl enable k8s-cloudkms-plugin.service && systemctl restart k8s-cloudkms-plugin.service
创建 kms-encryption-config.yaml 例子如下:
vim /etc/kubernetes/kms-encryption-config.yaml
kind: EncryptionConfiguration
apiVersion: apiserver.config.k8s.io/v1
resources:
- resources:
- secrets
providers:
- kms:
name: cceKMSPlugin
endpoint: unix:///var/run/kmsplugin/socket.sock
cachesize: 1000
timeout: 3s
- identity: {}
增加 kube-apiserver启动参数: --encryption-provider-config 开启 etcd 落盘加密:
- kube-apiserver 二进制启动,由 systemd 托管,则按如下方式修改
# 判断是否为二进制启动, 能看到进程 running
systemctl status kube-apiserver.service
# 修改 kube-apiserver 启动文件
vim /etc/systemd/system/kube-apiserver.service
# 新增参数 encryption-provider-config
--encryption-provider-config=/etc/kubernetes/kms-encryption-config.yaml \
# 重启 kube-apiserver
systemctl daemon-reload && systemctl restart kube-apiserver.service
- kube-apiserver 容器化部署,则按如下方式修改
# 判断是否为容器化部署,能看到 apiserver pod
kubectl get pod -n kube-system | grep kube-apiserver
# 修改 kube-apiserver manifests 文件
vim /etc/kubernetes/manifests/kube-apiserver.yaml
# 启动参数新增 encryption-provider-config
- --encryption-provider-config=/etc/kubernetes/kms-encryption-config.yaml
# 将 kmsplugin 挂载到容器内, volumeMounts、volumes 新增 kmsplugin
volumeMounts:
- mountPath: /var/run/kmsplugin
name: kmsplugin
volumes:
- hostPath:
path: /var/run/kmsplugin
type: Directory
name: kmsplugin
依次操作完所有master节点即可。
验证
-
在集群中新建 Secret
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
-
执行下列命令,验证 Secret 已正确解密。
# 输出结果为 mydata kubectl get secret secret1 -o=jsonpath='{.data.mykey}' | base64 -d
-
(可选)验证 etcd 中数据是否已加密,登录master节点,替换下列命令中的IP为机器IP,并执行:
ETCDCTL_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 # 输出结果包含:cceKMSPlugin,且没有明文数据, 则加密成功
-
如需对所有 secret 加密落盘,可执行:
kubectl get secrets --all-namespaces -o json| kubectl replace -f -