基本概念
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/v1kind: EncryptionConfigurationresources: - 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: v1kind: Podmetadata: creationTimestamp: null labels: component: jdcloud-kms-plugin tier: control-plane name: jdcloud-kms-plugin-node-01 namespace: kube-systemspec: 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-directorystatus: {}
以上内容保留在/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 驱动进行数据加密
作者:京东科技 王晓飞
起源:京东云开发者社区 转载请注明起源