KMS 加密驱动使用封套加密模型来加密 etcd 中的数据。 数据使用数据加密秘钥(DEK)加密;每次加密都生成一个新的 DEK。 这些 DEK 经一个秘钥加密秘钥(KEK)加密后在一个远端的 KMS 中存储和管理。 KMS 驱动使用 gRPC 与一个特定的 KMS 插件通信。这个 KMS 插件作为一个 gRPC 服务器被部署在 Kubernetes 主服务器的同一个主机上,负责与远端 KMS 的通信。
现在基本云厂商都提供KMS服务。这里以阿里云为例。
(1)开通密钥管理服务
(2)创建密钥
(3)然后部署kms-plugin
apiVersion: apps/v1kind: Deploymentmetadata:name: ack-kms-pluginnamespace: kube-systemspec:selector:matchLabels:name: ack-kms-plugintemplate:metadata:labels:name: ack-kms-pluginspec:affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- preference: {}weight: 100requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: nodeoperator: Invalues:- masterrestartPolicy: Alwaystolerations:- key: node-role.kubernetes.io/mastereffect: NoSchedulevolumes:- name: kmssockethostPath:path: /var/run/kmsplugintype: DirectoryOrCreatecontainers:- name: ack-kms-pluginimage: registry.{{ .Region }}.aliyuncs.com/acs/ack-kms-plugin:v1.0.2imagePullPolicy: Alwayscommand:- ack-kms-plugin- --gloglevel=5- --key-id={{ .KeyId }}- --path-to-unix-socket=/var/run/kmsplugin/grpc.socklivenessProbe:exec:command:- ack-kms-plugin- health- --path-to-unix-socket=/var/run/kmsplugin/grpc.sockinitialDelaySeconds: 30failureThreshold: 3timeoutSeconds: 5periodSeconds: 300env:- name: ACCESS_KEY_ID #not required if you want plugin help to pull the sts credentialsvalue: {{ .AK }}- name: ACCESS_KEY_SECRET #not required if you want plugin help to pull the sts credentialsvalue: {{ .AK_Secret }}- name: CREDENTIAL_INTERVAL #not required if you want plugin help to pull the sts credentialsvalue: {{ .Credential_Interval }}volumeMounts:- name: kmssocketmountPath: /var/run/kmspluginreadOnly: false
其中需要更改的地方:
- {{ .Region }}:阿里巴巴云区域 ID, 如果您的群集部署在 ECS 上, 您可以通过curl http://100.100.100.200/latest/meta-data/region-id
- {{ .KeyId }}:Kms 服务列表中用于秘密加密的阿里云 Kms 密钥 ID
- {{ .AK }}:授权的角色ID
- {{ .AK_Secret }}:授权的角色密钥
- {{ .Credential_Interval }}:凭据轮询间隔
(4)创建kms插件配置文件/etc/kubernetes/kmsplugin/encryptionconfig.yaml
apiVersion: apiserver.config.k8s.io/v1kind: EncryptionConfigurationresources:- resources:- secretsproviders:- kms:name: grpc-kms-providerendpoint: unix:///var/run/kmsplugin/grpc.sockcachesize: 1000timeout: 3s- identity: {}
(5)修改kube-apiserver配置清单文件/etc/kubernetes/manifests/kube-apiserver.yaml
在启动参数里加入:
......spec:containers:- command:- kube-apiserver- --encryption-provider-config=/etc/kubernetes/kmsplugin/encryptionconfig.yaml......
然后再配置挂载,如下:
...volumeMounts:- name: kms-sockmountPath: /var/run/kmsplugin- name: kms-configmountPath: /etc/kubernetes/kmsplugin...volumes:- name: kms-sockhostPath:path: /var/run/kmsplugin- name: kms-confighostPath:path: /etc/kubernetes/kmsplugin
(6)重启kube-apiserver
(7)验证
现在,群集应使用信封加密方案,使用阿里云 KMS 的给定密钥加密密钥 (KEK) 对 中的秘密进行加密
1. 创建新机密
$ kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
使用 etcdtl,读取主节点中的 etcd中的机密:
ps: [.local-ip] 应替换为主节点 IP 之一。$ ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.pem --cert=/etc/kubernetes/pki/etcd/etcd-client.pem --key=/etc/kubernetes/pki/etcd/etcd-client-key.pem --endpoints=https://{{.local-ip}}:2379 get /registry/secrets/default/secret1
验证存储的机密是否前缀,指示我们的 kms 提供商已加密生成的数据。
k8s:enc:kms:v1:grpc-kms-provider
4. 验证密钥是否已正确解密:$ kubectl get secrets secret1 -o yaml
