适用于 Pod 的安全组 - Amazon EKS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

适用于 Pod 的安全组

适用于 Pod 的安全组将 Amazon EC2 安全组与 Kubernetes Pod 集成在一起。您可以使用 Amazon EC2 安全组定义允许流向和来自于您部署到运行在许多 Amazon EC2 实例类型和 Fargate 上节点的 Pod 的入站和出站网络流量的规则。有关此功能的详细说明,请参阅 Pod 的安全组介绍博客文章。

注意事项

在部署适用于 Pod 的安全组之前,请考虑以下限制和条件:

  • 流向和来自具有关联安全组的 Pod 的流量不受 Calico 网络策略执行的限制,并且仅受限于 Amazon EC2 安全组执行。社群正在努力消除这一限制。

  • 在 Amazon EC2 节点上运行的 Pod 可以是 Amazon EKS 支持的任何 Kubernetes 版本,但在 Fargate 上运行的 Pod 必须在 1.18 或更高版本的集群中。

  • 适用于 Pod 的安全组不能与 Windows 节点一起使用。

  • 容器的安全组不能与为包含 Amazon EC2 节点的 IPv6 系列配置的集群一起使用。但是,您可以将容器的安全组与为仅包含 Fargate 节点的 IPv6 系列配置的集群一起使用。有关更多信息,请参阅 将 IPv6 地址分配给容器和服务

  • 大多数基于 Nitro 的 Amazon EC2 实例系列都支持容器的安全组,包括 m5c5r5p3m6gc6gr6g 实例系列。t3 实例系列不受支持。有关受支持实例的完整列表,请参阅 Amazon EC2 支持的实例和分支网络接口。您的节点必须是受支持的实例类型之一。

  • 源 NAT 已对来自于已分配安全组的 Pod 的出站流量禁用,以便应用出站安全组规则。要访问 Internet,必须在配置了 NAT 网关或实例的私有子网中部署的节点上启动具有已分配安全组的 Pod。部署到公有子网的已分配安全组的 Pod 无法访问 Internet。

  • 使用实例目标(externalTrafficPolicy 设置为 Local)的 NodePortLoadBalancer 类型的 Kubernetes 服务不受您向其分配安全组的 Pod 的支持。有关将负载均衡器与实例目标一起使用的更多信息,请参阅 Amazon EKS 上的网络负载均衡

  • 如果您还使用 Pod 安全策略来限制对 Pod 变异的访问,则 eks-vpc-resource-controllervpc-resource-controller Kubernetes 服务账户必须在 Kubernetes ClusterRoleBinding 中指定用于您的 psp 所分配到的 Role。如果您使用的是默认 Amazon EKS psp、Role 和 ClusterRoleBinding,则此为 eks:podsecuritypolicy:authenticated ClusterRoleBinding。例如,您应将服务账户添加到 subjects: 部分,如以下示例所示:

    ... subjects: - kind: Group apiGroup: rbac.authorization.k8s.io name: system:authenticated - kind: ServiceAccount name: vpc-resource-controller - kind: ServiceAccount name: eks-vpc-resource-controller
  • 如果您将自定义联网和适用于 Pod 的安全组一起使用,则请使用适用于 Pod 的安全组所指定的安全组,不要使用 ENIconfig 中指定的安全组。

  • 使用安全组的 Pod 必须在其 Pod 规范中包含 terminationGracePeriodSeconds。这是因为 Amazon EKS VPC CNI 插件会在删除主机上的 Pod 网络之前查询 API 服务器以检索 Pod IP 地址。如果没有此设置,插件将不会删除主机上的 Pod 网络。

  • 使用 Nodelocal DNSCache 的集群不支持使用安全组的容器。

部署适用于 Pod 的安全组

