top of page
  • 작성자 사진LoxiLB

EKS - LoadBalancerClass를 사용해서 LoxiLB 로드밸런서 설정

최종 수정일: 2023년 3월 21일

이번 포스트에서는 EKS에서 LoadBalancer 서비스 생성시 LoadBalancerClass를 지정함으로서, LoxiLB를 로드밸런서로 사용하도록 설정하는 방법을 기술합니다.


쿠버네티스는 EKS든, GCE든 다양한 클라우드 인프라 위에 설치가 가능합니다. 하지만 클라우드 인프라마다 네트워크를 관리하는 방식은 다들 제각각이고, 이걸 쿠버네티스가 전부 지원하는 건 사실상 불가능한 일입니다. 쿠버네티스는 이 문제를 cloud provider라는 인터페이스 모듈을 제공함으로서 해결했습니다. 각 클라우드 공급자는 자기 클라우드 환경에 맞게 cloud provider 인터페이스를 구현해서 쿠버네티스에 제공하고, 쿠버네티스는 cloud provider 인터페이스를 사용해서 로드밸런서, 노드 및 네트워킹 경로를 설정할 수 있습니다.


하지만 간혹 EKS를 사용하지만 ELB가 제공하는 기능 대신 다른 로드밸런서의 기능이 필요한 상황이 생길 수 있습니다. 이럴 때를 대비해서, 쿠버네티스는 1.24 버전부터 서비스 Spec에 LoadBalancerClass 필드를 제공합니다. LoadBalancerClass 필드를 설정하면, cloud provider가 설정한 기본값 이외의 로드밸런서를 사용할 수 있습니다.


LoadBalancerClass가 설정된 서비스에 대해서 cloud provider는 아무 동작도 수행하지 않습니다. LoadBalancerClass를 사용하기 위해서는 해당 LoadBalancerClass를 처리하고 로드밸런서와 연결할 수 있는 애플리케이션과, 로드밸런서 관련 네트워크 설정 같은 작업을 사용자가 해주어야 합니다.


LoxiLB는 kube-loxilb 애플리케이션을 제공하여 LoadBalancerClass를 지원합니다. 이 포스트에서는 kube-loxilb를 EKS에 배포하고 LoxiLB를 설정하는 방법을 살펴보도록 하겠습니다.



kube-loxilb

kube-loxilb는 쿠버네티스에 Deployment 형태로 배포되는 애플리케이션입니다. k8s 서비스 생성 이벤트를 감시하며, 로드밸런서 서비스 스펙에 LoadBalancerClass가 지정되어 있는지 체크합니다. LoadBalancerClass 값이 loxilb.io/loxilb 일 경우, kube-loxilb는 LoxiLB 로드밸런서와 서비스를 연결하고 External IP를 할당합니다.



Topology

테스트를 위해 사용한 토폴로지는 다음과 같습니다.




3개의 노드로 구성된 EKS를 생성하고, 로드밸런서 노드 역할을 할 LoxiLB node를 생성했습니다. 외부에서 토폴로지로 접근이 가능하도록 AWS로부터 외부에서 접근 가능한 public IP를 부여받았고, 이 IP를 LoxiLB node의 eth0 IP (192.168.3.68) 로 연결되도록 설정합니다.

사용한 쿠버네티스 버전은 1.24 이상입니다. (LoadBalancerClass를 지원하는 최소 버전)


eksctl 설치

EKS를 프로비저닝 하기 위해 로컬에 eksctl을 설치하겠습니다. 먼저 AWS CLI부터 설치합니다.


$ sudo apt install unzip
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

그다음 아래 명령어로 AWS CLI 에 사용자의 엑세스 정보를 추가합니다. region은 이 포스트에서는 ap-northeast-2 를 사용하도록 하겠습니다.


$ aws configure 
 AWS Access Key ID [None]: ~~~ 
 AWS Secret Access Key [None]: ~~~ 
 Default region name [None]: ap-northeast-2 
 Default output format [None]: json

이제 eksctl을 설치합니다.


$ curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
$ sudo mv /tmp/eksctl /usr/local/bin
$ eksctl version

EKS 클러스터 생성

ekscli를 사용해 EKS Cluster를 생성합니다. 생성하는 명령어는 다음과 같습니다.


$ eksctl create cluster \
--version 1.24 \
--name loxilb-demo \
--vpc-nat-mode Single \
--region ap-northeast-2 \
--node-type t3.medium \
--nodes 3 \
--with-oidc \
--ssh-access \
--ssh-public-key aws-netlox \
--managed
  • --version : 쿠버네티스 버전을 지정합니다.

  • --name : EKS 클러스터 이름을 지정합니다. 여기에 사용한 이름을 사용해서 EKS의 VPC이름이 정해집니다.

  • --vpc-nat-mode : 테스트를 위해서 Single로 지정합니다.

  • --ssh-public-key : SSH 엑세스를 위한 키를 지정합니다.


