选择您的 Cookie 首选项

我们使用必要 Cookie 和类似工具提供我们的网站和服务。我们使用性能 Cookie 收集匿名统计数据,以便我们可以了解客户如何使用我们的网站并进行改进。必要 Cookie 无法停用,但您可以单击“自定义”或“拒绝”来拒绝性能 Cookie。

如果您同意,AWS 和经批准的第三方还将使用 Cookie 提供有用的网站功能、记住您的首选项并显示相关内容,包括相关广告。要接受或拒绝所有非必要 Cookie,请单击“接受”或“拒绝”。要做出更详细的选择,请单击“自定义”。

对 Amazon EKS 容器组(pod)使用安全组策略

聚焦模式
对 Amazon EKS 容器组(pod)使用安全组策略 - Amazon EKS

帮助改进此页面

要帮助改进本用户指南,请选择位于每个页面右侧窗格中的在 GitHub 上编辑此页面链接。

帮助改进此页面

要帮助改进本用户指南,请选择位于每个页面右侧窗格中的在 GitHub 上编辑此页面链接。

要使用容器组(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),则可以将 podSelector 替换为 serviceAccountSelector。您必须指定一个或其他选择器。空的 podSelector(示例:podSelector: {})会选择命名空间中的所有容器组(pod)。您可以将 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)(或其上会运行容器组的节点)的安全组进行出站通信。适用于您的 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 实例支持 9 个分支网络接口。如果节点组有 5 个节点,则最多可以为节点组创建 45 个分支网络接口。在删除另一个具有关联安全组的容器组(pod)前,您尝试部署的第 46 个容器组(pod)将会处于 Pending 状态。

    如果您运行 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)或删除运行该容器组的节点时,VPC 资源控制器会删除分支网络接口。如果您使用适用于安全组的容器组(pod)删除带有容器组的集群,则该控制器不会删除分支网络接口,因此您需要自行删除这些接口。有关如何删除网络接口的信息,请参阅《Amazon EC2 用户指南》中的删除网络接口

  5. 在单独的终端中,shell 进入其中一个容器组(pod)。对于本主题的其余部分,此终端称为 TerminalB。请将 5df6f7687b-4fbjm 替换为您在上一步输出中返回的其中一个容器组(pod)的 ID。

    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),您的容器组对其进行了名称查找。

  7. TerminalA 中,删除允许从安全组与集群安全组进行 DNS 通信的安全组规则。如果您在上一步中没有将 DNS 规则添加到集群安全组中,请将 $my_cluster_security_group_id 替换为您在其中创建规则的安全组的 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)关联的安全组进行 DNS 通信。

    如果您尝试使用上一步中的其中一个容器组(pod)返回的 IP 地址访问应用程序,您仍然会收到响应,因为在与安全组相关联的容器组之间允许所有端口,并且不需要名称查找。

  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

下一主题:

多个接口

上一主题:

配置
隐私网站条款Cookie 首选项
© 2025, Amazon Web Services, Inc. 或其附属公司。保留所有权利。