1. 背景与目标

  • 为什么自建 K8s 需要 ALB?
    • ALB(Application Load Balancer)能将外部流量智能路由到集群内不同服务
    • 支持路径路由、HTTPS 终端、自动扩缩容
  • Ingress + ALB 优势
    • 免去手动创建 Nginx/Traefik 负载均衡器
    • 与 AWS 网络生态深度整合(VPC、SG、Target Group)
  • 本文目标
    • 从 IAM 策略到 Ingress 创建,完整部署流程
    • 用 AWS CLI 验证 ALB、TargetGroup 健康状态

2. 前置准备

  • AWS 账号与 IAM

    拥有管理员权限或者创建自定义 IAM 策略

  • Kubernetes 集群信息

    K8s 版本、节点数量、网络插件(如 Flannel)

  • 必要工具

    kubectl version
    helm version
    aws --version

  • 注意事项

    • 确保节点能访问 AWS API(公网或 VPC Endpoint)
    • 确认子网和 SG 已经创建

3. IAM 策略与角色配置

  • 创建 IAM 策略

    对于快速测试环境官方有一套全面的策略json文件,直接下载使用可以有所有必要的策略

    curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/install/iam_policy.json
    

image-EFPH.png

策略创建完后绑定到iam角色,如果没有角色需要创建,我这里有就可以直接绑定

image-goii.png

将所有的k8s集群node节点附加iam角色

image-uoZs.png

4. 创建 IngressClassParams CRD

  • CRD 作用

    • 定义 ALB Ingress 的参数,供后续 Ingress 使用
  • 创建命令示例

    kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master"
    

image-EBBw.png

image-PgTG.png

成功创建了crd的资源对象

ingressclassparams.elbv2.k8s.aws 定义 ALB Ingress 的参数模板(例如 group、scheme、ipTargetType 等)
targetgroupbindings.elbv2.k8s.aws 管理 ALB Target Group 与 Kubernetes Pod/Service 的绑定关系

然后要创建一个 IngressClassParams资源对象,因为 IngressClass 本身太简单了,它只能告诉系统“这个 Ingress 交给 ALB 管理”,
不能定义 ALB 的详细参数(比如 ALB 要共享吗?是公网的还是内网的?TargetType 是 IP 还是实例?)。

于是 AWS 定义了一个 扩展 CRD —— IngressClassParams 来补足这些参数。

结构示例(典型的 IngressClassParams)

apiVersion: elbv2.k8s.aws/v1beta1
kind: IngressClassParams
metadata:
name: png1-icp
spec:
group:
name: IngressClassParams-name# ALB 分组名(多个 Ingress 可共用同一个 ALB)
scheme: internet-facing # 负载均衡器是公网的(也可以 internal)
ipAddressType: ipv4 # IPv4 或 dualstack (IPv4+IPv6)
namespaceSelector:
matchLabels:
use-alb: "true" # 只允许特定命名空间的 Ingress 使用这个 class
tags:
Environment: production # 创建出来的 ALB 上打的 tag

5. 安全组 标签

  • 为 SG 添加 Kubernetes 标签

找到node节点的实例使用的安全组,添加标签

image-ZYNf.png

kubernetes.io/cluster/kubernetes=owned
这里的kubernetes是你的集群名字

6. 安装 AWS Load Balancer Controller

  • 首先创建ServiceAccount,因为我们使用的iam角色,直接绑定该角色即可

kubectl create serviceaccount aws-load-balancer-controller -n kube-system创建serviceaccount

 绑定 IAM 角色(替换你的 IAM Role ARN)
kubectl annotate serviceaccount aws-load-balancer-controller \
  -n kube-system \
  eks.amazonaws.com/role-arn=arn:aws:iam::123456789012:role/your-alb-controller-role
  • Helm 安装命令
    添加helm仓库并且更新
    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=kubernetes \
      --set serviceAccount.create=false \
      --set serviceAccount.name=aws-load-balancer-controller \
      --set image.repository=public.ecr.aws/eks/aws-load-balancer-controller \
      --set image.tag=v2.14.1
    

