1. Introduction
일단 두가지 방식의 Load Balancer가 존재합니다.
Network Load Balancer
Application Load Balancer
두가지 방식에 대해서 설명하도록 하겠습니다.
2. Network Load Balancer
2.1 What is Network Load Balancer
L4 에서 로드 밸런싱
네트워크 트래픽을 분산시킴
2.2 Deploying Nginx
cat <<EOF > nginx-deployment.yaml
apiVersion : apps/v1
kind : Deployment
metadata :
name : nginx-deployment
labels :
app : nginx
spec :
replicas : 2
selector :
matchLabels :
app : nginx
template :
metadata :
labels :
app : nginx
spec :
containers :
- name : nginx
image : nginx:1.14.2 # ECS Container 로 수정
imagePullPolicy : Always
ports :
- name : http
containerPort : 80
EOF
$ kubectl apply -f nginx-deployment.yaml
$ kubectl get pods
2.3 Network Load Balancer
cat <<EOF > network-service.yaml
apiVersion : v1
kind : Service
metadata :
name : nginx-service-lb
annotations :
service.beta.kubernetes.io/aws-load-balancer-type : external
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type : ip
service.beta.kubernetes.io/aws-load-balancer-scheme : internet-facing
spec :
type : LoadBalancer
selector :
app : nginx
ports :
- protocol : TCP
port : 80
targetPort : 80
EOF
$ kubectl apply -f network-service.yaml
$ kubectl get services
AWS에서는 두가지 모드로 AWS Load Balancer를 Kubernetes 위에서 올릴수 있습니다.
Ingress를 통해서 Application Load Balancers 로 프로비저닝 하는 경우
Service를 통해서 Network Load Balancers 로 프로비저닝 하는 경우
3. Application Load Balancer
3.1 What is Application Load Balancer
아래 그림처럼 Application LB의 경우 Rule이 listener 를 정의하게 되며,
클라이언트로부터 온 request를 미리 지정해둔 target으로 라우팅 하게 됩니다.
따라서 반드시 default rule은 지정을 해주어야 합니다.
Multiple target groups 을 지정할수 있으며, 각 target group마다 health check을 설정 할 수 있습니다.
EKS 에서 배포되는 ALB의 특징은 다음과 같습니다.
Kubernetes Ingress 생성할때 AWS Application Load Balancer 도 함께 프로비져닝 됩니다.
ALB는 L7 에서 로드 밸런싱되며, L4로 하려면 위에 있는 Network Load Balancer 를 하면 됩니다.
3.2 AWS Load Balancer Contoller
AWS LB Contoller를 통해서 Kubernetes를 위한 AWS Elastic Load Balancers 를 관리하게 됩니다.
Ingress 는 Application Load Balancers 를 프로비져닝
Service 는 Network Load Balancers 를 프로비져닝
AWS Load Balancer Controller 는 오픈소스.
설치 방법은 링크 를 참조 합니다.
3.2.1 OIDC 생성
먼저 EKS Cluster를 위한 OpenID Connect (OIDC) 가 있는지 확인해 봅니다.
$ aws eks describe-cluster --name <cluster_name> --query "cluster.identity.oidc.issuer" --output text
https://oidc.eks.ap-northeast-2.amazonaws.com/id/D12E32BC25678012345689123456894E
# 있는지 확인
$ aws iam list-open-id-connect-providers | grep D12E32BC25678012345689123456894E
"Arn" : "arn:aws:iam::130384630012:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/D12E32BC25678012345689123456894E"
# 만약 없다면 새로 생성합니다.
$ eksctl utils associate-iam-oidc-provider --cluster <cluster_name> --approve
3.2.2 IAM Policy & Role 설정
아래의 IAM Policy를 다운로드 받습니다.
해당 policy를 통해서 AWS API 콜을 할수 있게 됩니다.
$ curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.3.1/docs/install/iam_policy.json
# IAM Policy
$ aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
# 잘 생성됐는지 확인합니다.
$ aws iam list-policies | jq '.Policies[] | select(.PolicyName == "AWSLoadBalancerControllerIAMPolicy")'
{
"PolicyName" : "AWSLoadBalancerControllerIAMPolicy" ,
"PolicyId" : "ABCDEFG123456789ABCD" ,
"Arn" : "arn:aws:iam::123456789012:policy/AWSLoadBalancerControllerIAMPolicy" ,
"Path" : "/" ,
"DefaultVersionId" : "v1" ,
"AttachmentCount" : 1,
"PermissionsBoundaryUsageCount" : 0,
"IsAttachable" : true ,
"CreateDate" : "2021-01-16T11:39:19+00:00" ,
"UpdateDate" : "2021-01-16T11:39:19+00:00"
}
IAM Role 을 생성하고, kube-system 아래에 service account도 생성해줍니다.
attach-policy-arn 의 경우 위에서 만든 ARN주소를 넣습니다.
$ eksctl create iamserviceaccount \
--cluster = my_cluster \
--namespace = kube-system \
--name = aws-load-balancer-controller \
--attach-policy-arn = arn:aws:iam::123456789012:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--approve
추가적으로 alb-ingress-controller 삭제해주는 부분이 있는데..
이건 문서 에 링크만 남기겠습니다.
3.2.3 AWS Load Balancer Contoller 설치
eks-charts repository 를 추가합니다.
$ helm repo add eks https://aws.github.io/eks-charts
$ helm repo update
설치합니다.
$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set awsRegion = <Region_Name> \
--set awsVpcID = <Cluster_VPC_ID> \
--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
$ kubectl get serviceaccounts aws-load-balancer-controller -n kube-system
3.2.4 2048 Game
cat <<EOF > game-2048.yaml
---
apiVersion : v1
kind : Namespace
metadata :
name : game-2048
---
apiVersion : apps/v1
kind : Deployment
metadata :
namespace : game-2048
name : deployment-2048
spec :
selector :
matchLabels :
app.kubernetes.io/name : app-2048
replicas : 5
template :
metadata :
labels :
app.kubernetes.io/name : app-2048
spec :
containers :
- image : alexwhen/docker-2048
imagePullPolicy : Always
name : app-2048
ports :
- containerPort : 80
---
apiVersion : v1
kind : Service
metadata :
namespace : game-2048
name : service-2048
spec :
ports :
- port : 80
targetPort : 80
protocol : TCP
type : NodePort
selector :
app.kubernetes.io/name : app-2048
---
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
namespace : game-2048
name : ingress-2048
annotations :
kubernetes.io/ingress.class : alb
# alb.ingress.kubernetes.io/group.name: game-2048
# alb.ingress.kubernetes.io/healthcheck-path: "/health-check"
alb.ingress.kubernetes.io/scheme : internet-facing
alb.ingress.kubernetes.io/target-type : ip
alb.ingress.kubernetes.io/listen-ports : ' [{"HTTP": 80}, {"HTTP":8080}]'
# alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
# alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
spec :
defaultBackend :
service :
name : zeppelin-server
port :
number : 80
rules :
- http :
paths :
- path : /*
pathType : ImplementationSpecific
backend :
service :
name : service-2048
port :
number : 80
EOF
위의 내용을 배포합니다.
(위의 내용이 해당 파일 내용과 동일합니다.)
$ kubectl apply -f game-2048.yaml
$ kubectl get ingress -n game-2048
나온 주소로 들어가면 다음과 같은 화면이 나옵니다.