AWS自建k8s集群使用Ingress + ALB作为集群服务统一入口
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

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

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

4. 创建 IngressClassParams CRD
-
CRD 作用
- 定义 ALB Ingress 的参数,供后续 Ingress 使用
-
创建命令示例
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master"


成功创建了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节点的实例使用的安全组,添加标签

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 ekshelm 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参数限制只能某个命名空间使用,不加参数就监控所有命名空间,都可以使用

执行命令后开始安装
我首次安装时出现" 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


正常情况已经启动完成,看服务日志如果有权限相关的报错,检查iam的角色权限是否缺失
7. 创建 Ingress 资源
- Ingress YAML 示例

在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

加入标签后服务会自动发现并把带标签的子网加入到负载均衡器
-
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中的 Servicetest。backend.service.port.number: 8209:Service 的端口号。
这条规则会把/test/foo的请求也路由到test:8209。
- path: /test
写好yaml后apply创建资源,然后观察ingress,发现已经成功创建了host的dns

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


目标组里面有所有k8s集群的node节点
到这里就创建成功了,一个命名空间需要一个ingress对象,一个ingress下可以设置多个svc,用不同的路径来区分