侧边栏壁纸
博主头像
背锅小王子博主等级

我从事运维工作有十年之久,主要从事云原生相关的工作,对k8s、devops、servicemesh、可观察性等较为熟悉!

  • 累计撰写 59 篇文章
  • 累计创建 64 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

eks部署aws-load-balancer-controller

背锅小王子
2022-08-22 / 0 评论 / 0 点赞 / 249 阅读 / 1,976 字
温馨提示:
本文最后更新于 2022-11-14,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1、简介

AWS 负载均衡器控制器是帮助管理 Kubernetes 集群的弹性负载均衡器的控制器。

  • 它通过配置Application Load Balancer来满足 Kubernetes Ingress 资源。
  • 它通过配置 网络负载均衡器来满足 Kubernetes服务资源。

2、原理

AWS 负载均衡器控制器的工作原理

图片-1661150935023

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
0

评论区