* 이 글은 백엔드 개발자가 홈서버를 구성하며 겪은 시행착오를 공부하고 정리한 글입니다. 잘못 알고있는 점이 있다면 지적해주시면 감사하겠습니다.
이 글에서는 다음 항목을 다룹니다.
- MetalLB 설치
- LoadBalnacer 구성
- ClusterIP 구성
- NGINX ingress controller 구성
다이어그램으로 나타내면 다음과 같습니다.
앞선 포스트에서 물리 서버 위에 RKE2로 k8s 클러스터를 구성한 후 MySQL을 설치했습니다. 이제 외부에서 접근할 수 있도록 만들어보겠습니다.
Install MetalLB
https://metallb.universe.tf/installation/
MetalLB는 베어 메탈 머신에서 로드밸런서 구현을 제공하는 오픈소스 프로젝트입니다.
Helm을 사용하여 MetalLB를 설치하도록 하겠습니다.
우선 가이드에 따라 MetalLB를 설치할 namespace에 권한을 주어야 합니다. metallb-system 네임스페이스에 설치하도록 하겠습니다.
![]() |
| https://metallb.universe.tf/installation/#installation-with-helm |
권한 설정 파일을 생성합니다.
vi metallb-namespace.yaml
다음 내용을 붙여넣습니다.
apiVersion: v1
kind: Namespace
metadata:
name: metallb-system
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
저장한 뒤에 privilege 설정을 적용합니다.
kubectl apply -f metallb-namespace.yaml
이제 Helm으로 MetalLB를 metallb-system 네임스페이스에 설치합니다.
helm repo add metallb https://metallb.github.io/metallb
helm repo update
helm install metallb metallb/metallb --namespace metallb-system --create-namespace
MetalLB 설정 파일을 만들어줍니다.
vi metallb-config.yaml
다음 내용을 붙여넣습니다.
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: metallb-ip-pool
namespace: metallb-system
spec:
addresses:
- {ip-pool-start}-{ip-pool-end}
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: my-l2-advertisement
namespace: metallb-system
- spec.addresses.... - IP pool을 설정해주는 부분입니다. 사용 가능한 IP pool이 있으시면 해당 IP pool을 등록해주셔도 되고, 없다면 현재 노드의 IP로 등록해주어도 동작합니다. 저는 한 대의 노드로 구성하였으므로 {ip-pool-start}, {ip-pool-end} 둘다 현재 노드의 IP로 설정해주겠습니다.
불가피하게 하나의 IP만 등록할 경우 주의해야할 점이 몇 가지 있습니다.
- 하나의 LoadBalancer만 생성 가능합니다.
- 해당 IP의 노드가 실패할 경우 LoadBalancer를 통한 접근이 불가능해집니다.
- 개방할 port가 겹치지 않아야 합니다.
config 파일을 적용합니다.
kubectl apply -f metallb-config.yaml
Install NGINX
LoadBalnacer에서 원하는 서비스로 트래픽을 전달할 수 있는데, NGINX를 추가로 설치해주는 이유가 궁금할 수 있습니다. 그 이유는 환경적 제약사항을 우회하기 위해서입니다.
저는 하나의 IP만 가용한 환경에서 k8s 클러스터를 구성하고 있습니다. LoadBalancer 서비스는 포트를 분리하더라도 여러 개의 서비스로 트래픽을 보낼 수 없기 때문에, NGINX ingress controller에서 여러 개의 서비스로 트래픽을 분배하는 역할을 수행하도록 구상했습니다.
helm으로 nginx ingress를 설치하기 위해 repo에 ingress-nginx를 추가합니다.
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
31000 port로 MySQL primary pod에 접근하고, 32000 port로 MySQL secondary pods에 접근하도록 하겠습니다.
helm-ingress-values.yaml 파일을 생성하고, 아래 내용을 붙여넣은 후 저장합니다.
tcp:
31000: "default/mysql-primary:3306"
32000: "default/mysql-secondary:3306"
controller:
service:
extraPorts:
- name: mysql-primary
port: 31000
targetPort: 31000
protocol: TCP
- name: mysql-secondary
port: 32000
targetPort: 32000
protocol: TCP
helm-ingress-values.yaml 파일을 사용하여 커스텀한 nginx ingress controller를 설치합니다.
helm install nginx-ingress ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
-f helm-ingress-values.yaml
주의
저와 같이 RKE2로 k8s를 설치하셨다면 다음과 같은 오류 문구를 마주할 수 있습니다.
kubectl get all -n kube-system | grep ingress
sudo vi /etc/rancher/rke2/config.yaml
disable:
- rke2-ingress-nginx
sudo systemctl restart rke2-server
kubectl get all -n kube-system | grep ingress
ClusterIP 생성
mysql-primary-cluster-ip.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-primary
spec:
type: ClusterIP
ports:
- port: 3306
targetPort: 3306
protocol: TCP
name: mysql
selector:
statefulset.kubernetes.io/pod-name: mysql-primary-0
mysql-secondary-cluster-ip.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-secondary
spec:
type: ClusterIP
ports:
- port: 3306
targetPort: 3306
protocol: TCP
name: mysql
selector:
app.kubernetes.io/instance: mysql
app.kubernetes.io/component: secondary









댓글 없음:
댓글 쓰기