DevOps/Kubernetes

[Kubernetes] EKS에서 로드밸런싱 사용하기 (NLB, ALB)

TTOII 2022. 6. 12. 15:46
728x90
기능 Application Load Balancer Network Load Balancer Classic Load Balancer
로드 밸런서 유형 계층 7 계층 4 계층 4/7
대상 유형 IP, 인스턴스, Lambda IP, 인스턴스, ALB  
흐름/프록시 동작 종료
프로토콜 리스너 HTTP, HTTPS, gRPC TCP, UDP, TLS TCP, SSL/TLS, HTTP, HTTPS
다음을 통해 연결 가능 VIP VIP  

 

🚀 NLB for LoadBalancer Service

Amazon EKS의 네트워크 로드 밸런싱 - Amazon EKS

 

eks에서 로드밸런서를 생성하면 기본적으로 classic LoadBalancer가 생성된다.

EC2 인스턴스를 사용하는 경우 classic LoadBalancer는 정상 작동하지만 Fargate를 사용하는 경우에는 classic LoadBalancer가 작동하지 않는다.
classic LoadBalancer는 반드시 EC2 인스턴스에만 연결될 수 있는데 Fargate 같은 경우 EC2 인스턴스가 생성되지 않기 때문이다.

 

📌 EC2 인스턴스에 NLB 설정하기

service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"

로드밸런서를 만들 때 annotation을 붙여야한다.


external은 외부용이라는 의미이며 nlb-target-typeNLB가 생성되고 NLB의 타겟이되는 대상은 인스턴스라는 의미이다.
정확히는 EC2 인스턴스의 NodePort가 타겟이 된다. 로드밸런서 서비스는 NodePort를 사용한다.

그리고 EC2 인스턴스 내부에 파드가 존재하며 파드 안에는 App이 실행되고 있다.

즉, NLB를 통해 파드 내의 App에 부하 분산한다.

 

 

📌 Fargate에 NLB 설정하기

service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"

다음은 Fargate를 위한 aws-load-balancer-nlb-target-type이다.  

ip 타입은 파드에 NLB가 직접적으로 연결되는 방식이다.
즉, Fargate에 사용하기 위해 만들어 놓은 것이다.

 

인스턴스가 private network에 배치되었으므로 퍼블릭 ip를 가지지 않는다.

 

private 서브넷에 배치되어있다.

 

myapp.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb
          ports:
            - containerPort: 8080

 

mysvc.yaml

apiVersion: v1
kind: Service
metadata:
  name: myweb-svc-lb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "external"
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080

 

annotations를 붙인다.

PS C:\Users\Shinsohui\aws-eks\nlb> kubectl get deploy,rs,po,svc,ep
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myweb-deploy   3/3     3            3           19s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/myweb-deploy-657f957c85   3         3         3       19s

NAME                                READY   STATUS    RESTARTS   AGE
pod/myweb-deploy-657f957c85-4mlzw   1/1     Running   0          18s
pod/myweb-deploy-657f957c85-sxhcz   1/1     Running   0          18s
pod/myweb-deploy-657f957c85-z9xws   1/1     Running   0          18s

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes     ClusterIP      10.100.0.1      <none>        443/TCP        40m
service/myweb-svc-lb   LoadBalancer   10.100.103.31   <pending>     80:30785/TCP   14s

NAME                     ENDPOINTS                                                     AGE
endpoints/kubernetes     192.168.133.118:443,192.168.97.133:443                        40m
endpoints/myweb-svc-lb   192.168.131.98:8080,192.168.167.43:8080,192.168.99.189:8080   14s
PS C:\Users\Shinsohui\aws-eks\nlb> kubectl describe svc myweb-svc-lb
Name:                     myweb-svc-lb
Namespace:                default
Labels:                   <none>
Annotations:              service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
                          service.beta.kubernetes.io/aws-load-balancer-type: external

 

🚀 AWS LoadBalancer Controller 설치

AWS Load Balancer Controller 추가 기능 설치 - Amazon EKS

NLBALB를 구성하기 위해서는 다음 addon를 추가해야한다.

eksctl create iamserviceaccount \
  --cluster=my-cluster \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --attach-policy-arn=arn:aws:iam::111122223333:policy/AWSLoadBalancerControllerIAMPolicy \
  --override-existing-serviceaccounts \
  --approve

