[K3s-04] K3s 로드밸런서 구성 (Klipper와 MetalLB)
목차
온프레미스 쿠버네티스는 자체 운영 로드밸런서를 생성할 수 없으며 (ClusterIP와 NodePort는 사용 가능), LoadBalancer
유형은 원래 클러스터 외부에서 운영될 수 있도록 설계되었습니다. 따라서 쿠버네티스 클러스터에서 LoadBalancer 유형을 사용하려면 추가 설정이 필요합니다.
K3s에는 기본적으로 Traefik이 Ingress 컨트롤러로 설치되어 있습니다. 이는 80번과 443번 포트에서 LoadBalancer를 배포합니다. 이 포트들은 다른 HostPort 또는 NodePort와 함께 노출되어서는 안 됩니다.
ServiceLB가 아닌 다른 LoadBalancer(예: MetalLB)를 사용하려면, 클러스터의 모든 서버를
--disable=servicelb
flag로 구성해야합니다.
k3s Networking docs에서 발췌
Traefik의 초기 설정 파일은
/var/lib/rancher/k3s/server/manifests/traefik.yaml
에 위치합니다. 초기 설정이므로 수동으로 편집해서는 안 됩니다! 대신,/var/lib/rancher/k3s/server/manifests
에HelmChartConfig
매니페스트를 생성하여 Traefik을 사용자 정의해야 합니다. 자세한 내용 및 예제는 HelmChartConfig로 패키지 구성 요소 사용자 정의를 참조하세요. 가능한 구성 값에 대한 자세한 정보는 공식 Traefik Helm 구성 매개변수를 참조하세요.
1) Klipper, built-in k3s Service LB #
먼저 k3s 에이전트 노드에 외부 IP를 설정하는 것이 좋습니다 (https://docs.k3s.io/cli/agent). 아래 값은 단순히 예시를 위해 제가 사용하는 노드 자체의 IP 주소입니다.
- control plane: 13.209.245.101
- agent node: 43.202.94.188, 43.203.19.201
# k3s-node-b, (43.202.94.188)
sudo k3s agent --node-external-ip 43.202.94.188 --server https://13.209.245.101:6443 --token XXX
# k3s-node-c (43.203.19.201)
sudo k3s agent --node-external-ip 43.203.19.201 --server https://13.209.245.101:6443 --token XXX
# 외부 IP 적용에는 시간이 조금 걸립니다
kubectl get node -A -o wide
ServiceLB Pod가 외부 IP가 구성된 노드에서 실행되면, 노드의 외부 IP는 서비스의 status.loadBalancer.ingress
에 전파합니다. 그렇지 않은 경우에는, 노드의 내부 IP가 사용됩니다.
ServiceLB를 위해 특정 노드를 선택하려면, 하나 이상의 노드에 svccontroller.k3s.cattle.io/enablelb=true
라벨을 추가합니다. 기본적으로 노드에는 라벨이 지정되지 않습니다. 모든 노드가 라벨이 없는 한, 포트가 사용 가능한 모든 노드가 ServiceLB에 의해 사용됩니다. (+ 또한, ServiceLB 노드 풀 생성으로 그룹으로 라벨을 지정할 수 있습니다)
문제: 단일 노드가 있거나 실행 중인 노드를 로드밸런서로 사용하려는 경우 문제가 있습니다. 로드밸런서는 포트 80과 443을 사용하는 기본적으로 traefik이 설치된 노드에서 호스팅됩니다. 그렇다면 k3s 노드에서 로드밸런서를 어떻게 호스팅할 수 있을까요?
답변: k3s 노드에서 traefik을 비활성화하는 것은 완전한 해결책이 아닙니다. --disable traefik
매개변수를 사용하여 traefik을 비활성화한다면, 웹 요청조차 처리되지 않습니다.
# https://github.com/k3s-io/k3s/issues/2403#issuecomment-956220875
mkdir -p /var/lib/rancher/k3s/server/manifests/
# Create traefik-config.yaml
cat <<EOF > /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
ports:
web:
exposedPort: 8088
websecure:
port: 8443
expose: true
exposedPort: 8443
EOF
# Install k3s
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--https-listen-port 7443" sh -
Traefik의 포트를 변경함으로써 우리는 80번과 443번 포트를 로드밸런서로 사용할 수 있습니다. 그러나 k3s 기본 설정을 변경하려면 k3s를 설치하기 전에 수행해야 합니다.
2) MetalLB configuration (WIP) #
- 클라우드에서 제공하는 관리형 쿠버네티스 클러스터에서는 MetalLB를 사용하지 마세요. → https://metallb.universe.tf/installation/clouds/
- Flannel, Cilium 등이 호환됩니다. → https://metallb.universe.tf/installation/network-addons/
다른 LB를 실행하려면 ServiceLB를 비활성화하고, 클러스터의 모든 서버를
--disable=servicelb
플래그로 구성하세요.
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
metallb-system
namespace를 생성합니다
- metallb-system/controller: IP 주소 할당을 처리하는 컨트롤러
- metallb-system/speaker: 프로토콜을 처리하는 데몬셋
- serviceaccounts 및 RBAC 권한
MetalLB의 두 가지 모드 https://velog.io/@youwins/MetalLB
- L2 모드: k3s 노드가 로드밸런서로 작동하도록 ARP 요청을 수신 및 브로드캐스트
- BGP 모드: 클러스터 외부에 외부 로드밸런서를 두고 BGP advertisement를 통해 연결
+) Q. MetalLB에서 FRR 모드는 무엇인가요?
3) Traefik Ingress (Recommended) #
K3s 서비스를 외부에 노출하는 가장 간단한 방법은 Traefik Ingress를 사용하는 것입니다. Traefik 및 그의 Ingress는 기본적으로 k3s에 구성되어 있습니다. 단순히 Ingress 리소스를 생성하고 노출하고자 하는 서비스의 이름(이 경우 nginx-deployment)을 작성하면 외부에 노출됩니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
spec:
ingressClassName: traefik
rules:
- host: k3s.jaehong21.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-deployment
port:
number: 80
Ingress에 TLS 인증서를 첨부하는 경우, 다음 글을 참조하세요.