在專屬節點集區中隔離工作負載

本文說明如何透過在 Google Distributed Cloud (GDC) 實體隔離環境的專屬節點集區中隔離容器工作負載,提升 Kubernetes 叢集的安全性和管理效率。隔離工作負載可讓您進一步控管 Pod,並降低 Kubernetes 叢集發生提權攻擊的風險。如要進一步瞭解專屬節點集區的優點和限制,請參閱「節點隔離總覽」。

隔離容器工作負載需要多個工作流程,包括:

  • 為節點集區加上 taint 和標籤:將 taint 和標籤套用至節點集區,除非 Pod 經過特別標記要在該處執行,否則會排斥 Pod 離開節點集區。

  • 新增容許條件和節點親和性規則:將容許條件和規則套用至 Pod,強制 Pod 只能在指定節點集區中執行。

  • 確認隔離功能正常運作:確認受汙染的節點集區只會執行您標示要在該處執行的 Pod。

這些工作流程的目標對象包括平台管理員群組中的 IT 管理員 (負責管理 Kubernetes 叢集的節點集區),以及應用程式運算子群組中的應用程式開發人員 (負責管理容器工作負載)。詳情請參閱 GDC air-gapped 說明文件適用對象

事前準備

如要完成本文中的工作,您必須要求必要的權限並準備環境。

要求 IAM 角色

您必須具備特定角色,才能取得所需權限,在 Kubernetes 叢集中隔離容器工作負載。所需角色取決於您是在機構範圍的共用叢集,還是專案範圍的標準叢集內工作。詳情請參閱「Kubernetes 叢集設定」。

共用叢集角色

請與機構 IAM 管理員聯絡,要求下列角色,以便在共用叢集中汙染及標記節點集區:

  • 使用者叢集管理員 (user-cluster-admin):建立、刪除、編輯或查看管理 API 伺服器上共用叢集的資源。這個角色可存取共用叢集的節點集區。

  • 使用者叢集開發人員 (user-cluster-developer):建立、刪除、編輯或查看共用叢集。這個角色可存取共用叢集內託管的資料層 API。

這類角色不會繫結至命名空間。

標準叢集角色

請與專案 IAM 管理員聯絡,要求對方授予下列角色,以便在標準叢集中汙染及標記節點集區:

  • 叢集管理員 (cluster-admin):在標準叢集中建立、刪除、編輯或查看所有資源。這個角色可存取標準叢集內代管的資料平面 API,用於管理叢集資源。

  • 叢集開發人員 (cluster-developer):建立、刪除、編輯或查看標準叢集。這個角色可存取標準叢集內代管的資料平面 API,用於管理叢集。

  • 標準叢集管理員 (standard-cluster-admin):建立、刪除、編輯或查看管理 API 伺服器上代管的標準叢集資源。這個角色可存取標準叢集的節點集區。

這些角色會繫結至專案命名空間。

準備環境

如要使用 API 對 Kubernetes 叢集執行指令,請確認您具備下列資源:

  • 登入並產生 Kubernetes 叢集的 kubeconfig 檔案。

  • 請使用 Kubernetes 叢集的 kubeconfig 路徑,替換這些操作說明中的 KUBERNETES_CLUSTER_KUBECONFIG

  • 登入並產生管理 API 伺服器的 kubeconfig 檔案。

  • 使用管理 API 伺服器的 kubeconfig 路徑,取代這些操作說明中的 MANAGEMENT_API_SERVER

  • 為要用於專屬節點集區的節點汙點和節點標籤選擇特定名稱。例如 workloadType=untrusted

汙染並標記新的節點集區

將汙點或標籤套用至新的節點集區時,所有節點 (包括稍後新增的節點) 都會自動取得指定的汙點和標籤。節點集區套用汙點或標籤後,就無法移除。

如要為新的節點集區新增汙點和標籤,請完成下列步驟:

  1. 建立節點集區時,直接編輯自訂資源的 nodePools 區段:Cluster

    nodePools:
      # Several lines of code are omitted here.
      - machineTypeName: n2-standard-2-gdc
        name: nodepool-1
        nodeCount: 3
        taints:
        - key: "TAINT_KEY"
          value: "TAINT_VALUE"
          effect: "TAINT_EFFECT"
        labels:
          LABEL_KEY: LABEL_VALUE
    

    更改下列內容:

    • TAINT_KEY:與排程相關聯的鍵/值組合中的汙點鍵部分。TAINT_EFFECT例如:workloadType
    • TAINT_VALUE:與排程 TAINT_EFFECT 相關聯的鍵/值組合中的汙點值部分。例如:untrusted
    • TAINT_EFFECT:下列其中一個效果值:
      • NoSchedule:系統不會把無法容許此 taint 的 Pod 指派到節點上,也不會將現有的 Pod 自節點中移除。
      • PreferNoSchedule:Kubernetes 會避免將無法容忍此 taint 的 Pod 排程到節點上。
      • NoExecute:如果 Pod 已在節點上執行,系統會移除節點中的 Pod。如果尚未在節點上執行,也不會將 Pod 排程到節點上。
    • LABEL_KEY: LABEL_VALUE: 節點標籤的鍵/值組合,對應至您在工作負載資訊清單中指定的選取器。
  2. 套用 Cluster 資源,建立新的節點集區:

    kubectl apply -f cluster.yaml --kubeconfig MANAGEMENT_API_SERVER
    

    MANAGEMENT_API_SERVER 替換為 Kubernetes 叢集所在區域 API 伺服器的 kubeconfig 路徑。

