Tanzu Kubernetes GridのEtcdのデータを暗号化する (Encryption at Rest)
Tanzu Kubernetes Gridで作成するKubernetesクラスタは "Encryption at Rest" の設定が入っていないので、 Etcdには平文でデータが保存されます。
vSphere with Tanzuで作成されるTanzu Kubernetes Grid Clusterは"Encryption at Rest"が設定されています。
試しに、普通のTanzu Kubernetes Grid ClusterにSecretを作成して、Etcdの中を覗いてみます。
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
kubectl exec -n kube-system -ti $(kubectl get pod -n kube-system -l component=etcd --template '{{(index .items 0).metadata.name}}') -- /bin/sh
# etcdctl --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key --cacert=/etc/kubernetes/pki/etcd/ca.crt get /registry/secrets/default/secret1
/registry/secrets/default/secret1
k8s
v1Secret?
?
secret1default"*$027a1469-b37a-4881-b18d-8b09ee8937582?⑇z?`
kubectl-createUpdatev?⑇FieldsV1:.
,{"f:data":{".":{},"f:mykey":{}},"f:type":{}}
mykeymydataOpaque"
mydataがしっかり見えてますね。
"Encryption at Rest"の設定は↓のドキュメントが詳しいです。
このドキュメントの内容をTanzu Kubernetes Gridに適用します。
ポイントとしては
EncryptionConfigurationの設定ファイルを用意する- kube-apiserverの
encryption-provider-configオプションにEncryptionConfigurationの設定ファイルのパスを渡す
をCluster APIのKubeadmControlPlaneに設定する必要があります。
これを実現するのに ytt のoverlayを使用します。
$HOME/.tanzu/tkg/providers/infrastructure-vsphere/ytt/vsphere-overlay.yamlに次の設定を記述または追記します。
#@ load("@ytt:overlay", "overlay")
#@overlay/match by=overlay.subset({"kind": "KubeadmControlPlane"})
---
spec:
kubeadmConfigSpec:
clusterConfiguration:
apiServer:
extraArgs:
#@overlay/match missing_ok=True
encryption-provider-config: /etc/kubernetes/etcd-encryption/encryption.yaml
#@overlay/match missing_ok=True
extraVolumes:
- name: encryption-provider-config
hostPath: /etc/kubernetes/etcd-encryption/encryption.yaml
mountPath: /etc/kubernetes/etcd-encryption/encryption.yaml
readOnly: true
pathType: File
files:
#@overlay/append
- content: |
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- secretbox:
keys:
- name: secret-key-1
secret: ***************************
# identity is a required (default) provider
- identity: {}
owner: "root:root"
path: "/etc/kubernetes/etcd-encryption/encryption.yaml"
permissions: "0644"
***************************の箇所にはhead -c 32 /dev/urandom | base64の出力結果を設定します。
これでtanzu cluster create --dry-runでoverlay適用結果を確認します。
ここではCluster名blueberryで、定義を次のようにblueberry.yaml設定します。設定値は環境によって異なります。
AVI_ENABLE: "false"
CLUSTER_CIDR: 100.96.0.0/11
CLUSTER_NAME: blueberry
CLUSTER_PLAN: dev
ENABLE_CEIP_PARTICIPATION: "false"
ENABLE_MHC: "true"
IDENTITY_MANAGEMENT_TYPE: none
INFRASTRUCTURE_PROVIDER: vsphere
SERVICE_CIDR: 100.64.0.0/13
TKG_HTTP_PROXY_ENABLED: "false"
VSPHERE_CONTROL_PLANE_DISK_GIB: "20"
VSPHERE_CONTROL_PLANE_ENDPOINT: 192.168.10.100
VSPHERE_CONTROL_PLANE_MEM_MIB: "4096"
VSPHERE_CONTROL_PLANE_NUM_CPUS: "2"
VSPHERE_DATACENTER: /Datacenter
VSPHERE_DATASTORE: /Datacenter/datastore/datastore1
VSPHERE_FOLDER: /Datacenter/vm/tkg
VSPHERE_NETWORK: VM Network
VSPHERE_PASSWORD: ....
VSPHERE_RESOURCE_POOL: /Datacenter/host/Cluster/Resources/tkg
VSPHERE_SERVER: administrator@vsphere.local
VSPHERE_SSH_AUTHORIZED_KEY: ssh-rsa AAAA....
VSPHERE_TLS_THUMBPRINT: 04:FD:....
VSPHERE_USERNAME: administrator@vsphere.local
VSPHERE_WORKER_DISK_GIB: "20"
VSPHERE_WORKER_MEM_MIB: "4096"
VSPHERE_WORKER_NUM_CPUS: "2"
出力結果に次の内容が含まれていることを確認します。
$ tanzu cluster create -f blueberry.yaml --dry-run
# ...
---
apiVersion: controlplane.cluster.x-k8s.io/v1alpha3
kind: KubeadmControlPlane
metadata:
name: blueberry-control-plane
namespace: default
spec:
infrastructureTemplate:
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
kind: VSphereMachineTemplate
name: blueberry-control-plane
kubeadmConfigSpec:
clusterConfiguration:
apiServer:
extraArgs:
cloud-provider: external
encryption-provider-config: /etc/kubernetes/etcd-encryption/encryption.yaml
tls-cipher-suites: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
extraVolumes:
- hostPath: /etc/kubernetes/etcd-encryption/encryption.yaml
mountPath: /etc/kubernetes/etcd-encryption/encryption.yaml
name: encryption-provider-config
readOnly: true
timeoutForControlPlane: 8m0s
# ...
files:
- content: |
...
owner: root:root
path: /etc/kubernetes/manifests/kube-vip.yaml
- content: |
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- secretbox:
keys:
- name: secret-key-1
secret: ***************************
# identity is a required (default) provider
- identity: {}
owner: root:root
path: /etc/kubernetes/etcd-encryption/encryption.yaml
# ...
問題なければ--dry-runオプションを外して、クラスタを作成します。
tanzu cluster create -f blueberry.yaml -y
クラスタが作成されたら、次のコマンドを実行してクラスタにアクセスできるようにします。
tanzu cluster kubeconfig get --admin blueberry
kubectl config use-context blueberry-admin@blueberry
Etcdのデータが暗号化されているかどうか確認します。
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
kubectl exec -n kube-system -ti $(kubectl get pod -n kube-system -l component=etcd --template '{{(index .items 0).metadata.name}}') -- /bin/sh
# etcdctl --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key --cacert=/etc/kubernetes/pki/etcd/ca.crt get /registry/secrets/default/secret1
/registry/secrets/default/secret1
k8s:enc:secretbox:v1:secret-key-1:l|??ص?P ?F?M??
?օ????I?h?T?+?P???4?L??@??R,?
_Q[-?5g,@?T????o??'?*???^?c?Ѳky??͉?????ܮ??
*???EfQ??>?,ӣ??+?L?NG#.??X??P????|?6?ˇ???#??????2??6P?h???\|?P?i?5L??9?xD/=?J?#?b???-Þ??d?o????
@?{?xX?/?%??̻?ej?X?ՙ:???--e
?q?C>???
ちゃんと暗号化されていますね🔓