[본투비엔지니어] 나에게 베어본만 주어진다면?? (8)

2026. 1. 29. 17:03·project/본투비엔지니어

지난 시간, 앤서블(Ansible)의 힘을 빌려 5대의 서버를 하나의 쿠버네티스 클러스터로 묶는 데 성공했습니다. 외부 트래픽을 통신하기 위해서는 'MetalLB' 와 'Ingress Nginx'가 필요합니다.

 

MetalLB 란?

외부 접속 IP(LoadBalancer IP)를 할당받을 수 있게 해주는 필수 도구입니다.

MetalLB는 크게 두 가지 방식으로 작동하지만, 홈랩에서는 Layer 2 (ARP/NDP) 모드를 주로 사용합니다.  다른 하나는 BGP 모드입니다. 쓰려면, BGP 프로토콜을 지원하는 고가의 L3 스위치나 라우터가 필요합니다.

 

  • IP Pool 설정: 사용자님이 MetalLB에게 192.168.219.200 ~ 210 대역을 쓸 수 있다고 알려줍니다.
  • IP 할당 (Controller): 사용자가 서비스를 생성하면, MetalLB의 Controller가 IP 하나(예: .200)를 꺼내 해당 서비스에 할당합니다.
  • 주소 광고 (Speaker): 각 노드에 설치된 MetalLB Speaker가 공유기(네트워크)를 향해 소리칩니다.
    • "여기요! 192.168.219.200번 찾는 패킷 있으면 저(k8s-worker-1)한테 보내세요!"
  • 트래픽 수신: 공유기는 이 외침(ARP 응답)을 듣고, .200으로 가는 트래픽을 해당 노드로 보냅니다.

MetalLB는 두 가지 파드(Pod)로 구성됩니다.

  1. Controller (Deployment):
    • IP를 관리하는 관리자입니다.
    • 서비스가 생기면 "너는 200번 써", "너는 201번 써" 하고 IP를 배분합니다.
  2. Speaker (DaemonSet):
    • 모든 노드에 하나씩 설치되는 "확성기"입니다.
    • 실제로 네트워크에 ARP(IPv4) 패킷을 쏘면서 "이 IP 여기 있어요"라고 광고하는 역할을 합니다.

 

앤서블 플레이북

 

  • Helm 설치: 쿠버네티스용 패키지 매니저인 helm을 마스터 노드에 설치합니다.
  • MetalLB 설치: 가짜 로드밸런서 역할을 할 MetalLB를 설치합니다.
  • MetalLB 설정 (IP Pool): 192.168.219.200 ~ 210 대역을 사용하도록 설정합니다.
  • Ingress Nginx 설치: 웹 트래픽을 도메인별로 분배해 줄 인그레스 컨트롤러를 설치합니다.

 

addons.yaml  은 이렇게 작성 할 수 있습니다.

---
- name: Install Kubernetes Addons (MetalLB & Ingress-Nginx)
  hosts: masters
  become: yes
  environment:
    KUBECONFIG: /etc/kubernetes/admin.conf
  tasks:

    # 0. Helm 설치 (패키지 매니저)
    - name: Download Helm installer
      get_url:
        url: https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
        dest: /tmp/get_helm.sh
        mode: '0700'

    - name: Install Helm
      shell: /tmp/get_helm.sh
      args:
        creates: /usr/local/bin/helm

    # 1. MetalLB 설치 (LoadBalancer)
    - name: Add MetalLB Helm Repo
      shell: |
        helm repo add metallb https://metallb.github.io/metallb
        helm repo update

    - name: Install MetalLB via Helm
      shell: |
        helm upgrade --install metallb metallb/metallb \
          --namespace metallb-system \
          --create-namespace \
          --timeout 10m \
          --wait

    # 2. MetalLB 설정 (L2 모드 & IP Pool)
    - name: Create MetalLB IPAddressPool & L2Advertisement
      copy:
        dest: /root/metallb-config.yaml
        content: |
          apiVersion: metallb.io/v1beta1
          kind: IPAddressPool
          metadata:
            name: first-pool
            namespace: metallb-system
          spec:
            addresses:
            - 192.168.219.200-192.168.219.210
          ---
          apiVersion: metallb.io/v1beta1
          kind: L2Advertisement
          metadata:
            name: example
            namespace: metallb-system
      register: metallb_config

    - name: Apply MetalLB Configuration
      shell: kubectl apply -f /root/metallb-config.yaml
      when: metallb_config.changed

    # 3. Ingress Nginx 설치 (Traffic Controller)
    - name: Add Ingress-Nginx Helm Repo
      shell: |
        helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
        helm repo update

    - name: Install Ingress-Nginx via Helm
      shell: |
        helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
          --namespace ingress-nginx \
          --create-namespace \
          --set controller.service.type=LoadBalancer \
          --set controller.service.externalTrafficPolicy=Local \
          --timeout 10m

실행

ansible-playbook addons.yml

 

 

실행 중 위와 같은 오류가 생겼습니다.

 

metallb controller 가 CrashLoopBackOff 상태가 되었습니다. 다행히도 고쳤습니다... 정리해보자면

1. 현상 (Symptoms)

  • MetalLB Controller 파드가 Running 상태가 되어도 로그가 Starting...에서 멈춘 채 진행되지 않음 (Webhook 호출 실패).
  • 클러스터 내부에서 Service IP(10.96.0.1)로 curl 요청을 보내면 응답 없이 무한 대기(Hang/Timeout) 발생.
  • Ping(ICMP)은 정상적으로 통신되지만, HTTP/TCP 데이터 통신만 불가능함.
  • 방화벽(firewalld, nftables)을 모두 끄고, iptables를 초기화해도 증상이 동일함.