clusterName是自己的集群名字

watchNamespace参数限制只能某个命名空间使用,不加参数就监控所有命名空间,都可以使用

image-sZEZ.png

执行命令后开始安装

我首次安装时出现" from "STDIN": no matches for kind "IngressClassParams" in version "elbv2.k8s.aws/v1beta1"这个报错,卡了很久,就是因为没有创建IngressClassParams资源,切记要先创建该资源才可以安装

安装完成后

# 1. 查看 Pod
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller

# 2. 查看日志
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller --tail=5

image-xkUg.png

image-tlcW.png

正常情况已经启动完成,看服务日志如果有权限相关的报错,检查iam的角色权限是否缺失

7. 创建 Ingress 资源

  • Ingress YAML 示例

image-FKWN.png

在helm部署完成后会自动出现一个ingressclassparams和ingressclass

接下来就可以创建ingress
示例yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-alb
  namespace: test #命名空间
  annotations:
    kubernetes.io/ingress.class: alb 
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
    alb.ingress.kubernetes.io/healthcheck-path: /
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/subnets: 子网id,可以用tag的方式
spec:
  ingressClassName: alb #指定ingressClassName对象
  rules:
  - http:
      paths:
      - path: /test
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 8209
  - http:
      paths:
      - path: /test1
        pathType: Prefix
        backend:
          service:
            name: test1
            port:
              number: 8101

  • kubernetes.io/ingress.class: alb
    作用:不同的 Ingress Controller 可以共存(比如 Nginx 和 ALB),通过这个字段区分。

  • alb.ingress.kubernetes.io/scheme: internet-facing

    internet-facing:可以被公网访问(会分配公网 IP 和 DNS)。internal:只能在 VPC 内访问。

  • alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'

    告诉 ALB Controller ALB 要监听哪些端口和协议。ALB 支持 HTTP、HTTPS、gRPC 等协议。

  • alb.ingress.kubernetes.io/healthcheck-path: /

    ALB 会定期请求每个后端节点的 / 路径判断是否健康,健康的节点才会被加入目标组。

    可针对服务实际健康接口设置,比如 /healthz

  • alb.ingress.kubernetes.io/target-type: instance

    instance:直接把 EC2 节点作为目标,ALB 发请求到节点上 Service 的 NodePort。ip:把 Pod 的 IP 注册到目标组,ALB 可以直接发请求到 Pod(更现代、更灵活)

  • alb.ingress.kubernetes.io/subnets: 子网id

    ALB 必须至少跨两个可用区的子网以保证高可用。如果不指定子网可以用tag

    公网子网:kubernetes.io/role/elb = 1 内网子网:kubernetes.io/role/internal-elb = 1

image-oFkF.png

加入标签后服务会自动发现并把带标签的子网加入到负载均衡器

  • http:
    paths:

    • path: /test
      pathType: Prefix
      backend:
      service:
      name: test
      port:
      number: 8209
    • 解释
      • path: /test:当请求 URL 以 /test 开头时匹配。
      • pathType: Prefix:表示前缀匹配(还有 Exact 精确匹配)。
      • backend.service.name: test:流量发送到命名空间 test 中的 Service test
      • backend.service.port.number: 8209:Service 的端口号。
        这条规则会把 /test/foo 的请求也路由到 test:8209

写好yaml后apply创建资源,然后观察ingress,发现已经成功创建了host的dns

image-UOHr.png

然后在负载均衡器里面查看已经有我们设置过的规则

image-hYCB.png

image-mIJq.png

目标组里面有所有k8s集群的node节点

到这里就创建成功了,一个命名空间需要一个ingress对象,一个ingress下可以设置多个svc,用不同的路径来区分