1、简介
AWS 负载均衡器控制器是帮助管理 Kubernetes 集群的弹性负载均衡器的控制器。
- 它通过配置Application Load Balancer来满足 Kubernetes Ingress 资源。
- 它通过配置 网络负载均衡器来满足 Kubernetes服务资源。
2、原理
AWS 负载均衡器控制器的工作原理
2.1 入口创建
本节描述上述每个步骤(圆圈)。此示例演示了满足 1 个入口资源。
[1]:控制器监视来自 API 服务器的入口事件。当它找到满足其要求的入口资源时,它开始创建 AWS 资源。
[2]: 在 AWS 中为新的入口资源创建ALB (ELBv2)。此 ALB 可以面向 Internet 或内部。您还可以使用注释指定它在其中创建的子网。
[3]:在 AWS 中为入口资源中描述的每个唯一 Kubernetes 服务创建目标组。
[4]:为入口资源注释中详述的每个端口创建侦听器。如果未指定端口,则使用合理的默认值 (80或443)。证书也可以通过注释附加。
[5]:为入口资源中指定的每个路径创建规则。这可确保将流向特定路径的流量路由到正确的 Kubernetes 服务。
除上述内容外,控制器还…
- 当从 k8s 中删除入口资源时删除 AWS 组件。
- 当 k8s 中的入口资源发生变化时修改 AWS 组件。
- 在启动时组装现有与入口相关的 AWS 组件列表,允许您在控制器重新启动时进行恢复。
2.2 入口流量
AWS 负载均衡器控制器支持两种流量模式:
- 实例模式
- IP模式
默认情况下,Instance mode使用,用户可以通过alb.ingress.kubernetes.io/target-type注释显式选择模式。
实例模式
入口流量从 ALB 开始,通过每个服务的 NodePort 到达 Kubernetes 节点。这意味着必须公开从入口资源引用的服务type:NodePort才能被 ALB 访问。
IP模式
入口流量从 ALB 开始,直接到达 Kubernetes pod。CNI 必须支持通过ENI 上的辅助 IP 地址直接访问 POD ip 。
3、创建IAM OIDC提供商
- 创建一个 IAM policy,该策略允许负载均衡器代表您调用 AWS API
AWS GovCloud(美国东部)或 AWS GovCloud(美国西部)AWS 区域
curl -o iam_policy_us-gov.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.2/docs/install/iam_policy_us-gov.json
所有其他 AWS 区域
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.2/docs/install/iam_policy.json
- 应用这个策略
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
- 创建一个 IAM 角色
请将 my-cluster 替换为您的集群的名称,将 111122223333 替换为您的账户 ID,然后运行命令。如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国西部)AWS 区域,则将 arn:aws: 替换为 arn:aws-us-gov:。
eksctl create iamserviceaccount \
--cluster=my-cluster \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name "AmazonEKSLoadBalancerControllerRole" \
--attach-policy-arn=arn:aws:iam::111122223333:policy/AWSLoadBalancerControllerIAMPolicy \
--approve
4、部署
注意:支持的 Kubernetes 版本
- AWS负载平衡器控制器v2.0.0〜v2.1.3要求Kubernetes 1.15+
- AWS负载平衡器控制器v2.2.0〜v2.3.1要求Kubernetes 1.16-1.21
- AWS负载平衡器控制器v2.4.0+需要Kubernetes 1.19+
部署aws-load-balancer-controller ,将 cluster-name 替换为您自己的值
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=cluster-name \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
验证控制器是否已安装
kubectl get deployment -n kube-system aws-load-balancer-controller
输出结果如下:
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 2m
5、部署IngressClass
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb
spec:
controller: ingress.k8s.aws/alb
部署ingress测试
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
namespace: default
annotations:
alb.ingress.kubernetes.io/load-balancer-name: nginx
alb.ingress.kubernetes.io/target-type: ip
kubernetes.io/ingress.class: alb
#alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/tags: Project=bgxwz
alb.ingress.kubernetes.io/success-codes: 200,404
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}]'
#alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443},{"HTTP":80}]'
#alb.ingress.kubernetes.io/certificate-arn: 'arn:aws:acm:ap-southeast-1:xxxxx:certificate/xxxxxx'
#alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=web-front-alb,access_logs.s3.prefix=front-alb-logs
alb.ingress.kubernetes.io/security-groups: xxxxxx
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=120
spec:
# 开启tls支持,根据情况开启
#tls:
#- hosts:
# - nginx.bgxwz.com
# secretName: bgxwz-com-tls
rules:
# alb绑定的域名,根据情况开启
#- host: nginx.bgxwz.com
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
有关annotations中的参数的具体含义,请参考官网:aws-load-balancer-controller
6、子网自动发现
如果你是eksctl创建的eks集群,则会自动添加相应的子网发现的标签,但是若是手动创建的子网,则需要为子网添加相应的标签,否则实例无法正常获取的IP地址
公共子网
kubernetes.io/role/elb 1 或 ''
私有子网
kubernetes.io/role/internal-elb 1 或 ''
7、Pod 就绪检测
AWS 负载均衡器控制器支持“Pod 就绪检测”以指示 pod 已注册到 ALB/NLB 并且可以正常接收流量。控制器在 pod 创建期间通过 mutating webhook 自动将必要的就绪门配置注入到 pod 规范中。
在某些情况下需要 Pod 就绪门以实现完全零停机时间滚动部署。考虑以下示例:
- 部署中的副本数量少
- 开始滚动更新部署
- 推出新 pod 所用的时间少于 AWS 负载均衡器控制器注册新 pod 并使其健康状态在目标组中变为“健康”所需的时间
- 在此滚动更新期间的某个时间点,目标组可能只注册了处于 »Initial« 或 »Draining« 状态的目标;这会导致服务中断
为了避免这种情况,AWS 负载均衡器控制器可以在构成您的入口或服务后端的 pod 上设置就绪条件。True仅当 ALB/NLB 目标组中的相应目标显示健康状态为 »Healthy« 时,Pod 上的条件状态才会设置为。这可以防止部署的滚动更新终止旧 pod,直到新创建的 pod 在 ALB/NLB 目标组中处于“健康”状态并准备好接受流量。
配置
在 AWS 负载均衡器控制器上默认启用 Pod 就绪检测支持。您需要将就绪检测注入标签应用于您想使用此功能的每个命名空间。您可以按如下方式创建和标记命名空间
kubectl label ns default elbv2.k8s.aws/pod-readiness-gate-inject=enabled
namespace/readiness labeled
kubectl describe ns default
Name: default
Labels: elbv2.k8s.aws/pod-readiness-gate-inject=enabled
kubernetes.io/metadata.name=default
Annotations: <none>
Status: Active
标记后,控制器会将 pod 就绪门配置添加到随后创建的所有满足以下所有条件的 pod
- 存在与同一命名空间中的 pod 标签匹配的服务
- 至少存在一个引用匹配服务的目标组绑定
- 目标类型是IP
就绪门具有前缀target-health.elbv2.k8s.aws,控制器仅在 pod 创建期间将配置注入到 pod 规范中。
检查 pod状态,输出结果如下:
$ kubectl get pod nginx-565785f75c-f94wr -o yaml | grep -B7 'type: target-health'
status:
conditions:
- lastProbeTime: null
lastTransitionTime: null
message: Initial health checks in progress
reason: Elb.InitialHealthChecking
status: "True"
type: target-health.elbv2.k8s.aws/k8s-default-nginx-eed73ae057
评论区