LoxiLB 노드 생성

EKS 클러스터가 배포되면, 이제 LoxiLB 노드를 생성합니다.

OS는 Ubuntu 20.04에 t2.large로 인스턴스를 새로 생성합니다. 외부에서 들어오는 트래픽은 LoxiLB 노드를 거쳐 로드밸런싱되어 EKS 로 가야 하기 때문에, VPC를 EKS 클러스터와 같은 VPC로 지정합니다. Subnet은 간편한 테스트를 위해서 EKS 클러스터의 Public network를 사용하겠습니다.


외부에서 접근할 수 있도록 security groups 역시 생성합니다. 이 포스트에서는 외부 접속용 SSH 포트와 8765 포트를 오픈하겠습니다.


LoxiLB 노드와 EKS 노드끼리 통신을 위해서 EKS의 security groups에 loxilb-node-sg 에서 오는 All traffic을 허용하도록 Inbound rules을 추가합니다.



외부에서 접속할 수 있도록 LoxiLB 노드에 Elastic IP 역시 할당합니다.



이제 LoxiLB 노드에 AWS 키 파일을 사용해서 SSH로 접속할 수 있습니다.



$ ssh -i aws-netlox.pem ubuntu@15.164.9.61


LoxiLB 노드에 kubectl 설치

LoxiLB 노드에 kubectl을 설치해서, LoxiLB 노드에서 쿠버네티스를 관리할 수 있게 설정합니다. 위에서 EKS를 1.24 버전으로 배포했기 때문에 kubectl 역시 1.24 버전으로 설치합니다. 원하는 버전을 설치하기 위해서는 이 링크를 참조하시면 됩니다.


$ curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.24.9/2023-01-11/bin/linux/amd64/kubectl
$ chmod +x ./kubectl
$ mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
$ echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc
$ kubectl version --short --client

kubectl을 통해서 EKS에 접근하기 위해서는 AWS 인증과 kubeconfig 파일이 필요합니다.

이 포스트의 eksctl 설치 항목을 참고해서 LoxiLB 노드에서도 AWS 사용자 Key 정보를 등록합니다.


kubeconfig 파일은 eksctl create cluster 명령을 실행했던 노드의 ~/.kube/config 경로에 해당 파일이 생성되어 있습니다. 해당 파일을 LoxiLB 노드의 ~/.kube 디렉토리에 복사합니다.


인증이 끝나면 kubectl get nodes 명령어를 통해 정보를 가져올 수 있습니다.


$ kubectl get nodes
NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-29-103.ap-northeast-2.compute.internal   Ready    <none>   46m   v1.24.9-eks-49d8fe8
ip-192-168-54-159.ap-northeast-2.compute.internal   Ready    <none>   46m   v1.24.9-eks-49d8fe8
ip-192-168-91-227.ap-northeast-2.compute.internal   Ready    <none>   46m   v1.24.9-eks-49d8fe8


LoxiLB 노드에 docker ce 설치

이 링크를 참고하여 LoxiLB 노드에 docker를 설치합니다.



LoxiLB 노드에서 LoxiLB 실행

LoxiLB 노드에서 다음 명령으로 LoxiLB 컨테이너를 실행합니다.


$ docker run -u root --cap-add SYS_ADMIN --net=host --restart unless-stopped --privileged -dit -v /dev/log:/dev/log --name loxilb ghcr.io/loxilb-io/loxilb:latest --host=0.0.0.0



k8s에 kube-loxilb 배포

따로 LoadBalancerClass로 LoxiLB 로드밸런서를 지정해서 사용하기 위해서는 kube-loxilb 애플리케이션이 쿠버네티스에 배포되어 있어야 합니다.


LoxiLB 노드에서 다음 명령어로 kube-loxilb 매니페스트 파일을 다운로드합니다.


$ wget https://github.com/loxilb-io/kube-loxilb/raw/main/manifest/kube-loxilb.yaml

kube-loxilb.yaml 파일에서 kube-loxilb Deployment 항목을 찾습니다. spec.container.args 항목으로 가면 loxiURL 과 externalCIDR, setLBMode 설정을 확인할 수 있습니다. kube-loxilb를 배포하기 전에 이 옵션들을 수정해야 합니다.


terminationGracePeriodSeconds: 0
      containers:
      - name: kube-loxilb
        image: ghcr.io/loxilb-io/kube-loxilb:latest
        imagePullPolicy: Always
        command:
        - /bin/kube-loxilb
        args:
        - --loxiURL=http://12.12.12.1:11111,http://14.14.14.1:11111
        - --externalCIDR=123.123.123.1/24
        #- --setBGP=true
        #- --setLBMode=1
        #- --config=/opt/loxilb/agent/kube-loxilb.conf
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"