eksctl 또는 kubectl을 사용하여 IAM 역할을 생성하고 AWS 로드 밸런서 컨트롤러의 kube-system 네임스페이스에 aws-load-balancer-controller라는 쿠버네티스 서비스 계정을 추가해야한다.

 

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 clusterName=myeks-custom --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller
PS C:\Users\Shinsohui\aws-eks\nlb> helm list -n kube-system
NAME                            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                                 APP VERSION
aws-load-balancer-controller    kube-system     1               2022-06-01 00:05:35.7677369 +0900 KST   deployed        aws-load-balancer-controller-1.4.2    v2.4.2

PS C:\Users\Shinsohui\aws-eks\nlb> kubectl get po -A
NAMESPACE     NAME                                            READY   STATUS    RESTARTS   AGE
default       myweb-deploy-657f957c85-4mlzw                   1/1     Running   0          18m
default       myweb-deploy-657f957c85-sxhcz                   1/1     Running   0          18m
default       myweb-deploy-657f957c85-z9xws                   1/1     Running   0          18m
kube-system   aws-load-balancer-controller-5d9867ff4d-c5lvr   1/1     Running   0          29s
kube-system   aws-load-balancer-controller-5d9867ff4d-hhwwk   1/1     Running   0          29s
kube-system   aws-node-57llb                                  1/1     Running   0          45m
kube-system   aws-node-kbjx5                                  1/1     Running   0          45m
kube-system   aws-node-mscqs                                  1/1     Running   0          45m
kube-system   coredns-556f6dffc4-k5s79                        1/1     Running   0          58m
kube-system   coredns-556f6dffc4-zx2lc                        1/1     Running   0          58m
kube-system   kube-proxy-68rw9                                1/1     Running   0          45m
kube-system   kube-proxy-gl9s6                                1/1     Running   0          45m
kube-system   kube-proxy-k89dw                                1/1     Running   0          45m
PS C:\Users\Shinsohui\aws-eks\nlb> kubectl get svc
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP                                                                         PORT(S)        AGE
kubernetes     ClusterIP      10.100.0.1      <none>                                                                              443/TCP        58m
myweb-svc-lb   LoadBalancer   10.100.103.31   k8s-default-mywebsvc-1771186f98-1a8bcf2f87e5c446.elb.ap-northeast-2.amazonaws.com   80:30785/TCP   18m

 

network 타입의 로드 밸런서가 생성되었다.

EC2 인스턴스 기반의 EKS는 classic이나 network 모두 정상 작동하지만 Fargate의 경우 classic 유형이 연결될 수 없다고 했다. → 그렇기 때문에 반드시 NLB로 구성해야 한다.

 

 

Schema가 internal이라는 것은 내부용으로 사용한다는 것이다.

public network에 배치된 것이 아니므로 외부에서 접속할 수 없다.

 

service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"

internet-facing을 사용해야 public network에 배치된다.

현재 NLB는 private network에 배치되어있다.

외부에 노출이 된 것이 아니기 때문에 다른 내부 서비스에서만 사용할 수 있다.

 

apiVersion: v1
kind: Service
metadata:
  name: myweb-svc-lb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "external"
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080

최종 코드는 다음과 같다.

 

internet-facing로 변경되었고 활성되었다.

 

외부에서 접속 가능하다.

 

🚀 Ingress for ALB

Amazon EKS의 애플리케이션 로드 밸런싱 - Amazon EKS

L7에서 애플리케이션 트래픽을 로드 밸런싱하려면 Kubernetes ingress를 배포해야한다. 이는 AWS Application Load Balancer를 프로비저닝한다. 

Ingress도 마찬가지로 AWS LoadBalancer Controll이 설치되어 있어야 한다.

 

  • alb.ingress.kubernetes.io/target-type: ip - Fargate
  • alb.ingress.kubernetes.io/target-type: ip - EC2
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myweb-ing
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/target-type: instance
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myweb-svc-lb
                port:
                  number: 80
PS C:\Users\Shinsohui\aws-eks\nlb> kubectl get ing
NAME        CLASS    HOSTS   ADDRESS                                                                                PORTS   AGE
myweb-ing   <none>   *       internal-k8s-default-mywebing-ba340b948e-1254008606.ap-northeast-2.elb.amazonaws.com   80      4s

Ingress의 주소가 배치되었다.

 

프로비저닝 중인 ALB를 확인할 수 있다.

 

해당 ALB도 마찬가지로 Schema가 internal이다. 외부에서 사용하기 위해서는 annotations을 조정해야 한다.

 

internal-facing으로 변경되었다.

 

이제 외부에서 접속 가능하다.

728x90