基本概念
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 驅動進行數據加密
審核編輯 黃宇
-
數據安全
+關注
關注
2文章
684瀏覽量
29973 -
KMS
+關注
關注
0文章
3瀏覽量
4693
發布評論請先 登錄
相關推薦
評論