汙染及標記現有節點集區

如要將汙點或標籤套用至現有節點集區,必須對每個現有節點套用變更。您無法動態更新節點集區設定。

節點集區套用汙點或標籤後,就無法移除。

如要在現有節點集區中新增汙點和標籤,請完成下列步驟:

  1. 列出專屬節點集區中的節點:

    kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \
        -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAME
    

    請替換下列變數:

    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 叢集的 kubeconfig 路徑。
    • NODE_POOL_NAME:專屬節點集區的名稱。

    從輸出內容中記下節點集區中所有節點的節點 ID。

  2. 針對節點集區中的每個節點,套用汙點:

    kubectl taint nodes NODE_ID \
        TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    請替換下列變數:

    • NODE_ID:專屬節點集區中的 worker 節點 ID。
    • TAINT_KEY=TAINT_VALUE:與排程相關聯的鍵/值組合。TAINT_EFFECT例如:workloadType=untrusted
    • TAINT_EFFECT:下列其中一個特效值:
      • NoSchedule:系統不會把無法容許此 taint 的 Pod 指派到節點上,也不會將現有的 Pod 自節點中移除。
      • PreferNoSchedule:Kubernetes 會避免將無法容忍此 taint 的 Pod 排程到節點上。
      • NoExecute:如果 Pod 已在節點上執行,系統會移除節點中的 Pod。如果尚未在節點上執行,也不會將 Pod 排程到節點上。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 叢集的 kubeconfig 路徑。
  3. 為節點集區中的每個節點套用與容器工作負載中定義的選取器相應的標籤:

    kubectl label NODE_ID \
        LABEL_KEY:LABEL_VALUE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    請替換下列變數:

    • NODE_ID:專屬節點集區中的 worker 節點 ID。
    • LABEL_KEY:LABEL_VALUE:節點標籤的鍵/值組合,對應至您在工作負載資訊清單中指定的選取器。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 叢集的 kubeconfig 路徑。

新增容許度和節點親和性規則

為專屬節點集區加上 taint 後,除非工作負載具有與您新增 taint 相對應的容許條件,否則無法排定在該集區上。在工作負載的規格中新增容許條件,讓這些 Pod 在受汙染的節點集區中排程。

如果您已為專屬節點集區加上標籤,也可以新增節點親和性規則,告知 GDC 只在該節點集區中排定工作負載。

如要設定容器工作負載,使其在專屬節點集區中執行,請完成下列步驟:

  1. 在容器工作負載資訊清單檔案的 .spec.template.spec 區段中新增下列區段,例如 Deployment 自訂資源:

    tolerations:
    - key: TAINT_KEY
      operator: Equal
      value: TAINT_VALUE
      effect: TAINT_EFFECT
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: LABEL_KEY
              operator: In
              values:
              - "LABEL_VALUE"
    

    更改下列內容:

    • TAINT_KEY:您套用至專屬節點集區的汙點鍵。
    • TAINT_VALUE:您套用至專屬節點集區的汙點值。
    • TAINT_EFFECT:下列其中一個效果值:
      • NoSchedule:系統不會把無法容許此 taint 的 Pod 指派到節點上,也不會將現有的 Pod 自節點中移除。
      • PreferNoSchedule:Kubernetes 會避免將無法容忍此 taint 的 Pod 排程到節點上。
      • NoExecute:如果 Pod 已在節點上執行,系統會移除節點中的 Pod。如果尚未在節點上執行,也不會將 Pod 排程到節點上。
    • LABEL_KEY:您套用至專屬節點集區的節點標籤鍵。
    • LABEL_VALUE:您套用至專屬節點集區的節點標籤值。

    舉例來說,下列 Deployment 資源會新增 workloadType=untrusted:NoExecute taint 的容許條件,以及 workloadType=untrusted 節點標籤的節點親和性規則:

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: my-app
      namespace: default
      labels:
        app: my-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          tolerations:
          - key: workloadType
            operator: Equal
            value: untrusted
            effect: NoExecute
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: workloadType
                    operator: In
                    values:
                    - "untrusted"
          containers:
          - name: my-app
            image: harbor-1.org-1.zone1.google.gdc.test/harborproject/my-app
            ports:
            - containerPort: 80
          imagePullSecrets:
          - name: SECRET
    
  2. 更新容器工作負載:

    kubectl apply -f deployment.yaml -n NAMESPACE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    請替換下列變數:

    • NAMESPACE:容器工作負載的命名空間。如果是共用叢集,這必須是專案命名空間。如果是標準叢集,則可以是任何命名空間。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 叢集的 kubeconfig 路徑。

GDC 會重新建立受影響的 Pod。節點親和性規則會強制將 Pod 移至您建立的專屬節點集區。容許條件只允許將這些 Pod 放置在節點上。

確認分隔線是否正常運作

確認您指定的 Pod 是否在標籤節點集區中執行。

  • 列出指定命名空間中的 Pod:

    kubectl get pods -o=wide -n NAMESPACE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    請替換下列變數:

    • NAMESPACE:容器工作負載的命名空間。如果是共用叢集,這必須是專案命名空間。如果是標準叢集,則可以是任何命名空間。
    • KUBERNETES_CLUSTER_KUBECONFIG:Kubernetes 叢集的 kubeconfig 路徑。

    輸出看起來類似以下內容:

    pod/kube-abc-12tyuj
    pod/kube-abc-39oplef
    pod/kube-abc-95rzkap
    

    確認工作負載是在專屬節點集區中執行。

後續步驟