EKS 网络:VPC CNI 与负载均衡
使用 Amazon VPC CNI 插件为 Pod 分配原生 VPC IP 地址,并通过 AWS Load Balancer Controller 对外提供服务
EKS 网络:VPC CNI 与负载均衡 是 CoddyKit 上的免费 Cloud & IT Cert Prep 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Cloud & IT Cert Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Cloud & IT Cert Prep 课程共包含 4 节课。
Kubernetes 网络基础
Kubernetes 要求每个 Pod 都拥有唯一且可路由的 IP 地址,并且 Pod 之间能够在不使用 NAT 的情况下相互通信。Container Network Interface(CNI)插件负责为工作节点分配 IP,并配置网络路由。不同的 Kubernetes 平台使用不同的 CNI 实现;AWS 使用 Amazon VPC CNI plugin,将 Kubernetes 网络直接集成到 VPC 层。
Amazon VPC CNI Plugin
Amazon VPC CNI plugin 直接从 VPC 子网的 CIDR 范围为每个 Pod 分配 IP 地址。这意味着 Pod 是VPC 的一等公民——其他 VPC 资源、通过 VPN/Direct Connect 连接的本地系统以及安全组都可以访问它们,无需通过覆盖网络进行转换。每个 EC2 工作节点都会维护一个辅助私有 IP 池(每个 ENI 插槽一个),并在 Pod 调度时将这些 IP 分配给 Pod。
# Check the VPC CNI version installed in your cluster
kubectl describe daemonset aws-node -n kube-system | grep Image
# View the secondary IPs assigned to a node
aws ec2 describe-network-interfaces \
--filters 'Name=attachment.instance-id,Values=i-0abcdef1234567890' \
--query 'NetworkInterfaces[].PrivateIpAddresses[].PrivateIpAddress'ENI 与 IP 地址预热池
VPC CNI plugin 会在每个节点上维护一个预先分配的 IP 地址预热池,以便快速调度 Pod。节点启动时,CNI 会附加多个 ENI,并将辅助 IP 分配到由 WARM_IP_TARGET 或 MINIMUM_IP_TARGET 环境变量指定的数量。因而,一个节点可运行的 Pod 最大数量受实例的 ENI 数量乘以每个 ENI 的 IP 数量限制,而这两个数量会因实例类型而异。
# Check maximum pods supported by an instance type
aws ec2 describe-instance-types \
--instance-types m5.large \
--query 'InstanceTypes[].NetworkInfo.{MaxENIs:MaximumNetworkInterfaces,IPv4sPerENI:Ipv4AddressesPerInterface}'
# Max pods formula: (MaxENIs x (IPv4sPerENI - 1)) + 2
# m5.large: 3 ENIs x (10-1) + 2 = 29 podsPod 的安全组
默认情况下,节点上的所有 Pod 共享该节点的安全组。借助 Security Groups for Pods 功能,您可以使用 SecurityGroupPolicy 自定义资源,为特定 Pod 分配单独的安全组。这样便可实现精细的网络访问控制——例如,只有数据库 Pod 才能从 API Pod 的安全组接收 5432 端口上的流量。此功能要求 VPC CNI Version 为 1.7.7 或更高,并且节点上有一个主干 ENI。
# Define a SecurityGroupPolicy (custom resource)
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
name: db-pod-sg-policy
namespace: production
spec:
podSelector:
matchLabels:
role: database
securityGroups:
groupIds:
- sg-0db1234567890abcdEKS 上的 Kubernetes Service 类型
Kubernetes Services 通过稳定的 DNS 名称和 IP 暴露一组 Pod。在 EKS 上,相关的三种 Service 类型包括:ClusterIP(仅用于集群内部通信)、NodePort(在每个节点上开放一个端口,在 EKS 上很少使用)以及 LoadBalancer(自动预置 AWS 负载均衡器)。LoadBalancer 类型是大多数面向互联网的 EKS Service 所采用的暴露方式。
# Expose a deployment with a LoadBalancer service
kubectl expose deployment my-api \
--type=LoadBalancer \
--name=my-api-svc \
--port=80 \
--target-port=8080
# Check the assigned AWS load balancer hostname
kubectl get svc my-api-svc -o wideAWS Load Balancer Controller
AWS Load Balancer Controller 是一个开源 Kubernetes 控制器,代表 EKS 集群管理 ALB 和 NLB 资源。当您创建 Kubernetes Ingress 对象时,该控制器会预置一个Application Load Balancer。当您使用正确的注释创建类型为 LoadBalancer 的 Service 时,它会预置一个Network Load Balancer。该控制器取代了旧版 Kubernetes 内置的负载均衡器提供程序。
# Install AWS Load Balancer Controller with Helm
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=my-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=us-east-1 \
--set vpcId=vpc-0abc1234def567890使用 ALB 的 Kubernetes Ingress
一个 Kubernetes Ingress 对象定义进入集群的 HTTP/HTTPS 路由规则,包括基于路径和基于主机的规则。AWS Load Balancer Controller 会读取带有 kubernetes.io/ingress.class: alb 注释的 Ingress 对象,并创建相应的Application Load Balancer 以及与之匹配的侦听器规则。这样,您就不必为每个应用程序 Service 手动创建 ALB 和目标组。
# Ingress YAML that creates an ALB
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: production
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80面向 TCP/UDP 工作负载的 NLB
当您的工作负载需要TCP 或 UDP(而不是 HTTP)时,例如游戏服务器、gRPC Service 或数据库代理,请使用 NLB 而不是 ALB。请为 Kubernetes Service 添加 service.beta.kubernetes.io/aws-load-balancer-type: 'external' 和 service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: 'ip' 注释。该控制器会预置一个以 Pod IP 作为直接目标的 NLB,绕过节点级端口转发,从而降低延迟。
# Service YAML that creates an NLB with IP targets
apiVersion: v1
kind: Service
metadata:
name: grpc-svc
namespace: production
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: 'external'
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: 'ip'
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
type: LoadBalancer
selector:
app: grpc-server
ports:
- port: 50051
targetPort: 50051
protocol: TCP集群内的 DNS 解析
EKS 运行 CoreDNS 作为集群 DNS 提供程序。每个 Service 都会获得格式为 service-name.namespace.svc.cluster.local 的 DNS 名称,该名称会解析到 Service 的 ClusterIP。Pod 也可以通过 DNS 被发现。CoreDNS 以 Deployment(而非 DaemonSet)的形式部署,其副本数应根据集群规模进行调整。EKS 将 CoreDNS 作为附加组件进行管理,因此可以自动升级 Version。
# Verify DNS resolution from within a pod
kubectl run dns-test --image=busybox --rm -it --restart=Never -- \
nslookup kubernetes.default.svc.cluster.local
# Expected output: Name: kubernetes.default.svc.cluster.local
# Address: 10.100.0.1 (ClusterIP of the kubernetes service)EKS 中的网络策略
Kubernetes NetworkPolicy 对象为 Pod 到 Pod 以及 Pod 到外部的流量定义 Allow 规则。默认情况下,集群中的所有 Pod 都可以自由通信。要实施零信任网络,您可以 Install Amazon VPC CNI network policy controller(VPC CNI v1.14 起提供)。网络策略会在 Linux 内核层使用 eBPF 进行评估,从而无需覆盖网络即可实现高性能强制执行。
# NetworkPolicy: allow traffic to api pods only from frontend pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-frontend
namespace: production
spec:
podSelector:
matchLabels:
role: api
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080VPC CNI 故障排查提示
常见的 EKS 网络问题包括:IP 地址耗尽(通过 Enable prefix delegation 或添加更大的子网来修复)、由于节点没有可用的辅助 IP 而导致的Pod 卡在 Pending 状态,以及因 CoreDNS 副本不足而导致的间歇性 DNS 解析失败。请使用 kubectl describe pod 检查事件,使用 kubectl describe node 查看已分配的 IP 数量,并使用 CloudWatch Container Insights 监控集群规模下的 DNS error 速率。
# Enable prefix delegation to increase pod density per node
kubectl set env daemonset aws-node \
-n kube-system \
ENABLE_PREFIX_DELEGATION=true \
WARM_PREFIX_TARGET=1
# Check current IP usage on a node
kubectl describe node ip-10-0-1-100.ec2.internal | grep -A5 'Allocatable'快速检查
请测试您对本课 AWS Solutions Architect(SAA-C03)概念的理解。
课程回顾
在本课中,您学习了:Amazon VPC CNI plugin 为每个 Pod 分配原生 VPC IP,从而实现无缝的 VPC 集成;AWS Load Balancer Controller 为 HTTP Ingress 预置 ALB,并为 TCP/UDP Service 预置 NLB;以及 Security Groups for Pods 支持在 Pod 层面控制网络访问。接下来我们将探索 IRSA,将细粒度的 IAM 角色绑定到 Kubernetes Service Account。
用 AI 导师学习 Cloud & IT Cert Prep — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 150
- 课程
- 600
常见问题解答
「EKS 网络:VPC CNI 与负载均衡」课时是免费的吗?
是的 — 「EKS 网络:VPC CNI 与负载均衡」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Cloud & IT Cert Prep 课程的其余内容,请升级到 CoddyKit PRO。 Cloud & IT Cert Prep 课程共包含 4 节课。
「EKS 网络:VPC CNI 与负载均衡」这节课中我会学到什么?
使用 Amazon VPC CNI 插件为 Pod 分配原生 VPC IP 地址,并通过 AWS Load Balancer Controller 对外提供服务 你通过在浏览器中直接运行的动手代码来练习 Cloud & IT Cert Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Cloud & IT Cert Prep 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Cloud & IT Cert Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「EKS 网络:VPC CNI 与负载均衡」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Cloud & IT Cert Prep 课中编写并运行代码吗?
能。每节 Cloud & IT Cert Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- EKS 控制平面与工作节点
- 用于无服务器 Pod 的 Fargate 配置文件
- EKS 网络:VPC CNI 与负载均衡
- 服务账户的 IAM 角色(IRSA)