掌握流量管理:利用 EKS Ingress 和 AWS 负载均衡器控制器

什么是 Ingress?

在 Kubernetes 中,Ingress 是一个 API 对象,它定义了将外部 HTTP 和 HTTPS 流量路由到集群内服务的规则和配置,并提供了一种管理服务入站流量的方法。它们允许您为不同的 URL 路径或域名定义规则,并相应地将流量定向到特定服务或后端 Pod。

什么是 Ingress 控制器?

Ingress 控制器负责实现 Ingress 资源中定义的规则并管理传入流量的路由。它是一个在集群内运行的组件,用于监视 Ingress 资源的变化。当发生变化时,Ingress 控制器会配置底层负载均衡机制,以根据定义的规则路由流量。Ingress 控制器充当外部环境与集群内运行的服务之间的中介,根据 Ingress 规则将传入的请求定向到适当的后端服务。

Kubernetes Ingress 如何与 aws-alb-ingress-controller 协同工作

下图详细说明了 aws-alb-ingress-controller 在用户定义 Ingress 资源时创建的 AWS 组件。Ingress 资源将入口流量从 ALB 路由到 Kubernetes 集群。

图:Kubernetes Ingress 如何与 aws-alb-ingress-controller 协同工作

Ingress 创建

  1. 在 Kubernetes API 中创建 Ingress 资源时,alb-ingress-controller 会观察到所做的更改。
  2. alb-ingress-controller 根据 Ingress 资源中添加的注释创建 AWS Application Load Balancer。
  3. Ingress 资源中指定的每个后端都会创建目标组。
  4. 可以使用路径或查询参数访问 Application Load Balancer URL。
  5. 根据 Ingress 资源中配置的规则,请求会被重定向到特定的目标组,并通过 ClusterIP 或 NodePort 到达 Pod 服务。

入口流量

AWS ALB 入口控制器支持两种流量模式:实例模式和 IP 模式。用户可以通过在入口和服务定义中声明 alb.ingress.kubernetes.io/target-type 注释来明确指定这些流量模式。

  • 实例模式:入口流量从 ALB 发起,到达为您的服务打开的 NodePort。然后,流量被路由到集群内的 Pod。
  • IP 模式:入口流量从 ALB 发起,直接到达集群内的 Pod。要使用此模式,Kubernetes 集群的网络插件必须使用 ENI 上的辅助 IP 地址作为 Pod IP,也称为 Kubernetes 的 AWS CNI 插件。

注意:如果您在 Fargate 上使用 EKS 的 ALB 入口,则需要使用 IP 模式。

使用eksctl创建EKS 集群

复制代码
ninjamac@ninjamacdeMacBook-Air key % eksctl create cluster \                        
  --name rock-cluster \     
  --region ap-southeast-2 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 2 \
  --nodes-min 1 \
  --nodes-max 3 \
  --managed
2025-05-04 20:59:03 [ℹ]  node "ip-192-168-20-242.ap-southeast-2.compute.internal" is ready
2025-05-04 20:59:03 [ℹ]  node "ip-192-168-33-165.ap-southeast-2.compute.internal" is ready
2025-05-04 20:59:03 [✔]  created 1 managed nodegroup(s) in cluster "rock-cluster"
2025-05-04 20:59:04 [ℹ]  kubectl command should work with "/Users/ninjamac/.kube/config", try 'kubectl get nodes'
2025-05-04 20:59:04 [✔]  EKS cluster "rock-cluster" in "ap-southeast-2" region is ready

为您的集群创建 IAM OIDC Provider:

首先,设置您的集群名称:

复制代码
cluster_name=rock-cluster

获取集群的 OIDC ID:

复制代码
oidc_id=$(aws eks describe-cluster --name $cluster_name --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5) echo $oidc_id

使用以下命令将 IAM OIDC 身份提供商与您的集群关联:

复制代码
eksctl utils associate-iam-oidc-provider --cluster $cluster_name --approve

使用 eksctl 创建 IAM 角色:

下载 AWS 负载均衡器控制器的 IAM 策略,以允许其与 AWS API 交互。

复制代码
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.7.2/docs/install/iam_policy.json

使用下载的文件创建 IAM 策略:

复制代码
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json

使用刚刚创建的 IAM 策略在 kube-system 命名空间中创建服务账户:

