이 글은 EKS에서 AWS ALB controller(AWS Load Balancer Controller)를 사용하는 방법을 설명합니다.
※ github 링크: https://github.com/choisungwook/eks-practice/tree/main/alb_controller
※ 유투브 영상: https://youtu.be/JJfin3N-43E
1. ALB controller이란?
EKS에서 kubernetes spec으로 AWS NLB또는 ALB를 생성하려면 ALB controller를 설치해야합니다. ALB controller가 설치되어 있지 않으면 AWS Loadbalancer생성단계가 pending상태에 멈춥니다.
ALB는 Application LoadBalancer약자가 아니라 AWS LoadBalancer 약자입니다. github에 오픈소스로 공개되어 있으며 사용 메뉴얼도 있습니다.
2. 동작원리
ALB controller은 kubernetes API server를 감시(watch)하여 ALB 이벤트 발생을 인지합니다. 이벤트가 발생하면 AWS API를 사용하여 ALB 작업을 수행합니다.
3. 실행 전제조건
3.1 AWS Subnet tags
ALB controller를 사용하기 위해 subnet tag가 적절하게 설정되야 합니다. tag가 없다면 ALB controller은 제대로 동작하지 않습니다. eksctl를 사용하여 EKS를 설치하면, subnet tag가 자동으로 설정되어 있습니다. 자세한 내용은 공식문서를 참고하시길 바랍니다. (eksctl로 EKS를 설치했으면 자동으로 subnet tag가 설정되어 있습니다)
- private subnet: kubernetes.io/role/internal-elb = 1
- public subnet: kubernetes.io/role/elb = 1
3.2 AWS 인증정보(feat: EKS OIDC provider)
ALB controller는 AWS API를 사용하므로 AWS인증정보가 필요합니다. 인증정보를 하드코딩하게 되면, pod가 해킹당하여 인증정보가 탈취당했을 때 보안위험이 생깁니다.
그래서 pod별로 IAM role을 할당하는 ISRA를 사용하여 임시로 사용하는 임시자격증명을 사용하는 것이 안전합니다. 임시자격증명을 생성할 때 EKS OIDC proivder를 사용합니다.
EKS 공식문서에서도 EKS OIDC provider를 사용하여 ALB controller설치 메뉴얼을 설명합니다. eksctl로 간단히 EKS OIDC provider를 설치할 수 있습니다. 생성한 EKS ODIC provider는 [AWS IAM Identity provider]메뉴에서 확인할 수 있습니다.
CLUSTER_NAME="baisc-cluster"
eksctl utils associate-iam-oidc-provider --cluster ${CLUSTER_NAME} --approve
4. 설치방법
저는 AWS ISRA와 helm을 사용하여 AWS ALB controller을 설치했습니다.
4.1 준비
ALB controller pod에서 사용할 IAM policy를 생성합니다. IAM policy는 EKS공식문서에서 제공한 policy를 다운로드 받았습니다.
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json
AWS CLI를 사용하여 IAM policy를 생성합니다.
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
eksctl명령어를 사용하여 ALB controller에 사용할 IAM role과 kubernetes serviceaccount를 생성합니다. 이전에 생성한 IAM policy arn이 필요합니다.
POLICY_ARN=$(aws iam list-policies --query 'Policies[?PolicyName==`AWSLoadBalancerControllerIAMPolicy`].Arn' --output text)
ROLE_NAME="AmazonEKSLoadBalancerControllerRole"
CLUSTER_NAME="${eks-cluster-name}"
eksctl create iamserviceaccount \
--cluster ${CLUSTER_NAME} \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name ${ROLE_NAME} \
--attach-policy-arn=${POLICY_ARN} \
--approve
eksctl명령어가 끝나면 kubernetes service account와 AWS IAM role이 생성됩니다.
4.2 설치
AWS ALB controller를 설치할 준비가 끝났습니다. helm chart를 사용하하여 AWS ALB controller를 설치합니다.
먼저, EKS helm chart를 추가합니다.
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install 또는 upgrade명령어로 helm chart를 릴리즈합니다. EKS클러스터 이름을 helm values에 꼭 설정해야 합니다. serviceaccount는 이미 생성했으므로 중복 생성하지 않기 위해 false로 설정했습니다.
CLUSTER_NAME="${your_eks_cluster_name}"
helm upgrade --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
kube-system namespace에 ALB Controller pod가 실행중인지 확인합니다.
kubectl -n kube-system get po
5. NLB 생성/삭제 예제
AWS NLB를 쿠버네티스로 생성하려면 쿠버네티스 loadbalancer service의 annotation과 loadBalancerClass를 설정해야 합니다. annotation은 AWS NLB옵션을 설정합니다. 자세한 내용은 공식 사용 메뉴얼을 참조하시길 바랍니다.
예제 yaml는 아래와 같습니다. kubectl apply명령어로 yaml로 배포합니다.
# kubectl apply nlb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-nlb-test
spec:
selector:
matchLabels:
app: nginx-nlb-test
replicas: 1
template:
metadata:
labels:
app: nginx-nlb-test
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-nlb-test
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "80"
spec:
type: LoadBalancer
loadBalancerClass: service.k8s.aws/nlb
selector:
app: nginx-nlb-test
ports:
- port: 80
targetPort: 80
protocol: TCP
yaml파일을 배포한 후, aws console에서 Network유형 ELB가 생성됩니다. 약 5분 기다리시면 Active상태로 변합니다.
Active상태가 된 후, Network LoadBalancer DNS주소를 웹 브라우저에 접속하면 nginx디폴트 페이지가 보입니다.
kuebctl delete로 yaml을 삭제하면 AWS Network LoadBalancer가 삭제됩니다.
kubectl delete -f nlb.yaml
6. ALB 생성/삭제 예제
AWS ALB는 ingress spec으로 생성할 수 있습니다. ingress annotation과 ingrssClassName을 설정해야 합니다. annotation은 AWS ALB옵션을 설정합니다.
예제 yaml는 아래와 같습니다. kubectl apply명령어로 yaml로 배포합니다.
# kubectl apply -f alb.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-alb-test
labels:
app: nginx-alb-test
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-alb-test
spec:
selector:
app: nginx-alb-test
ports:
- name: http
port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-alb-test
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: nginx-alb-test
port:
number: 80
yaml파일을 배포한 후, aws console에서 Application유형 ELB가 생성됩니다. 약 5분 기다리시면 Active상태로 변합니다.
Active상태가 된 후, Application LoadBalancer DNS주소를 웹 브라우저에 접속하면 nginx디폴트 페이지가 보입니다.
kuebctl delete로 yaml을 삭제하면 AWS Application LoadBalancer가 삭제됩니다.
kubectl delete -f alb.yaml
'연재 시리즈' 카테고리의 다른 글
EKS 스터디 - 3주차 2편 - EKS Fargate와 원리 (0) | 2023.04.30 |
---|---|
EKS 스터디 - 3주차 1편 - EKS가 AWS스토리지를 다루는 원리 (0) | 2023.04.28 |
EKS 스터디 - 2주차 2편 - EKS POD IP는 무한대로 할당할 수 있을까? (0) | 2023.04.19 |
EKS 스터디 - 2주차 1편 - EKS는 어떤 CNI를 사용할까? (2) | 2023.04.18 |
EKS 스터디 - 1주차 3편 - eksctl로 EKS생성 (0) | 2023.04.16 |