- 외부에서의 로컬 K8S 클러스터 접근을 위해 MetalLB와 HAproxy를 사용
- K8S 클러스터 내부의 로드밸런서로는 nginx controller를 사용 중인 상태
- AWS라면, ALB Controller 하나만으로 MetalLB+HAproxy+nginxcontroller 기능을 커버 가능
- 사실상의 CSP의 K8S를 쓰는 이유??
https://metallb.universe.tf/installation/
- 클러스터 내부용 로드밸런서
- 오픈소스
- CSP의 LB를 사용하지 못하는 경우(내/외부 양쪽에서 사용가능한 LB)에, 내부용 L4 로드밸런서로 사용하기 위해 주로 MetalLB를 사용
사전 준비
- kube-proxy의 configmap에서 strictARP 활성화
1
2
3
4
5
6
7
| kubectl edit configmap -n kube-system kube-proxy
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
|
1
2
| helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb
|
1
2
3
4
5
6
7
8
9
10
| cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: default
spec:
addresses:
- 172.27.1.100-172.27.1.110
EOF
|
1
2
3
4
5
6
7
8
9
10
| cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: default
spec:
ipAddressPools:
- default-pool
EOF
|
HAproxy
1
2
| yum install -y haproxy
systemctl enable --now haproxy
|
- haproxy 설정
Jenkins를 예시로 구성
1
2
3
| # kubectl get ingress -n jenkins
NAME CLASS HOSTS ADDRESS PORTS AGE
jenkins-ingress nginx jenkins.local 172.27.1.100 80 26h
|
- 파드가 MetalLB로부터 부여받은 IP가 172.27.1.100일 경우 하기와 같이 설정
- 백엔드 헬스체크는 MetalLB에서 하고 있으니 HAproxy에선 설정하지 않음
http-request set-header Host- 클라이언트에서 오는 모든 HTTP 요청의 Host 헤더를 jenkins.local로 변경
http-request del-header X-Forwarded-Hosthttp-request del-header X-Forwarded-Proto
1
2
3
4
5
6
7
8
| tee /etc/haproxy/haproxy.cfg > /dev/null <<EOF
frontend jenkins_frontend
bind *:8080
default_backend metallb_backend
backend metallb_backend
server metallb 172.27.1.100:80
EOF
|
통신 구조
- jenkins 파드가 하기와 같이 구성되어 있다 가정할 때 통신 구조
- 현재 외부에서의 접근 시 80/443 포트를 사용하지 못하고 별도의 포트를 사용해야 하는 환경이기 때문에 8080포트를 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
| # kubectl get ingress -n jenkins
NAME CLASS HOSTS ADDRESS PORTS AGE
jenkins-ingress nginx jenkins.local 172.27.1.100 80 26h
# kubectl get all -n jenkins
NAME READY STATUS RESTARTS AGE
pod/jenkins-0 2/2 Running 0 9d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins ClusterIP 10.233.5.87 <none> 8080/TCP 9d
service/jenkins-agent ClusterIP 10.233.28.70 <none> 50000/TCP 9d
NAME READY AGE
statefulset.apps/jenkins 1/1 9d
|
- 브라우저에서 <도메인>:8080으로 접속
- DNS 해석되어 공인IP:8080으로 라우팅
- HAproxy frontend 설정으로 8080포트로 들어오는 요청을 HAproxy backend로 라우팅
- HAproxy backend는 172.27.1.100:80
- 172.27.1.100 IP는 MetalLB의 IP 풀에서부터 할당받은 Nginx Controller의 IP
- Nginx Ingress Controller는 LoadBalancer 타입 Service
- Nginx Ingress Controller는 HAproxy backend로부터 받은 트래픽의 Host 헤더가 Jenkins Ingress에 정의된 Host인 jenkins.local인지 확인
- Jenkins Ingress에 정의된 규칙에 따라 Jenkins Service로 라우팅
- Jenkins Service에서 Jenkins Pod로 라우팅