部署适用于 Pod 的安全组的步骤

  1. 如果您使用的是仅适用于 Fargate Pod 的安全组,而且集群上没有任何 Amazon EC2 节点,请跳至第 4 步。使用以下命令查看您当前的 CNI 插件版本。

    kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

    输出类似于以下内容。

    amazon-k8s-cni-init:1.7.5-eksbuild.1 amazon-k8s-cni:1.7.5-eksbuild.1

    如果您的 CNI 插件版本低于 1.7.7,请将其更新到 1.7.7 或更高版本。有关更多信息,请参阅 更新 Amazon VPC CNI Amazon EKS 附加组件

  2. AmazonEKSVPCResourceController 托管策略添加到与您的 Amazon EKS 集群关联的集群角色策略允许角色管理网络接口、网络接口的私有 IP 地址以及与实例之间的连接和分离。以下命令可将策略附加到名为 eksClusterRole 的集群角色。

    aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController \ --role-name eksClusterRole
  3. 通过在 aws-node DaemonSet 中将 ENABLE_POD_ENI 变量设置为 true,启用 CNI 插件来管理 Pod 的网络接口。此设置一旦设置为 true 后,插件会为集群中的每个节点添加一个带有值 vpc.amazonaws.com/has-trunk-attached=true 的标注。VPC 资源控制器会创建并附加一个带有 aws-k8s-trunk-eni 描述且名为中继网络接口的特殊网络接口。

    kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true
    注意

    中继网络接口包含在实例类型支持的最大网络接口数中。有关每种实例类型支持的最大接口数的列表,请参阅适用于 Linux 实例的 Amazon EC2 用户指南中的每种实例类型的每个网络接口的 IP 地址数。如果您的节点已经附加了最大数量的标准网络接口,则 VPC 资源控制器将预订一个空间。您将必须缩减您正在运行的容器 Pod,以便控制器足以分离和删除标准网络接口、创建中继网络接口并将其附加到实例。

    您可以使用以下命令查看哪些节点的 aws-k8s-trunk-eni 设置为 true

    kubectl get nodes -o wide -l vpc.amazonaws.com/has-trunk-attached=true

    创建中继网络接口后,可以从中继或标准网络接口为 Pod 分配辅助 IP 地址。如果节点被删除,中继接口将自动删除。

    当您在后面的步骤中部署适用于 Pod 的安全组时,VPC 资源控制器会创建一个具有 aws-k8s-branch-eni 描述的名为分支网络接口的特殊网络接口,并将安全组与其关联。除了附加到节点的标准网络接口和中继网络接口之外,还会创建分支网络接口。如果您使用的是存活探测或就绪探测器,则您还需要禁用 TCP 早期解复用器,以便 kubelet 可以通过 TCP 连接到分支网络接口上的 Pod。要禁用 TCP 早期解复用器,请运行以下命令:

    kubectl patch daemonset aws-node \ -n kube-system \ -p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'
  4. 创建要将资源部署到该处的命名空间。

    kubectl create namespace my-namespace
  5. 将 Amazon EKS SecurityGroupPolicy 部署到集群。

    1. 将以下示例安全策略保存到名为 my-security-group-policy.yaml 的文件中。如果您希望根据服务账户标签选择 Pod,您可以将 podSelector 替换为 serviceAccountSelector。您必须指定一个或其他选择器。空的 podSelector(示例:podSelector: {})会选择命名空间中的所有 Pod。空的 serviceAccountSelector 会选择命名空间中的所有服务账户。您必须为 groupIds 指定 1-5 个安全组 ID。如果指定了多个 ID,则所有安全组中的所有规则的组合都会对选定的 Pod 生效。

      apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: my-security-group-policy namespace: my-namespace spec: podSelector: matchLabels: role: my-role securityGroups: groupIds: - sg-abc123
      重要
      • 您在策略中指定的安全组必须是存在的。如果它们不存在,那么当您部署与选择器匹配的 Pod 时,该 Pod 会在创建过程中处于卡住状态。如果您描述 Pod,则会看到类似于以下内容的错误消息:An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-abc123' does not exist

      • 安全组必须允许通过您为其配置了探测器的任何端口来自集群安全组的入站通信(对于 kubelet)。

      • 安全组必须允许与安全组进行出站通信。此安全组应允许来自其的入站 TCP 和 UDP 端口 53(针对 CoreDNS 容器组)。

      • 如果您将安全组策略与 Fargate 一起使用,请确保您的安全组具有允许 Pod 与 Kubernetes 控制层面通信的规则。执行此操作的最简单方法是将集群安全组指定为安全组之一。

      • 安全组策略仅适用于新调度的 Pod,不影响正在运行的 Pod。

    2. 部署策略。

      kubectl apply -f my-security-group-policy.yaml
  6. 部署其标注与上一步中指定的 podSelectormy-role 值相匹配的示例应用程序。

    1. 将以下内容保存到一个文件中。

      apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app role: my-role spec: containers: - name: my-container image: my-image ports: - containerPort: 80
    2. 使用以下命令部署应用程序。当您部署应用程序时,CNI 插件将匹配 role 标注,并且您在上一步中指定的安全组将应用到 Pod。

      kubectl apply -f my-security-group-policy.yaml
      注意
      • 如果您的 Pod 卡在 Waiting 状态,而且您在描述 Pod 时看到了 Insufficient permissions: Unable to create Elastic Network Interface.,请确认您已在上一步中将 IAM 策略添加到 IAM 集群角色。

      • 如果您的 Pod 卡在 Pending 状态,请确认您的节点实例类型已列在 Amazon EC2 支持的实例和分支网络接口 中,并且尚未达到实例类型支持的最大分支网络接口数乘以节点组中节点数得到的数值。例如,m5.large 实例支持 9 个分支网络接口。如果节点组有 5 个节点,则最多可以为节点组创建 45 个分支网络接口。在删除另一个具有关联安全组的 Pod 前,您尝试部署的第 46 个 Pod 将会处于 Pending 状态。

      如果您运行 kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace 并看到类似于以下消息内容的消息,则可以安全地忽略该消息。当 CNI 插件尝试在创建网络接口时设置主机联网并失败时,可能会出现此消息。CNI 插件会记录此事件,直到创建了网络接口为止。

      Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "e24268322e55c8185721f52df6493684f6c2c3bf4fd59c9c121fd4cdc894579f" network for pod "my-deployment-59f5f68b58-c89wx": networkPlugin cni failed to set up pod "my-deployment-59f5f68b58-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 支持的实例和分支网络接口

