使用適用於 Amazon EKS Pod 的安全群組政策 - Amazon EKS

協助改進此頁面

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

若要為本使用者指南貢獻內容,請點選每個頁面右側面板中的在 GitHub 上編輯此頁面連結。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用適用於 Amazon EKS Pod 的安全群組政策

如需使用適用於 Pod 的安全群組,必須設定現有的安全群組。下列步驟介紹如何使用 Pod 的安全群組政策。除非另有備註,請從同一終端機完成所有步驟,因為變數用於不會保留跨終端機的以下步驟。

若您有包含 Amazon EC2 執行個體的 Pod,使用此程序之前,必須設定外掛程式。如需詳細資訊,請參閱針對適用於 Amazon EKS Pod 的安全群組設定適用於 Kubernetes 的 Amazon VPC CNI 外掛程式

  1. 建立 Kubernetes 命名空間以部署 資源。您可以將 my-namespace 取代為要使用的命名空間的名稱。

    kubectl create namespace my-namespace
  2. 將 Amazon EKS SecurityGroupPolicy 部署至您的叢集。

    1. 將以下內容複製到您的裝置。若您希望根據服務帳戶標籤選取 Pod,則您可以使用 serviceAccountSelector 取代 podSelector。您必須指定其中一個選取器或其他工具。空白 podSelector (例如:podSelector: {}) 選取命名空間中的所有 Pood。您可以將 my-role 變更為您的角色名稱。空白 serviceAccountSelector 會選取命名空間中的所有服務帳戶。您可以將 my-security-group-policy 取代為您的 SecurityGroupPolicy 的名稱,將 my-namespace 取代為要在其中建立 SecurityGroupPolicy 的命名空間。

      您必須將 my_pod_security_group_id 取代為現有安全群組的 ID。如果您沒有現有的安全群組,則必須先建立一個。如需詳細資訊,請參閱《Amazon EC2 使用者指南》https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/中的適用於 Linux 執行個體的 Amazon EC2 安全群組一節。您可以指定 1-5 個安全群組 ID。如果您指定多個 ID,則所有安全群組中的所有規則的組合對選取的 Pod 都有效。

      cat >my-security-group-policy.yaml <<EOF apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: my-security-group-policy namespace: my-namespace spec: podSelector: matchLabels: role: my-role securityGroups: groupIds: - my_pod_security_group_id EOF
      重要

      您指定的 Pod 的一個或多個安全群組 必須符合下列條件:

      • 它們必須存在。如果它們不存在,那麼當您部署符合選取器的 Pod 時,您的 Pod 仍會停留在建立程序中。如果您描述 Pod,您會看到類似下列錯誤訊息:An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-05b1d815d1EXAMPLE' does not exist

      • 安全群組必須允許透過您已設定偵測的任何連接埠,而來自套用於您節點的安全群組的傳入通訊 (適用於 kubelet)。

      • 其必須允許透過 TCPUDP 連接埠 53 與指派給執行 CoreDNS 的 Pod 的安全群組 (或 Pod 在其上執行的節點) 進行對外通訊。您的 CoreDNS Pod 的安全群組必須允許來自您所指定安全群組的傳入 TCPUDP 連接埠 53 流量。

      • 其必須具備必要的傳入和傳出規則,從而和其需要與之溝通的其他 Pod 溝通。

      • 如果您使用具有 Fargate 的安全群組,其必須具有允許 Pod 與 Kubernetes 控制平面通訊的規則。執行此動作最簡單的方法是指定叢集安全群組為其中一個安全群組。

      安全群組政策僅適用於新排程的 Pod。它們不會影響執行中的 Pod。

    2. 部署政策。

      kubectl apply -f my-security-group-policy.yaml
  3. 部署範例應用程式,其中標籤符合您在上一步驟指定的 podSelectormy-role 值。

    1. 將以下內容複製到您的裝置。使用您自己的值取代範例值,然後執行修改後的命令。如果您取代 my-role,請確保其與您在上一步中為選取器指定的值相同。

      cat >sample-application.yaml <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 4 selector: matchLabels: app: my-app template: metadata: labels: app: my-app role: my-role spec: terminationGracePeriodSeconds: 120 containers: - name: nginx image: public.ecr.aws/nginx/nginx:1.23 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-app namespace: my-namespace labels: app: my-app spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 EOF
    2. 使用下列命令部署應用程式。當您部署應用程式時,適用於 Kubernetes 的 Amazon VPC CNI 外掛程式會符合您在上一步驟中指定的 role 標籤和安全群組,且可套用至 Pod。

      kubectl apply -f sample-application.yaml
  4. 檢視與範例應用程式一起部署的 Pod。對於本主題的餘數,該終端機稱為 TerminalA

    kubectl get pods -n my-namespace -o wide

    範例輸出如下。

    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-5df6f7687b-4fbjm 1/1 Running 0 7m51s 192.168.53.48 ip-192-168-33-28.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-j9fl4 1/1 Running 0 7m51s 192.168.70.145 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-rjxcz 1/1 Running 0 7m51s 192.168.73.207 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-zmb42 1/1 Running 0 7m51s 192.168.63.27 ip-192-168-33-28.region-code.compute.internal <none> <none>
    注意

    若任何 Pod 停滯,則嘗試這些小貼士。

    • 若任何 Pod 停滯在 Waiting 狀態,則請執行 kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace 。若您看到 Insufficient permissions: Unable to create Elastic Network Interface.,請確認您已在上一步驟中將 IAM 政策新增至 IAM 叢集角色。

    • 若任何 Pod 停滯在 Pending 狀態,請確認您的節點執行個體類型已列在 limits.go 中,並且尚未達到該執行個體類型支援的分支網路介面數量上限乘以節點群組中節點數量的乘積。例如,m5.large 執行個體支援九個分支網路介面。如果您的節點群組有五個節點,則最多可以為節點群組建立 45 個分支網路介面。您嘗試部署的第 46 個 Pod 將位於 Pending 狀態,直到刪除具有相關聯安全群組的另一個 Pod 為止。

    如果您執行 kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace ,並看到類似下列訊息的訊息,則可以放心地將其忽略。當適用於 Kubernetes 的 Amazon VPC CNI 外掛程式嘗試設定主機聯網並在建立網路介面時失敗時,可能會出現此訊息。外掛程式會記錄此事件,直到網路介面建立為止。

    Failed to create Pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "e24268322e55c8185721f52df6493684f6c2c3bf4fd59c9c121fd4cdc894579f" network for Pod "my-deployment-5df6f7687b-4fbjm": networkPlugin cni failed to set up Pod "my-deployment-5df6f7687b-4fbjm-c89wx_my-namespace" network: add cmd: failed to assign an IP address to container

    您不能超過執行個體類型上可以執行的 Pod 數量上限。關於每種執行個體類型上可執行的 Pod 數目上限清單,請參閱 GitHub 上的 eni-max-pods.txt。當您刪除具有關聯安全群組的 Pod,或刪除 Pod 執行所在的節點時,VPC 資源控制器會刪除分支網路介面。如果您使用安全群組的 Pod 來刪除具有 Pod 的叢集,則控制器不會刪除分支網路介面,因此您需要自行刪除它們。如需有關如何刪除網路介面的資訊,請參閱《Amazon EC2 使用者指南》中的刪除網路介面

  5. 在單獨的終端機中,shell 轉換為 Pod。對於本主題的餘數,該終端機稱為 TerminalB。使用從上一步驟傳回的輸出中的其中一個 Pod 的 ID 取代 5df6f7687b-4fbjm

    kubectl exec -it -n my-namespace my-deployment-5df6f7687b-4fbjm -- /bin/bash
  6. TerminalB 中的 shell,確認範例應用程式是否正常運作。

    curl my-app

    範例輸出如下。

    <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> [...]

    您收到了輸出,因為所有執行該應用程式的 Pod 都與您建立的安全群組關聯。該群組包含一個規則,其允許與安全群組關聯的所有 Pod 之間的流量。允許從該安全群組傳出 DNS 流量到與節點關聯的叢集安全群組。這些節點正在執行 CoreDNS Pod,您的 Pod 對此進行了名稱查詢。

  7. TerminalA 中,移除允許從安全群組與叢集進行 DNS 通訊的安全群組規則。如果在上一步驟並未新增 DNS 規則至叢集安全群組,則用您在其中建立規則的安全群組的 ID 取代 $my_cluster_security_group_id

    aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_tcp_rule_id aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_udp_rule_id
  8. TerminalB,再次嘗試存取該應用程式。

    curl my-app

    範例輸出如下。

    curl: (6) Could not resolve host: my-app

    嘗試失敗,因為 Pod 不再能存取 CoreDNS Pod,其具有與之關聯的叢集安全群組。叢集安全群組不再具有允許從與 Pod 關聯的安全群組進行 DNS 通訊的安全群組規則。

    如果您在上一步驟中,嘗試存取使用其中一個 Pod 傳回的 IP 位址的應用程式,您仍會接收到回應,因為已允許具有與之關聯的安全群組的 Pod 之間的所有連接埠,並且不需要進行名稱查詢。

  9. 在實驗完成後,您可以移除自己建立的範例安全群組政策、應用程式和安全群組。從 TerminalA 執行下列命令。

    kubectl delete namespace my-namespace aws ec2 revoke-security-group-ingress --group-id $my_pod_security_group_id --security-group-rule-ids $my_inbound_self_rule_id wait sleep 45s aws ec2 delete-security-group --group-id $my_pod_security_group_id