이번 포스트에서는 저번 블로그 글에서 소개했던 K8s 클러스터 내에 LoxiLB 파드를 배포해서 external 로드밸런서 서비스를 구성하는 방법을 EKS에 적용해 보겠습니다.
이전 내용과 비교해서 달라진 점은 (당연한 말이지만) 클러스터 구성을 K3s가 아니라 EKS를 사용하는 것과, EKS 특성상 마스터 노드가 없다는 점입니다.
로드밸런서 기능을 하는 loxilb-lb 파드는 마스터 노드에 배포되도록 toleration이 설정되어 있습니다. 따라서 이번 포스트에서는 마스터 노드 역할을 할 노드를 생성하고 추가 taint를 추가하여 loxilb-lb용 노드로 사용할 것입니다.
준비사항
이 포스트에서는 로컬 서버에 AWS CLI, eksctl, 그리고 kubectl이 설치되었음을 가정하고 설명합니다.
AWS CLI 설치는 이 링크를 참조하시면 됩니다.
eksctl 설치는 이 링크를 참조하시면 됩니다.
kubectl (eks 용) 설치는 이 링크를 참조하시면 됩니다.
또한, EKS 클러스터를 프로비저닝 할 수 있는 IAM 계정 생성 과정 및 aws cli 계정 등록 과정은 생략합니다.
EKS 클러스터 생성
다음 명령어로 EKS 클러스터를 생성합니다.
eksctl create cluster \
--version 1.24 \
--name loxilb-demo \
--vpc-nat-mode Single \
--region ap-northeast-2 \
--node-type t3.small \
--nodes 4 \
--with-oidc \
--managed
해당 명령어는 노드 4개를 생성하고 public 서브넷을 생성합니다. 노드 2개는 loxilb-lb를, 다른 2개는 loxilb-peer를 실행할 것입니다. 편의성을 위해서 노드 그룹을 나누지는 않았습니다.
생성이 끝나면 kubectl 명령어로 노드들을 조회할 수 있습니다.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-47-35.ap-northeast-2.compute.internal Ready <none> 4h20m v1.24.15-eks-a5565ad
ip-192-168-62-216.ap-northeast-2.compute.internal Ready <none> 4h20m v1.24.15-eks-a5565ad
ip-192-168-8-187.ap-northeast-2.compute.internal Ready <none> 4h20m v1.24.15-eks-a5565ad
ip-192-168-80-56.ap-northeast-2.compute.internal Ready <none> 4h20m v1.24.15-eks-a5565ad
노드들 중 ip-192-168-47-35 노드와 ip-192-168-62-216 노드를 loxilb-lb 노드로 사용하겠습니다. 다음 명령어로 노드에 각각 “loxilb.io/loxilb-node=true” taint를 설정합니다.
$ kubectl taint nodes ip-192-168-47-35.ap-northeast-2.compute.internal loxilb.io/loxilb-node=true:NoSchedule
node/ip-192-168-47-35.ap-northeast-2.compute.internal tainted
$ kubectl taint nodes ip-192-168-62-216.ap-northeast-2.compute.internal loxilb.io/loxilb-node=true:NoSchedule
node/ip-192-168-62-216.ap-northeast-2.compute.internal tainted
그리고 마찬가지로 노드에 각각 “loxilb.io/loxilb-node=true” label 역시 추가합니다.
$ kubectl label nodes ip-192-168-47-35.ap-northeast-2.compute.internal loxilb.io/loxilb-node=true
node/ip-192-168-47-35.ap-northeast-2.compute.internal labeled
$ kubectl label nodes ip-192-168-62-216.ap-northeast-2.compute.internal loxilb.io/loxilb-node=true
node/ip-192-168-62-216.ap-northeast-2.compute.internal labeled
loxilb-lb 배포
다음은 loxilb-lb를 배포하기 위한 yaml 파일입니다. 이전 포스트와 내용은 거의 동일합니다. 한 가지 다른 점은 “loxilb.io/loxilb-node” taint/label이 설정된 노드에서 실행하기 위해 toleration과 nodeAffinity가 변경되었습니다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: loxilb-lb
namespace: kube-system
spec:
selector:
matchLabels:
app: loxilb-app
template:
metadata:
name: loxilb-lb
labels:
app: loxilb-app
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
tolerations:
- key: "loxilb.io/loxilb-node"
operator: Exists
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "loxilb.io/loxilb-node"
operator: Exists
containers:
- name: loxilb-app
image: "ghcr.io/loxilb-io/loxilb:latest"
imagePullPolicy: Always
command: [ "/root/loxilb-io/loxilb/loxilb", "--bgp", "--egr-hooks", "--blacklist=cni[0-9a-z]|veth.|flannel." ]
ports:
- containerPort: 11111
- containerPort: 179
securityContext:
privileged: true
capabilities:
add:
- SYS_ADMIN
---
apiVersion: v1
kind: Service
metadata:
name: loxilb-lb-service
namespace: kube-system
spec:
clusterIP: None
selector:
app: loxilb-app
ports:
- name: loxilb-app
port: 11111
targetPort: 11111
protocol: TCP
- name: loxilb-app-bgp
port: 179
targetPort: 179
protocol: TCP
위의 내용을 loxilb-lb.yaml 파일에 저장한 후, 다음 명령어로 eks에 배포합니다.
$ kubectl apply -f loxilb-lb.yaml
daemonset.apps/loxilb-lb created
service/loxilb-lb-service created
배포가 정상적으로 완료되면 다음 명령어로 loxilb-lb 파드가 2개만 생성되었음을 확인할 수 있습니다.
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-9wz7g 1/1 Running 0 5h36m
kube-system aws-node-ddm8t 1/1 Running 0 5h36m
kube-system aws-node-rbbvj 1/1 Running 0 5h36m
kube-system aws-node-wlmwh 1/1 Running 0 5h36m
kube-system coredns-dc4979556-2d24q 1/1 Running 0 5h44m
kube-system coredns-dc4979556-9fgdd 1/1 Running 0 5h44m
kube-system kube-proxy-7mmqx 1/1 Running 0 5h36m
kube-system kube-proxy-txbgv 1/1 Running 0 5h36m
kube-system kube-proxy-wf4v2 1/1 Running 0 5h36m
kube-system kube-proxy-x5n6f 1/1 Running 0 5h36m
kube-system loxilb-lb-p9d9s 1/1 Running 0 3s
kube-system loxilb-lb-zsqqh 1/1 Running 0 3s
loxilb-peer 배포
다음은 loxilb-peer를 배포하기 위한 yaml 파일입니다. 마찬가지로 nodeAffinity 부분만 변경되었습니다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: loxilb-peer
namespace: kube-system
spec:
selector:
matchLabels:
app: loxilb-peer-app
template:
metadata:
name: loxilb-peer
labels:
app: loxilb-peer-app
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "loxilb.io/loxilb-node"
operator: DoesNotExist
containers:
- name: loxilb-peer-app
image: "ghcr.io/loxilb-io/loxilb:latest"
imagePullPolicy: Always
command: [ "/root/loxilb-io/loxilb/loxilb", "--peer" ]
ports:
- containerPort: 11111
- containerPort: 179
securityContext:
privileged: true
capabilities:
add:
- SYS_ADMIN
---
apiVersion: v1
kind: Service
metadata:
name: loxilb-peer-service
namespace: kube-system
spec:
clusterIP: None
selector:
app: loxilb-peer-app
ports:
- name: loxilb-peer-app
port: 11111
targetPort: 11111
protocol: TCP
- name: loxilb-peer-bgp
port: 179
targetPort: 179
protocol: TCP
위의 내용을 loxilb-peer.yaml 파일에 저장한 후, 다음 명령어로 배포합니다.
$ kubectl apply -f loxilb-peer.yaml
daemonset.apps/loxilb-peer created
service/loxilb-peer-service created
배포가 완료되면 다음 명령어로 loxilb-peer 파드가 생성되었음을 확인할 수 있습니다.
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-9wz7g 1/1 Running 0 5h45m
kube-system aws-node-ddm8t 1/1 Running 0 5h45m
kube-system aws-node-rbbvj 1/1 Running 0 5h45m
kube-system aws-node-wlmwh 1/1 Running 0 5h45m
kube-system coredns-dc4979556-2d24q 1/1 Running 0 5h53m
kube-system coredns-dc4979556-9fgdd 1/1 Running 0 5h53m
kube-system kube-proxy-7mmqx 1/1 Running 0 5h45m
kube-system kube-proxy-txbgv 1/1 Running 0 5h45m
kube-system kube-proxy-wf4v2 1/1 Running 0 5h45m
kube-system kube-proxy-x5n6f 1/1 Running 0 5h45m
kube-system loxilb-lb-p9d9s 1/1 Running 0 8m38s
kube-system loxilb-lb-zsqqh 1/1 Running 0 8m38s
kube-system loxilb-peer-pl8mt 1/1 Running 0 10s
kube-system loxilb-peer-tqpqk 1/1 Running 0 10s
kube-loxilb 배포
다음 명령어로 kube-loxilb.yaml 파일을 다운로드합니다.
wget -c https://raw.githubusercontent.com/loxilb-io/loxilb/main/cicd/k3s-flannel-incluster/kube-loxilb.yml
그리고 다음과 같이 kube-loxilb.yaml 파일의 args 항목을 수정합니다.
extBGPPeers 값은 위에서 gobgp를 실행한 test client 서버의 private IP와 AS ID로 수정합니다.
args:
- --externalCIDR=123.123.123.1/24
- --setBGP=64512
- --extBGPPeers=192.168.52.169:64515
파일 수정 후, 다음 명령어로 kube-loxilb를 배포할 수 있습니다.
$ kubectl apply -f kube-loxilb.yml
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
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-9wz7g 1/1 Running 0 5h57m
kube-system aws-node-ddm8t 1/1 Running 0 5h57m
kube-system aws-node-rbbvj 1/1 Running 0 5h57m
kube-system aws-node-wlmwh 1/1 Running 0 5h57m
kube-system coredns-dc4979556-2d24q 1/1 Running 0 6h5m
kube-system coredns-dc4979556-9fgdd 1/1 Running 0 6h5m
kube-system kube-loxilb-59f678cf9d-ks8fb 1/1 Running 0 27s
kube-system kube-proxy-7mmqx 1/1 Running 0 5h57m
kube-system kube-proxy-txbgv 1/1 Running 0 5h57m
kube-system kube-proxy-wf4v2 1/1 Running 0 5h57m
kube-system kube-proxy-x5n6f 1/1 Running 0 5h57m
kube-system loxilb-lb-p9d9s 1/1 Running 0 20m
kube-system loxilb-lb-zsqqh 1/1 Running 0 20m
kube-system loxilb-peer-pl8mt 1/1 Running 0 12m
kube-system loxilb-peer-tqpqk 1/1 Running 0 12m
이제 external 로드밸런서 서비스를 사용하기 위한 LoxiLB 배포가 전부 완료되었습니다.
Test 서비스 생성
로드밸런서 서비스 동작을 확인하기 위해 nginx 서비스를 생성합니다. 다음은 nginx 파드와 서비스를 생성하는 yaml 파일입니다.
apiVersion: v1
kind: Service
metadata:
name: nginx-lb1
annotations:
loxilb.io/lbmode: "fullnat"
spec:
externalTrafficPolicy: Local
loadBalancerClass: loxilb.io/loxilb
selector:
what: nginx-test
ports:
- port: 55002
targetPort: 80
type: LoadBalancer
externalIPs:
- 192.168.8.187
- 192.168.80.56
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
labels:
what: nginx-test
spec:
containers:
- name: nginx-test
image: ghcr.io/loxilb-io/nginx:stable
ports:
- containerPort: 80
externalIPs에 peer 노드의 private IP를 지정했습니다. 이 부분을 현재 세팅에 맞게 변경한 후, nginx.yaml 파일에 저장하고 다음 명령어로 eks에 배포합니다. 생성된 LoadBalancer 서비스에 지정한 external IP 가 할당되었음을 확인할 수 있습니다.
$ kubectl apply -f nginx.yaml
service/nginx-lb1 created
pod/nginx-test created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-test 1/1 Running 0 4s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 11d
nginx-lb1 LoadBalancer 10.100.45.36 192.168.8.187,192.168.80.56 55002:31038/TCP 98m
이제 외부에서 peer 노드의 public IP를 사용해서 LoadBalancer 서비스에 접근할 수 있습니다.
Comentarios