复制代码
ninjamac@ninjamacdeMacBook-Air eks % PolicyARN="arn:aws:iam::654654314383:policy/ALBIngressControllerIAMPolicy"
ninjamac@ninjamacdeMacBook-Air eks % echo $PolicyARN 
arn:aws:iam::654654314383:policy/ALBIngressControllerIAMPolicy
ninjamac@ninjamacdeMacBook-Air eks % eksctl create iamserviceaccount \
       --cluster=rock-cluster \
       --namespace=kube-system \
       --name=alb-ingress-controller \
       --attach-policy-arn=$PolicyARN \
       --override-existing-serviceaccounts \
       --approve

通过Helm安装AWS ingress controller

复制代码
helm repo add eks https://aws.github.io/eks-charts
helm repo update eks
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=rock-cluster \
  --set serviceAccount.create=false \
  --set serviceAccount.name=alb-ingress-controller

部署示例应用

现在,我们将一个示例 2048 游戏部署到我们的 Kubernetes 集群中,并使用 Ingress 资源将其暴露给流量。

部署 2048 游戏资源:

复制代码
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.11.0/docs/examples/2048/2048_full.yaml

几分钟后,使用以下命令验证 Ingress 资源是否已创建。

复制代码
kubectl get ingress/ingress-2048 -n game-2048

示例输出如下。

复制代码
NAME           CLASS    HOSTS   ADDRESS                                                                   PORTS   AGE
ingress-2048   <none>   *       k8s-game2048-ingress2-xxxxxxxxxx-yyyyyyyyyy.region-code.elb.amazonaws.com   80      2m32s

通过Route 53创建一个别名记录,指向elb的地址,这样就可以通过自定义的域名来访问2048游戏。

优化 AWS EKS:如何使用一个负载均衡器管理多个子域

在 AWS EKS(弹性 Kubernetes 服务)上的典型 Kubernetes 设置中,如果您依赖 AWS 负载均衡器控制器的默认配置,管理多个子域的成本可能会非常高昂。默认情况下,每次创建新的 Ingress 资源时,AWS 都会预配一个新的应用程序负载均衡器 (ALB)。当您管理多个子域时,此设置的成本会非常高昂,每个 ALB 每月的成本高达数百美元。

我们将介绍一种解决方案,允许您在 AWS EKS 中将单个 ALB 用于多个子域。这种方法不仅可以降低成本,还可以简化管理,尤其是在您在不同的子域上托管大量内部工具或服务的情况下。

为什么在 AWS EKS 中使用多个子域?

在 EKS 集群中使用子域很常见,原因如下:

  • 托管多个应用程序或工具:通常,您可能在同一个 EKS 集群中托管各种应用程序,例如监控工具、仪表板或 CI/CD 流水线。每个应用程序都可以通过单独的子域公开。
  • 受控访问:您可能希望向不同的团队成员公开不同的工具,而无需授予对整个 Kubernetes 集群的完全访问权限。子域方法可以实现更好的访问控制和隔离。
  • 集中式架构:为不同的服务设置子域可以使您的设置井然有序,并更轻松地管理流量、SSL 证书和访问控制。

为多个子域创建 Kubernetes Ingress

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-subdomain-ingress
  namespace: default
  annotations:
    alb.ingress.kubernetes.io/ssl-redirect: '443'
    alb.ingress.kubernetes.io/backend-protocol: HTTP
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/security-groups: sg-xxxxxxx
    alb.ingress.kubernetes.io/group.name: "my-subdomain-group"
    alb.ingress.kubernetes.io/certificate-arn: "certificate-arn-xxxxxxxx"
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/manage-backend-security-group-rules: "true"
spec:
  rules:
    - host: service1.mydomain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: "eks-service-1"
                port:
                  number: 80
    - host: service2.mydomain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: "eks-service-2"
                port:
                  number: 80

您可以使用 tls 代码块(而非"alb.ingress.kubernetes.io/certificate-arn")为子域名配置 SSL 证书。

用于 HTTPS 的 TLS:使用 tls 代码块为您的子域名定义 SSL 证书。您可以使用通配符证书 (*.domain.com) 来简化管理。

复制代码
tls:
    - hosts:
        - service1.example.com
        - service2.example.com
      secretName: example-tls-secret  # SSL certificate for both subdomain

为您的子域定义服务

Ingress 中的每个子域都必须绑定到处理流量的 Kubernetes 服务。以下是 service1 的服务资源示例:

复制代码
apiVersion: v1
kind: Service
metadata:
  name: service1
  namespace: default
  labels:
    app: {your-app}
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: service1

应用配置

