메인 콘텐츠로 이동하기
  1. Posts/

[K3s-04] K3s 로드밸런서 구성 (Klipper와 MetalLB)

·535 자

온프레미스 쿠버네티스는 자체 운영 로드밸런서를 생성할 수 없으며 (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/manifestsHelmChartConfig 매니페스트를 생성하여 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) #

다른 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 모드는 무엇인가요?

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 인증서를 첨부하는 경우, 다음 을 참조하세요.

Reference #