在 Azure Kubernetes Service (AKS) 中叢集安全性和升級的最佳做法
當您管理 Azure Kubernetes Service (AKS) 中的叢集時,工作負載和資料安全性是主要考量。 使用邏輯隔離執行多租用戶叢集時,您尤其需要保護資源和工作負載存取。 藉由套用最新的 Kubernetes 和節點作業系統安全性更新,將攻擊的風險降到最低。
本文著重在如何保護您的 AKS 叢集。 您會了解如何:
- 使用 Azure Active Directory 和 Kubernetes 角色型存取控制 (Kubernetes RBAC) 來保護 API 伺服器存取。
- 保護容器對節點資源的存取。
- 將 AKS 叢集升級至最新版 Kubernetes。
- 讓節點保持在最新狀態,並自動套用安全性修補檔。
您也可以閱讀適用於容器映像管理和 Pod 安全性的最佳做法。
啟用威脅保護
最佳做法指導方針
您可以啟用適用於容器的 Defender,以協助保護您的容器。 適用於容器的 Defender 可以評估叢集組態並提供安全性建議、執行弱點掃描,以及為 Kubernetes 節點和叢集提供即時保護和警示。
保護對 API 伺服器和叢集節點的存取
最佳做法指導方針
保護叢集最重要方式的其中一個是保護 Kubernetes API 伺服器的存取。 若要控制 API 伺服器的存取權,請整合 Kubernetes RBAC 與 Azure Active Directory (Azure AD)。 藉由這些控制可以保護 Azure 訂閱存取的相同方式來保護 AKS。
Kubernetes API 伺服器針對要求提供單一連線點,以在叢集內執行動作。 若要保護和稽核對 API 伺服器的存取,則必須限制存取並提供盡可能最低層次的權限。 雖然此方法不只適用於 Kubernetes,但您以邏輯方式隔離 AKS 叢集以供多租用戶使用時,此方法特別重要。
Azure AD 提供的身分識別管理解決方案不僅符合企業需求,也整合了 AKS 叢集。 由於 Kubernetes 未提供身分識別管理解決方案,因此您可能難以精確地限制對 API 伺服器的存取。 在 AKS 中使用與 Azure AD 整合的叢集,您就可以使用現有的使用者和群組帳戶,來對 API 伺服器驗證使用者。
使用 Kubernetes RBAC 和 Azure AD 整合可以保護 API 伺服器,並提供限定範圍資源集合所需的最低權限,例如單一命名空間。 您可以授與不同的 Azure AD 使用者或群組不同的 Kubernetes 角色。 藉由這些細微的權限,您可以限制對 API 伺服器的存取,並提供所執行動作的清楚稽核線索。
建議的最佳做法是使用「群組」來提供檔案和資料夾的存取權,而不是個別身分識別。 例如,使用 Azure AD 群組成員資格,將使用者繫結至 Kubernetes 角色,而不是個別「使用者」。 由於使用者的群組成員資格會變更,因此其位在 AKS 叢集上的存取權限也會隨之變更。
同時,假設您將個別使用者直接繫結至角色,且其作業函式變更。 雖然 Azure AD 群組成員資格會更新,但 AKS 叢集上的權限不會更新。 在這種情況下,使用者最後會被授與比所需更多的權限。
如需 Azure AD 整合、Kubernetes RBAC 和 Azure RBAC 的詳細資訊,請參閱 AKS 中驗證和授權的最佳做法。
限制對執行個體中繼資料 API 的存取
最佳做法指導方針
在全部使用者命名空間中新增網路原則,以封鎖中繼資料端點的 Pod 輸出。
注意
若要實作網路原則,請在建立 AKS 叢集時包含 屬性 --network-policy azure
。 使用下列命令來建立叢集: az aks create -g myResourceGroup -n myManagedCluster --enable-managed-identity --network-plugin azure --network-policy azure
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-instance-metadata
spec:
podSelector:
matchLabels: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.10.0.0/0#example
except:
- 169.254.169.254/32
保護容器對資源的存取
最佳做法指導方針
限制存取容器可執行的動作。 提供最低權限數量,並避免使用根存取或提升的權限。
就如同您應授與使用者或群組所需的最低權限一樣,也應限制容器只能執行必要動作和流程。 為了將攻擊風險降到最低,請避免設定需要提升權限或根存取的應用程式和容器。
例如,在 Pod 資訊清單中設定 allowPrivilegeEscalation: false
。 這些內建的 Kubernetes「Pod 資訊安全內容」可讓您定義其他權限,例如要執行的使用者或群組身分,或要公開的 Linux 功能。 如需最佳做法詳細資訊,請參閱保護 Pod 對資源的存取。
若要針對容器動作進行更細微的控制,您也可以使用內建的 Linux 安全性功能,例如 AppArmor 和 Seccomp。
- 在節點層級定義 Linux 安全性功能。
- 透過 Pod 資訊清單實作功能。
內建 Linux 安全性功能僅適用於 Linux 節點和 Pod。
注意
多租用戶如有惡意的使用,則 AKS 或其他位置中的 Kubernetes 環境就並不完全安全。 適用於節點的其他安全性功能,例如適用於容器的 Microsoft Defender、AppArmor、seccomp、Pod 安全性管理或適用於節點的 Kubernetes RBAC,會有效率地阻擋惡意探索。
執行惡意多租用戶工作負載時,若要真正確保安全性,應該只信任 Hypervisor。 Kubernetes 的安全性網域會成為整個叢集,而非個別節點。
對於這些類型的惡意多租用戶工作負載,您應使用實際隔離的叢集。
App Armor
若要限制容器動作,您可以使用 AppArmor Linux 核心安全性模組。 AppArmor 提供用來作為基礎 AKS 節點 OS 的組件,且預設為啟用。 您可以建立 AppArmor 設定檔來限制讀取、寫入或執行動作,也可以限制系統功能,例如裝載檔案系統。 預設 AppArmor 設定檔會限制存取各種 /proc
和 /sys
位置,並提供方法以邏輯方式從基礎節點隔離容器。 AppArmor 適用於任何在 Linux 上執行的應用程式,而不只是 Kubernetes Pod。
若要了解 AppArmor 如何運作,下列範例會建立防止寫入檔案的設定檔。
AKS 節點的 SSH。
建立名為 deny-write.profile 的檔案。
複製並貼上下列內容:
#include <tunables/global> profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { #include <abstractions/base> file, # Deny all file writes. deny /** w, }
使用 apparmor_parser
命令新增 AppArmor 設定檔。
將設定檔新增至 AppArmor。
指定在上個步驟中所建立設定檔的名稱:
sudo apparmor_parser deny-write.profile
如果設定檔已正確剖析並套用至 AppArmor,則不會看到任何輸出,而且您會返回命令提示字元。
現在,在本機電腦上建立名為 aks-apparmor.yaml 的 Pod 資訊清單。 此資訊清單:
- 定義
container.apparmor.security.beta.kubernetes
的註釋。 - 參考在前面步驟中建立的 deny-write 設定檔。
apiVersion: v1 kind: Pod metadata: name: hello-apparmor annotations: container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write spec: containers: - name: hello image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
- 定義
部署 Pod 之後,請執行下列命令,並確認 hello-apparmor Pod 顯示 [ 執行 中] 狀態:
kubectl get pods NAME READY STATUS RESTARTS AGE aks-ssh 1/1 Running 0 4m2s hello-apparmor 0/1 Running 0 50s
如需 AppArmor 的詳細資訊,請參閱 Kubernetes 中的 AppArmor 設定檔。
安全運算
AppArmor 適用於任何的 Linux 應用程式,而 Seccomp (安全運算) 則適用於處理序層級。 Seccomp 也是 Linux 核心安全性模組,且 AKS 節點使用的 Docker 執行階段原生支援。 使用 seccomp,您可以限制容器流程呼叫。 符合只授與容器最小執行權限的最佳做法:
- 使用篩選要允許或拒絕的動作來定義。
- 在 Pod YAML 資訊清單內標註,以與 seccomp 篩選建立關聯。
若要看 Seccomp 實際運作,請建立一個防止變更檔案權限的篩選。
AKS 節點的 SSH。
建立名為 /var/lib/kubelet/seccomp/prevent-chmod 的 seccomp 篩選。
複製並貼上下列內容:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "chmod", "action": "SCMP_ACT_ERRNO" }, { "name": "fchmodat", "action": "SCMP_ACT_ERRNO" }, { "name": "chmodat", "action": "SCMP_ACT_ERRNO" } ] }
在 1.19 版和更新版本中,您需要設定下列:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "names": ["chmod","fchmodat","chmodat"], "action": "SCMP_ACT_ERRNO" } ] }
在本機電腦上建立名為 aks-seccomp.yaml 的 Pod 資訊清單,然後貼上下列內容。 此資訊清單:
- 定義
seccomp.security.alpha.kubernetes.io
的註釋。 - 參考在上一步中建立的 prevent-chmod 篩選條件。
apiVersion: v1 kind: Pod metadata: name: chmod-prevented annotations: seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod spec: containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
在 1.19 版和更新版本中,您需要設定下列:
apiVersion: v1 kind: Pod metadata: name: chmod-prevented spec: securityContext: seccompProfile: type: Localhost localhostProfile: prevent-chmod containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
- 定義
使用 kubectl apply 命令部署範例 Pod:
kubectl apply -f ./aks-seccomp.yaml
使用 kubectl get pods 命令檢視 Pod 的狀態。
- Pod 會回報錯誤。
- Seccomp 篩選會防止執行
chmod
命令,如下列範例輸出所示:
kubectl get pods NAME READY STATUS RESTARTS AGE chmod-prevented 0/1 Error 0 7s
如需有關可用篩選的詳細資訊,請參閱適用於 Docer 的 Seccomp 安全性設定檔。
定期更新至最新版的 Kubernetes
最佳做法指導方針
為了持續取得最新功能和 Bug 修正,請定期升級 AKS 叢集中的 Kubernetes 版本。
Kubernetes 發行新功能的步調,比大部分傳統的基礎結構平台還快。 Kubernetes 更新包括:
- 新功能
- Bug 或安全性修正
新功能在變得「穩定」之前一般會經歷 Alpha 和 Beta 狀態。 穩定之後,正式推出並建議用於生產環境。 Kubernetes 新功能發行版本週期可讓您在更新 Kubernetes 的同時,不會經常遇到中斷性變更,或需要調整部署及範本。
AKS 支援 Kubernetes 的三個次要版本。 引入新的次要修補檔版本時,即會淘汰最舊的次要版本和支援的修補檔版本。 次要 Kubernetes 更新會定期發生。 若要保持支援,請確定您有治理流程可檢查必要的升級。 如需詳細資訊,請參閱支援的 Kubernetes 版本 AKS。
若要檢查可用於您叢集的版本,請使用 az aks get-upgrades 命令,如下列範例所示:
az aks get-upgrades --resource-group myResourceGroup --name myAKSCluster --output table
接著,您可以使用 az aks upgrade 命令升級 AKS 叢集。 升級流程能夠安全地:
- 一次隔離和清空一個節點。
- 排定剩餘節點上的 Pod。
- 部署執行最新作業系統和 Kubernetes 的新節點。
重要
在開發測試環境中測試新的次要版本,並驗證您的工作負載是否對於新的 Kubernetes 版本保持良好狀態。
Kubernetes 可能會取代您工作負載所用的 API (例如在 1.16 版中)。 將新版本帶入生產環境時,請考量在個別版本上使用多個節點集區,並一次升級一個集區,以漸進方式在叢集間進行更新。 如果執行多個叢集,請一次升級一個叢集,以漸進方式監視影響或變更。
az aks upgrade --resource-group myResourceGroup --name myAKSCluster --kubernetes-version KUBERNETES_VERSION
如需有關在 AKS 中升級的詳細資訊,請參閱 AKS 中支援的 Kubernetes 版本和升級 AKS 叢集。
處理 Linux 節點更新
每個晚上,AKS 中的 Linux 節點都會透過其散發套件更新通道取得安全性修補檔。 當節點部署到 AKS 叢集中時,即已自動設定此行為。 為了盡可能減少中斷,並降低對正在執行之工作負載的可能影響,如果安全性修補程式或核心更新需要重新啟動時,節點不會自動重新啟動。 如需如何處理節點重新啟動的詳細資訊,請參閱將安全性和核心更新套用至 AKS 中的節點。
節點映像升級
自動升級會將更新套用至 Linux 節點作業系統,但用來為叢集建立節點的映像會保持不變。 如果將新的 Linux 節點新增至您的叢集,則會使用原始映像來建立節點。 這個新節點會在每天晚上自動檢查期間收到全部可用的安全性和核心更新,但會保持未修補,直到全部檢查和重新啟動都完成為止。 您可以使用節點映像升級來檢查和更新叢集所使用的節點映像。 如需節點映像升級的詳細資訊,請參閱 Azure Kubernetes Service (AKS) 節點映像升級。
處理 Windows Server 節點更新
針對 Windows Server 節點,請定期執行節點映像升級作業,以安全地隔離和清空 Pod,以及部署更新的節點。