Ingress 和服务配置准备就绪后,您可以使用 kubectl 应用它们:

复制代码
kubectl apply -f eks-ingress.yaml
kubectl apply -f eks-service1.yaml
kubectl apply -f eks-service2.yaml

AWS 现在将创建一个单独的 ALB,根据您定义的子域规则路由流量。

高级特性

HTTPS 重定向

HTTP 协议的 URL 应重定向至 HTTPS 协议。我们将使用 alb.ingress.kubernetes.io/actions.${action-name} 注释来设置 Ingress,将 http 流量重定向至 https。

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echoserver
  namespace: echoserver
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/tags: Environment=dev,Team=app
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: '443'
spec:
  rules:
    - host: "dev.sivamuthukumar.com"
      http:
        paths:
          - path: /echo
            pathType: Prefix
            backend:
              service:
                name: echoserver
                port:
                  number: 80

自定义属性和插件

负载均衡器的自定义属性可以通过注释控制 - alb.ingress.kubernetes.io/load-balancer-attributes

例如,要在应用程序负载均衡器中启用 HTTP2,请执行以下操作:

复制代码
alb.ingress.kubernetes.io/load-balancer-attributes: routes.http2.enabled=true

查看其他可以添加到注释中的属性。

您可以通过在 Ingress 对象中添加以下注释,将 WAF 或 AWS Shield 附加到负载均衡器。

复制代码
alb.ingress.kubernetes.io/wafv2-acl-arn: <WAFv2 ACL ARN>
alb.ingress.kubernetes.io/shield-advanced-protection: 'true'

访问控制

可以使用以下注解控制负载均衡器的访问控制。

复制代码
alb.ingress.kubernetes.io/scheme: internal # To enable the internal load balancers
alb.ingress.kubernetes.io/inbound-cidrs: 10.0.0.0/24 # Inbound CIDRs from your network or VPC
alb.ingress.kubernetes.io/security-groups: sg-xxxx, sg-yyyy # Security gr

自定义域名和 SSL 证书

现在,我们将自定义域名绑定到 ALB 和 SSL 证书。您可以通过两种方式绑定 SSL 证书。

如果未指定 [alb.ingress.kubernetes.io/certificate-arn](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/annotations/#certificate-arn) 注释,则可以使用 Ingress 资源中的主机名自动发现 ALB 侦听器的 TLS 证书。

控制器将尝试从 Ingress 中的 tls 字段和 Ingress 规则中的 host 字段中发现 TLS 证书。

在本例中,我们将设置 SSL 证书的自动发现。

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echoserver
  namespace: echoserver
  annotations:
    **kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/tags: Environment=dev,Team=app**
spec:
  rules:
    - host: "dev.spectaflare.com"
      http:
        paths:
          - path: /echo
            pathType: Prefix
            backend:
              service:
                name: echoserver
                port:
                  number: 80

执行curl命令

复制代码
curl https://dev.spectaflare.com/echo -i
HTTP/1.1 200 OK

总结

AWS 负载均衡器控制器提供了一种 Kubernetes 原生的方式来配置和管理 Elastic Load Balancer,用于将流量路由到 Kubernetes 集群中运行的应用程序。我希望我已经向您解释了路由、入口组、SSL 配置、HTTP 到 HTTPS 重定向以及其他高级概念。

码字不易,如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

相关推荐
阿里云云原生8 小时前
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
数据库·阿里云·云计算
家庭云计算专家9 小时前
一键设置动态域名+ipv6内网直通访问ssh服务-家庭云计算专家
运维·docker·容器·云计算·ssh·onlyoffice
qq_390369539 小时前
AWS之数据分析类产品
大数据·数据分析·aws
Johny_Zhao10 小时前
堆叠、MLAG、VPC、VSS 技术对比及架构建议
linux·网络·人工智能·python·网络安全·ai·信息安全·云计算·cisco·等保测评·huawei·系统运维
千叶真尹11 小时前
基于阿里云DataWorks的物流履约时效离线分析
阿里云·云计算
知识点集锦12 小时前
代发考试战报:思科华为HCIP HCSE CCNP 考试通过
网络·学习·安全·华为·云计算
冰菓Neko17 小时前
《云计算》第三版总结
云计算
cooldream200917 小时前
深入理解负载均衡:传输层与应用层的原理与实战
运维·负载均衡·系统架构师
曹朋羽17 小时前
Spring Cloud LoadBalancer (负载均衡)
spring·spring cloud·微服务·负载均衡