适用于 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 实例系列都支持容器的安全组,包括
m5
、c5
、r5
、p3
、m6g
、c6g
和r6g
实例系列。t3
实例系列不受支持。有关受支持实例的完整列表,请参阅 Amazon EC2 支持的实例和分支网络接口。您的节点必须是受支持的实例类型之一。 -
源 NAT 已对来自于已分配安全组的 Pod 的出站流量禁用,以便应用出站安全组规则。要访问 Internet,必须在配置了 NAT 网关或实例的私有子网中部署的节点上启动具有已分配安全组的 Pod。部署到公有子网的已分配安全组的 Pod 无法访问 Internet。
-
使用实例目标(
externalTrafficPolicy
设置为Local
)的NodePort
和LoadBalancer
类型的 Kubernetes 服务不受您向其分配安全组的 Pod 的支持。有关将负载均衡器与实例目标一起使用的更多信息,请参阅 Amazon EKS 上的网络负载均衡。 -
如果您还使用 Pod 安全策略来限制对 Pod 变异的访问,则
eks-vpc-resource-controller
和vpc-resource-controller
Kubernetes 服务账户必须在 KubernetesClusterRoleBinding
中指定用于您的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 的安全组的步骤
-
如果您使用的是仅适用于 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 附加组件。
-
将
AmazonEKSVPCResourceController
托管策略添加到与您的 Amazon EKS 集群关联的集群角色。策略允许角色管理网络接口、网络接口的私有 IP 地址以及与实例之间的连接和分离。以下命令可将策略附加到名为
的集群角色。eksClusterRole
aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController \ --role-name
eksClusterRole
-
通过在
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"}]}}}}'
-
创建要将资源部署到该处的命名空间。
kubectl create namespace
my-namespace
-
将 Amazon EKS
SecurityGroupPolicy
部署到集群。-
将以下示例安全策略保存到名为
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。
-
-
部署策略。
kubectl apply -f
my-security-group-policy.yaml
-
-
部署其标注与上一步中指定的
的podSelector
值相匹配的示例应用程序。my-role
-
将以下内容保存到一个文件中。
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
-
使用以下命令部署应用程序。当您部署应用程序时,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
并看到类似于以下消息内容的消息,则可以安全地忽略该消息。当 CNI 插件尝试在创建网络接口时设置主机联网并失败时,可能会出现此消息。CNI 插件会记录此事件,直到创建了网络接口为止。my-deployment-xxxxxxxxxx-xxxxx
-nmy-namespace
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 |