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
該設定是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
該服務是啟動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
...
- --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
修改後儲存
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
etcdctl.sh get /kubernetes.io/secrets/default/secret1 [...] | hexdump -C
結果為加密資料
kubectl describe secret secret1 -n default
該結果為明文,mykey: mydata
在K8S叢集中,京東內部一直比較重視對敏感資料加密,特別是雲艦面對越來越多的金融行業客戶,加密服務基本是雲艦中的標準設定。
經過產品能力打磨和內部實現,KMS 加密服務和K8S自動化叢集以及一鍵設定建立都在雲艦內實現了很好的產品化能力,可以隨叢集建立,一鍵啟用KMS加密服務。
作者:京東科技 王曉飛
來源:京東雲開發者社群 轉載請註明來源