2. 원인 (Root Cause)

"미니 PC 랜카드(NIC)의 체크섬 오프로딩(Checksum Offloading) 버그"

  • 배경: 사용 중인 하드웨어(Beelink, GMKtec 등)에 탑재된 리얼텍(Realtek) 또는 인텔(Intel) 컨슈머용 NIC는 CPU 부하를 줄이기 위해 '패킷 검증(Checksum)'을 하드웨어가 대신 수행하는 기능(Offloading)이 켜져 있습니다.
  • 문제점: Rocky Linux(RHEL 계열 커널) 환경에서 Calico CNI가 사용하는 터널링 프로토콜(IPIP/VXLAN) 로 감싸진 패킷을 처리할 때, 이 랜카드가 체크섬 계산을 틀리게 하는 버그가 있습니다.
  • 결과:
    1. 송신 측(Node)은 "잘 보냈다"고 생각하고 패킷을 보냄.
    2. 수신 측(Master)은 패킷을 받았으나 **"데이터가 깨졌다(Bad Checksum)"**고 판단.
    3. 수신 측 커널이 아무런 에러 메시지 없이 해당 패킷을 조용히 폐기(Silent Drop).
    4. 애플리케이션(Curl, MetalLB)은 응답이 오지 않아 무한정 기다림.

3. 해결 과정 (Troubleshooting Steps)

  1. 좀비 프로세스 제거: 웹훅 설정(ValidatingWebhookConfiguration)이 남아 통신을 방해하는지 확인 및 삭제.
  2. 네트워크 초기화: iptables -F, conntrack -F 등을 통해 꼬인 네트워크 규칙과 캐시 초기화.
  3. 방화벽 해제: Rocky Linux의 숨겨진 방화벽 nftables 비활성화 및 iptables 정책 ACCEPT로 변경.
  4. MTU 조절: 터널링 오버헤드를 고려해 MTU를 1440 -> 1200으로 줄였으나 해결되지 않음 (단순 크기 문제가 아님을 확인).
  5. 최종 해결: 랜카드의 TX Checksum Offloading 기능을 비활성화(ethtool -K eth0 tx off) 하자마자 즉시 통신 재개.
# 1. ethtool 설치 (혹시 없을 수 있으므로)
ansible all -m package -a "name=ethtool state=present" -b

# 2. 체크섬 오프로딩 끄기 (TX Checksumming Off)
ansible all -m shell -a "ethtool -K eth0 tx off" -b

# 3. rp_filter 보안 해제 (0 또는 2로 설정)
ansible all -m shell -a "sysctl -w net.ipv4.conf.all.rp_filter=2 && sysctl -w net.ipv4.conf.default.rp_filter=2" -b

# 4. NetworkManager 설정으로 체크섬 기능 영구 비활성화 (Rocky Linux)
ansible all -m shell -a "nmcli connection modify eth0 ethtool.feature-tx off" -b

# 5. rp_filter 설정 영구 저장
ansible all -m shell -a "echo 'net.ipv4.conf.default.rp_filter = 2' > /etc/sysctl.d/99-k8s-override.conf && echo 'net.ipv4.conf.all.rp_filter = 2' >> /etc/sysctl.d/99-k8s-override.conf && sysctl --system" -b

 

 

성공!

통신 테스트

# Ingress Nginx 서비스 상태 확인
kubectl get svc -n ingress-nginx

 

 

http://192.168.219.200 으로 접속하면 404 가 나온다. 이게 이렇게 그리울 수가..

'project > 본투비엔지니어' 카테고리의 다른 글

[본투비엔지니어] 나에게 베어본만 주어진다면?? (10)  (0) 2026.02.01
[본투비엔지니어] 나에게 베어본만 주어진다면?? (9)  (0) 2026.01.31
[본투비엔지니어] 나에게 베어본만 주어진다면?? (7)  (0) 2026.01.29
[본투비엔지니어] 나에게 베어본만 주어진다면?? (6)  (0) 2026.01.29
[본투비엔지니어] 나에게 베어본만 주어진다면?? (5)  (0) 2026.01.28
'project/본투비엔지니어' 카테고리의 다른 글
  • [본투비엔지니어] 나에게 베어본만 주어진다면?? (10)
  • [본투비엔지니어] 나에게 베어본만 주어진다면?? (9)
  • [본투비엔지니어] 나에게 베어본만 주어진다면?? (7)
  • [본투비엔지니어] 나에게 베어본만 주어진다면?? (6)
heejunp
heejunp
희준개발
  • heejunp
    희준개발
    heejunp
  • 전체
    오늘
    어제
    • 분류 전체보기 (60)
      • 회고 (1)
      • project (13)
        • 본투비엔지니어 (12)
        • 페어쉐어 (1)
      • java (16)
      • spring (1)
      • go (1)
      • web (1)
      • cloud (1)
      • cloudflare (1)
      • database (1)
      • algorithm (16)
      • OS (1)
      • ai (1)
      • 기타 (2)
      • 오류 (1)
      • 생각정리 (2)
      • 자격증 (1)
        • RHCSA (1)
      • linux (0)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    heejunp
    [본투비엔지니어] 나에게 베어본만 주어진다면?? (8)
    상단으로

    티스토리툴바