基本概念
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節(jié)點,需要同時配置。
新建目錄
/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節(jié)點。 cachesize: 100 timeout: 3s - identity: {}
以上內容保存在/etc/kubernetes/kms/jdcloud/apiserver-encryption.conf
新建 jdcloud kms plugin 配置
kms server的上聯(lián)信息配置
{
"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服務,并按照配置和上聯(lián)的kms server進行通信,加密和解密數據,并通過socket服務和K8S APIServer交互。
該pod需要在kube-apiserver啟動之前啟動,否則與apiserver可能產生循環(huán)依賴。
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
修改后保存
驗證
在默認的命名空間里創(chuàng)建一個名為 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集群中,京東內部一直比較重視對敏感數據加密,特別是云艦面對越來越多的金融行業(yè)客戶,加密服務基本是云艦中的標準配置。
經過產品能力打磨和內部實現,KMS 加密服務和K8S自動化集群以及一鍵配置創(chuàng)建都在云艦內實現了很好的產品化能力,可以隨集群創(chuàng)建,一鍵啟用KMS加密服務。

參考:
1. 使用 KMS 驅動進行數據加密
審核編輯 黃宇
-
數據安全
+關注
關注
2文章
751瀏覽量
30742 -
KMS
+關注
關注
0文章
4瀏覽量
4783
發(fā)布評論請先 登錄

K8S集群中使用JDOS KMS服務對敏感數據安全加密
評論