下表列出了您可以与每种受支持的 Amazon EC2 实例类型一起使用的分支网络接口的编号。

实例类型 分支网络接口
a1.medium 10
a1.large 9
a1.xlarge 18
a1.2xlarge 38
a1.4xlarge 54
a1.metal 54
c5.large 9
c5.xlarge 18
c5.2xlarge 38
c5.4xlarge 54
c5.9xlarge 54
c5.12xlarge 54
c5.18xlarge 107
c5.24xlarge 107
c5.metal 107
c5a.large 9
c5a.xlarge 18
c5a.2xlarge 38
c5a.4xlarge 54
c5a.8xlarge 54
c5a.12xlarge 54
c5a.16xlarge 107
c5a.24xlarge 107
c5d.large 9
c5d.xlarge 18
c5d.2xlarge 38
c5d.4xlarge 54
c5d.9xlarge 54
c5d.12xlarge 54
c5d.18xlarge 107
c5d.24xlarge 107
c5d.metal 107
c5n.large 9
c5n.xlarge 18
c5n.2xlarge 38
c5n.4xlarge 54
c5n.9xlarge 54
c5n.18xlarge 107
c5n.metal 107
c6g.medium 4
c6g.large 9
c6g.xlarge 18
c6g.2xlarge 38
c6g.4xlarge 54
c6g.8xlarge 54
c6g.12xlarge 54
c6g.16xlarge 107
c6g.metal 107
g4dn.xlarge 39
g4dn.2xlarge 39
g4dn.4xlarge 59
g4dn.8xlarge 58
g4dn.12xlarge 54
g4dn.16xlarge 118
g4dn.metal 107
i3en.large 5
i3en.xlarge 12
i3en.2xlarge 28
i3en.3xlarge 38
i3en.6xlarge 54
i3en.12xlarge 114
i3en.24xlarge 107
i3en.metal 107
inf1.xlarge 38
inf1.2xlarge 38
inf1.6xlarge 54
inf1.24xlarge 107
m5.large 9
m5.xlarge 18
m5.2xlarge 38
m5.4xlarge 54
m5.8xlarge 54
m5.12xlarge 54
m5.16xlarge 107
m5.24xlarge 107
m5.metal 107
m5a.large 9
m5a.xlarge 18
m5a.2xlarge 38
m5a.4xlarge 54
m5a.8xlarge 54
m5a.12xlarge 54
m5a.16xlarge 107
m5a.24xlarge 107
m5ad.large 9
m5ad.xlarge 18
m5ad.2xlarge 38
m5ad.4xlarge 54
m5ad.8xlarge 54
m5ad.12xlarge 54
m5ad.16xlarge 107
m5ad.24xlarge 107
m5d.large 9
m5d.xlarge 18
m5d.2xlarge 38
m5d.4xlarge 54
m5d.8xlarge 54
m5d.12xlarge 54
m5d.16xlarge 107
m5d.24xlarge 107
m5d.metal 107
m5dn.large 9
m5dn.xlarge 18
m5dn.2xlarge 38
m5dn.4xlarge 54
m5dn.8xlarge 54
m5dn.12xlarge 54
m5dn.16xlarge 107
m5dn.24xlarge 107
m5n.large 9
m5n.xlarge 18
m5n.2xlarge 38
m5n.4xlarge 54
m5n.8xlarge 54
m5n.12xlarge 54
m5n.16xlarge 107
m5n.24xlarge 107
m6g.medium 4
m6g.large 9
m6g.xlarge 18
m6g.2xlarge 38
m6g.4xlarge 54
m6g.8xlarge 54
m6g.12xlarge 54
m6g.16xlarge 107
m6g.metal 107
p3.2xlarge 38
p3.8xlarge 54
p3.16xlarge 114
p3dn.24xlarge 107
r5.large 9
r5.xlarge 18
r5.2xlarge 38
r5.4xlarge 54
r5.8xlarge 54
r5.12xlarge 54
r5.16xlarge 107
r5.24xlarge 107
r5.metal 107
r5a.large 9
r5a.xlarge 18
r5a.2xlarge 38
r5a.4xlarge 54
r5a.8xlarge 54
r5a.12xlarge 54
r5a.16xlarge 107
r5a.24xlarge 107
r5ad.large 9
r5ad.xlarge 18
r5ad.2xlarge 38
r5ad.4xlarge 54
r5ad.8xlarge 54
r5ad.12xlarge 54
r5ad.16xlarge 107
r5ad.24xlarge 107
r5d.large 9
r5d.xlarge 18
r5d.2xlarge 38
r5d.4xlarge 54
r5d.8xlarge 54
r5d.12xlarge 54
r5d.16xlarge 107
r5d.24xlarge 107
r5d.metal 107
r5dn.large 9
r5dn.xlarge 18
r5dn.2xlarge 38
r5dn.4xlarge 54
r5dn.8xlarge 54
r5dn.12xlarge 54
r5dn.16xlarge 107
r5dn.24xlarge 107
r5n.large 9
r5n.xlarge 18
r5n.2xlarge 38
r5n.4xlarge 54
r5n.8xlarge 54
r5n.12xlarge 54
r5n.16xlarge 107
r5n.24xlarge 107
r6g.medium 4
r6g.large 9
r6g.xlarge 18
r6g.2xlarge 38
r6g.4xlarge 54
r6g.8xlarge 54
r6g.12xlarge 54
r6g.16xlarge 107
z1d.large 13
z1d.xlarge 28
z1d.2xlarge 58
z1d.3xlarge 54
z1d.6xlarge 54
z1d.12xlarge 107
z1d.metal 107