# AWS - EKS + (ALB/NLB) Load Balancer Controller


# 前言

在地端我們可以用 Service 或是一些 Ingress 來管理一些流量,雲端 AWS 中提供 AWS Load Balancer Controller 讓 Kubernetes 自動建立,設定與管理 AWS Load Balancer (ALB/NLB)


# 為什麽需要他

Kubernetes 中的原生 Service Type Load Balancer ,在雲端把把它交給底層『Cloud Controller Manager (CCM)』建立 Load Balancer

但是有些缺點

  • AWS 原生的 Cloud Control Manager 只能建立 Classic Load Balancer (舊版)
  • 想要建立新版的 ALB/NLB 就必須安裝 AWS Load Balancer Controller

# 架構

User Request > ALB/NLB (由 AWS Load Balancer Controller 建立) > EKS Service/Ingress > Pods on EC2/Fargate

Controller 負責 Listen

  • K8s Ingress (對應 ALB)
  • K8s Service (對應 NLB)

然後呼叫 AWS API

  • 自動建立 ALB/NLB
  • 維護 Target Group, Security Group, Listener Rules
  • 確保 Load Balancer 狀態與 K8s 配置一致

# 安裝流程


# Step.1 安裝 IAM OIDC Provider

1
2
3
4
eksctl utils associate-iam-oidc-provider \
--region ap-northeast-1 \
--cluster my-cluster \
--approve

# Step.2 建立 IAM Policy

1
2
3
4
5
6
# Download an IAM policy for the AWS Load Balancer Controller
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.0/docs/install/iam_policy.json
# Create an IAM policy using the policy
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json

# Step.3 建立 IAM Role for Service Account (IRSA)

1
2
3
4
5
6
7
8
eksctl create iamserviceaccount \
--cluster=<cluster-name> \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--region <aws-region-code> \
--approve

# Step.4 安裝 Controller (使用 Helm)

1
2
3
4
5
6
7
8
9
10
11
# Add the eks-charts Helm chart repository
helm repo add eks https://aws.github.io/eks-charts
# Update your local repo
helm repo update eks
# Install the AWS Load Balancer Controller
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=my-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--version 1.13.0

# Step.5 使用資源

# ALB(Ingress)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: game-2048
name: ingress-2048
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-2048
port:
number: 80

# NLB(Service)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Service
metadata:
namespace: game-2048
name: service-2048
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: LoadBalancer
selector:
app.kubernetes.io/name: app-2048

# Reference

  • AWS - Route internet traffic with AWS Load Balancer Controller
  • AWS - Install AWS Load Balancer Controller with Helm
  • AWS re:Post - How do I set up the AWS Load Balancer Controller on an Amazon EKS cluster for Fargate?