control plane 是整個 k8s cluster 的大腦,它的整個架構圖如下,所以相對的如果它的大腦被 hacker 得到,那就掰了。
然後這裡順到說一下 control plane 的組成有那些 :
kube-apiserver : 就是 k8s 的 api 服務,我們常使用的 kubectl 實際上就是去打 api 到它。
etcd : k8s 的資料儲放地,放了 cluster 的配置資訊,與現在的狀態。
kube-controller-manager : 它會監控 cluster 的 resource 的狀態,然後會根據狀態來進行相對應的操作 ( 例如 auto scaling )
cloud-controller-manager ( optional ) : 這個沒畫在下面這張圖,但有畫在官網中的那張。它主要管理 cloud provider ( ex. GCP ) 相關的控制。
圖片來源: platform9-Kubernetes Concepts and Architecture
由於在 gke 中,control plane 主要是會由 google 來管,因此我們這裡需要注意的資安相關的事情為 :
不要有外部 ip 可以連到 k8s api server。
使用 iam 來進行 cluster 的 authentication。
每一個 cluster 有他們自已的 CA ( root certificate authority ),然後進定期更新。
gke 會將 workloads 部署到 gcp compute engine 上,所以這也代表我們需要注意 node 的安全。
這裡我們事實上不需要做什麼,因為 gke 的 node 都是使用 google 的Container-Optimized OS
它們都已經做到 security 加強了,做了以下的東西 :
Locked-down firewall
Read-only filesystem where possible
Limited user accounts and disabled root login
升級永遠是一個在資安裡的 best practice 之一。
在 culster 上有些情況下會 run 一些未知或是不可信任的 workload,例如在 software-as-a-service ( Saas ) 這種服務就很常有這種需求,然後這裡是建議用 gke sandbox 來將這些未知或是不可信任的 workload 進行隔離。
可以參考以下這份文件,然後看起來就是開一個 sandbox 的 node。
https://cloud.google.com/kubernetes-engine/docs/how-to/sandbox-pods
這裡要說明一下instance metadata
是什麼。首先它是一個會放了很多關於 vm 的資訊與配置參數,它裡面會包含了一些重要資訊,例如網路配置、啟動 script。
https://cloud.google.com/compute/docs/metadata/overview
然後以下的指令可以看的到某個特定的 metadata,METADATA_ITEM 要替代成你要看的,例如 tags。
gcloud compute instances describe gke-cool-wharf-784-g-default-node-poo-f3d9b100-7v8d --format='value(METADATA_ITEM)'
因為有重要的資訊,因為這裡是建議是使用 workload identity 來 lock down 敏感的 instance metadata path。
https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity
它是一個被官方推薦,讓 workload ( pod、service ) 訪問 gcp cloud service 更安全與更好管理的方法。
https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity
將 gke 的 workload identity 開啟 ( 就在設定那,或是下指令 )。
建立一個 gcp service account ( GSA )。
建立 k8s 的 service account ( KSA )。
kubectl create serviceaccount [SERVICE_ACCOUNT_NAME]
將 KSA 綁定到 GSA 上。
gcloud iam service-accounts add-iam-policy-binding \
[GSA_EMAIL] \
--member "serviceAccount:[PROJECT_ID].svc.id.goog[[NAMESPACE]/[KSA_NAME]]" \
--role roles/iam.workloadIdentityUser
在 pod 上設定 service account。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
serviceAccountName: [SERVICE_ACCOUNT_NAME]
將 KSA mapping 到 GSA。
kubectl annotate serviceaccount \
[KSA_NAME] \
iam.gke.io/gcp-service-account=[GSA_EMAIL]