基本概念
KMS,Key Management Service,即密钥治理服务,在 K8S 集群中,以驱动和插件的模式启用对 Secret,Configmap 进行加密。以爱护敏感数据,
驱动和插件须要使用者依照需要进行定制和实现本人的 KMS 插件,插件能够是 gRPC 服务器或者启用一个云服务商提供的 KMS 插件。
本文中演示应用的 KMS 服务是京东云舰中的 KMS 加密服务。
目前 KMS 分为 V1,V2,本文基于 V1 进行演示。
架构
外部能够利用 kms 加密实现本人的加密算法,甚至国密算法。
当用户新建 secret 资源时,kube-apiserver 会通过 gRPC 调用 kms-plugin,而 kms-plugin 与加密服务器通信,进行数据加密。
此时如果通过间接获取 etcd 中的原始数据,内容为密文数据。
当用户获取 secret 资源内容时,kube-apiserver 会通过 gRPC 调用 kms-plugin,而 kms-plugin 与加密服务器通信,进行数据解密,将明文展现给用户
操作步骤
须要一套曾经运行的 Kubernetes 集群服务,如果是多台 master 节点,须要同时配置。
新建目录
/etc/kubernetes/kms/jdcloud
新建 EncryptionConfiguration
该配置是 kms 根本的加密配置,包含加密资源对象,socket 地址等等。
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets # 这里示意,只加密 secret
providers:
- kms:
name: myKmsPlugin
endpoint: unix:///var/run/k8s-kms-plugin/kms-plugin.sock # 如果不以 pod(jdcloud-kms-plugin.yaml)启动,须要 sock 文件放到 master 节点。cachesize: 100
timeout: 3s
- identity: {}
以上内容保留在 /etc/kubernetes/kms/jdcloud/apiserver-encryption.conf
新建 jdcloud kms plugin 配置
kms server 的上联信息配置
{
"AccessKey": "xxx", # 部署前,该参数须要事后晓得,"SecretKey": "yyy", # 部署前,该参数须要事后晓得。"KmsEndpoint": "kms.internal.cn-north-1.jdcloud-api.com", # 部署前,该参数须要事后晓得。"KmsKeyId": "abcd", # 部署前,该参数须要事后晓得。"KmsSchema": "http",
"GRPCSocketPath": "/var/run/k8s-kms-plugin/kms-plugin.sock"
}
以上内容保留在 /etc/kubernetes/kms/jdcloud/jdcloud-kms-plugin.json
新建 jdcloud kms plugin 服务
该服务是启动 socket 服务,并依照配置和上联的 kms server 进行通信,加密和解密数据,并通过 socket 服务和 K8S APIServer 交互。
该 pod 须要在 kube-apiserver 启动之前启动,否则与 apiserver 可能产生循环依赖。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: jdcloud-kms-plugin
tier: control-plane
name: jdcloud-kms-plugin-node-01
namespace: kube-system
spec:
containers:
- command:
- /k8s-kms-plugin
- -f=/etc/kubernetes/kms/jdcloud/jdcloud-kms-plugin.json # 指定 json
image: hub-pub.jdcloud.com/k8s/jdcloudsec/k8s-kms-plugin:v1.0.1
imagePullPolicy: IfNotPresent
name: jdcloud-kms-plugin
resources:
requests:
cpu: 250m
volumeMounts:
- mountPath: /etc/kubernetes/kms/jdcloud/jdcloud-kms-plugin.json # 留神门路
name: jdcloud-kms-plugin-configfile
readOnly: true
- mountPath: /var/run/k8s-kms-plugin/
name: k8s-kms-plugin-unixsock-directory
readOnly: false
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/kubernetes/kms/jdcloud/jdcloud-kms-plugin.json # 留神门路
type: File
name: jdcloud-kms-plugin-configfile
- hostPath:
path: /var/run/k8s-kms-plugin/
type: DirectoryOrCreate
name: k8s-kms-plugin-unixsock-directory
status: {}
以上内容保留在 /etc/kubernetes/manifests/jdcloud-kms-plugin.yaml
批改 kube apiserver 配置
...
- --encryption-provider-config=/etc/kubernetes/kms/jdcloud/apiserver-encryption.conf
image: hub-pub.jdcloud.com/k8s/kube-apiserver:v1.19.9-109
imagePullPolicy: IfNotPresent
livenessProbe:
...
- mountPath: /etc/kubernetes/kms/jdcloud/apiserver-encryption.conf
name: apiserver-encryption-conf
readOnly: true
- mountPath: /var/run/k8s-kms-plugin/
name: k8s-kms-plugin-unixsock-directory
readOnly: false
...
- hostPath:
path: /etc/kubernetes/kms/jdcloud/apiserver-encryption.conf
type: File
name: apiserver-encryption-conf
- hostPath:
path: /var/run/k8s-kms-plugin/
type: DirectoryOrCreate
name: k8s-kms-plugin-unixsock-directory
批改后保留
验证
在默认的命名空间里创立一个名为 secret1 的 Secret:
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
用 etcdctl 命令行,从 etcd 读取出 Secret:
etcdctl.sh get /kubernetes.io/secrets/default/secret1 [...] | hexdump -C
后果为加密数据
验证 Secret 在被 API server 获取时已被正确解密:
kubectl describe secret secret1 -n default
该后果为明文,mykey: mydata
产品能力
在 K8S 集群中,京东外部始终比拟器重对敏感数据加密,特地是云舰面对越来越多的金融行业客户,加密服务根本是云舰中的标准配置。
通过产品能力打磨和外部实现,KMS 加密服务和 K8S 自动化集群以及一键配置创立都在云舰内实现了很好的产品化能力,能够随集群创立,一键启用 KMS 加密服务。
参考:
1. 应用 KMS 驱动进行数据加密
作者:京东科技 王晓飞
起源:京东云开发者社区 转载请注明起源