세 옵션에 대한 설명은 다음과 같습니다.

  • loxiURL : LoxiLB API 서버 주소입니다. http:{LoxiLB node IP}:11111 형태로 지정하면 됩니다. 여러 개를 동시에 지정할 수 있습니다 (LoxiLB HA 클러스터링 구성시 사용)

  • externalCIDR : 로드밸런서가 서비스에 할당할 수 있는, 외부 접근이 가능한 글로벌 아이피를 지정합니다. externalCIDR에 설정된 아이피 대역은 LoxiLB를 사용하는 로드밸런서 서비스의 ExternalIP에 할당됩니다.

  • setLBMode : 로드밸런서의 NAT 모드를 지정합니다. 현재 지원하는 모드는 3가지가 있습니다.

이 포스트의 토폴로지에서 LoxiLB 노드는 192.168.3.68 IP를 가지고 있습니다. 현재 토폴로지의 설정을 적용해 값을 다음과 같이 변경했습니다.


        args:
        - --loxiURL=http://192.168.3.68:11111
        - --externalCIDR=192.168.3.68/32
        #- --setBGP=true
        - --setLBMode=2
        #- --config=/opt/loxilb/agent/kube-loxilb.conf

AWS에서 부여받은 Public IP로 접속하면 LoxiLB 노드로 연결되기 때문에, externalCIDR 옵션에는 LoxiLB 노드의 IP를 설정했습니다.

옵션을 수정한 다음 kubectl 을 사용하여 kube-loxilb를 배포합니다.


$ kubectl apply -f kube-loxilb.yaml
serviceaccount/kube-loxilb created
clusterrole.rbac.authorization.k8s.io/kube-loxilb created
clusterrolebinding.rbac.authorization.k8s.io/kube-loxilb created
deployment.apps/kube-loxilb created

배포가 완료되면 다음 명령으로 k8s의 kube-system 네임스페이스에 Deployment가 생성되었음을 확인할 수 있습니다.


$ kubectl -n kube-system get deployment
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
coredns       2/2     2            2           4d2h
kube-loxilb   1/1     1            1           113s


LoadBalancerClass를 사용해 서비스 생성

이제 LoadBalancerClass를 지정해서 LoxiLB를 로드밸런서로 사용할 수 있습니다. 테스트를 위해서 다음과 같이 nginx.yaml 파일을 작성합니다.


$ vi nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service1
  labels:
    app: loxilb
spec:
  selector:
    app: loxilb
  ports:
    - port: 8765
      targetPort: 80
  type: LoadBalancer
  loadBalancerClass: "loxilb.io/loxilb"
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: loxilb
spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc

nginx.yaml 파일은 nginx-service1 로드밸런서 서비스와 그에 연결된 파드 하나를 생성합니다. 서비스에는 loadBalancerClass로 loxilb.io/loxilb가 지정되어 있습니다. 해당 이름으로 loadBalancerClass를 지정하면, kube-loxilb가 서비스의 생성을 감지하고 LoxiLb 로드밸런서와 연결하게 됩니다.


다음 명령으로 서비스를 생성합니다.


$ kubectl apply -f nginx.yaml
service/nginx-service1 created
pod/nginx created

서비스를 확인해 보면 externalCIDR에 지정했던 IP를 ExternalIP로 할당받았음을 확인할 수 있습니다.


$ kubectl get svc
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
kubernetes       ClusterIP      10.100.0.1       <none>           443/TCP          4d2h
nginx-service1   LoadBalancer   10.100.124.111   192.168.3.68   
8765:32617/TCP   4m37s

LoxiLB 노드에서, 다음 명령어로 LoxiLB에도 로드밸런서 룰이 생성되었음을 확인할 수 있습니다.


$ docker exec -ti loxilb loxicmd get lb -o wide


외부에서 서비스 접근 확인

이제 LoxiLB 노드의 외부 아이피를 사용해서 k8s 서비스에 접근할 수 있습니다. AWS에서 부여받은 Public IP를 사용해서 LoxiLB 노드에 접근할 수 있습니다 (이 예제에서는 15.164.9.61 입니다). 다음과 같이 curl을 사용해서 외부 접속을 테스트합니다.


MacBookAir ~ % curl http://15.164.9.61:8765
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

nginx 파드에 정상적으로 접근했음을 알 수 있습니다.


관련해서 더 자세한 내용은 github 페이지에서 확인하실 수 있습니다.

조회수 387회댓글 0개

최근 게시물

전체 보기

GIThub

Learn, Contribute & Share

GETTING STARTED

Get started with deploying LoxiLB in your cluster

Documentation

Check LoxiLB Documentation for more information.

Join the LoxiLB slack channel to chat with the developers community.

bottom of page