[네떡스터디🔥kans] 쿠버네티스 서비스 이해하기 - kube-proxy IPVS 모드

CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 KANS 3기 내용을 정리한 글입니다.

 

IPVS 모드

IPVS 는 리눅스 커널에서 동작하는 소프트웨어 로드밸런서이다. 백엔드(플랫폼)으로 Netfilter 를 사용하며, TCP/UDP 요청을 처리 할 수 있다. PVS는 L4 계층에서 동작하며, 다양한 로드 밸런싱 알고리즘을 통해 서비스 요청을 여러 백엔드 서버로 분산시켜 트래픽을 효율적으로 관리합니다. 이를 통해 대규모 트래픽 환경에서도 안정적인 서비스를 제공하며, 고성능 로드 밸런싱을 필요로 하는 Kubernetes 클러스터에서 주로 사용됩니다. IPVS 모드는 커널 레벨에서 직접 작동하기 때문에 빠르고 확장성 있는 네트워크 트래픽 처리가 가능합니다. iptables 의 rule 기반 처리의 성능 한계와 분산 알고리즘이 없어서, 최근에는 대체로 IPVS 를 사용한다.

 

 

IPVS 모드로 클러스터 생성하기 

클러스터 생성 파일 

더보기

클러스터 생성할때 사용하는 kind 파일입니다. 

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  "InPlacePodVerticalScaling": true
  "MultiCIDRServiceAllocator": true
nodes:
- role: control-plane
  labels:
    mynode: control-plane
    topology.kubernetes.io/zone: ap-northeast-2a
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
  - containerPort: 30001
    hostPort: 30001
  - containerPort: 30002
    hostPort: 30002
  - containerPort: 30003
    hostPort: 30003
  - containerPort: 30004
    hostPort: 30004
  kubeadmConfigPatches:
  - |
    kind: ClusterConfiguration
    apiServer:
      extraArgs:
        runtime-config: api/all=true
    controllerManager:
      extraArgs:
        bind-address: 0.0.0.0
    etcd:
      local:
        extraArgs:
          listen-metrics-urls: http://0.0.0.0:2381
    scheduler:
      extraArgs:
        bind-address: 0.0.0.0
  - |
    kind: KubeProxyConfiguration
    metricsBindAddress: 0.0.0.0
    ipvs:
      strictARP: true
- role: worker
  labels:
    mynode: worker1
    topology.kubernetes.io/zone: ap-northeast-2a
- role: worker
  labels:
    mynode: worker2
    topology.kubernetes.io/zone: ap-northeast-2b
- role: worker
  labels:
    mynode: worker3
    topology.kubernetes.io/zone: ap-northeast-2c
networking:
  podSubnet: 10.10.0.0/16
  serviceSubnet: 10.200.1.0/24
  kubeProxyMode: "ipvs"
kind create cluster --config ipvs.yaml --name myk8s --image kindest/node:v1.31.0

 

같은 대역의 컨테이너 테스트용 생성

docker run -d --rm --name mypc --network kind nicolaka/netshoot sleep infinity

 

IPVS 설정 확인하기

생성된 클러스터가 ipvs모드로 잘 구성되었는지 확인해보도록 하겠습니다.

kubectl describe cm -n kube-system kube-proxy

 

ipvs 모드인걸 확인

 

이후에 MetalLB를 설치해서 테스트 하려면 strictARP를 true로 설정해야합니다. IPVS 모드에서 strict ARP가 활성화되면, 노드의 인터페이스는 자신에게 할당된 IP 주소에 대해서만 ARP 응답을 보내게 됩니다. 이는 IPVS로 로드밸런싱할 때 ARP 패킷이 잘못된 인터페이스로 전달되는 문제를 방지합니다. 이 설정은 특히 클러스터 내에서 여러 노드가 동일한 IP를 갖는 VIP(Virtual IP)를 사용하는 경우 중요합니다. 

 

kubectl get cm -n kube-system kube-proxy -o yaml | yq '.data["config.conf"]' | yq '.'

strictARP true

 

  • arp_ignore : ARP request 를 받았을때 응답 여부 - 0(ARP 요청 도착시, any Interface 있으면 응답), 1(ARP 요청을 받은 Interface 가 해당 IP일때만 응답)
  • arp_announce : ARP request 를 보낼 때 'ARP Sender IP 주소'에 지정 값 - 0(sender IP로 시스템의 any IP 가능), 2(sender IP로 실제 전송하는 Interface 에 IP를 사용)

 

docker exec -it myk8s-worker cat /proc/sys/net/ipv4/conf/kube-ipvs0/arp_ignore

docker exec -it myk8s-worker cat /proc/sys/net/ipv4/conf/kube-ipvs0/arp_announce

 

IPVS 도구 설명

ipset

Kubernetes의 IPVS 모드에서 ipset은 클러스터 내에서 효율적인 네트워크 관리에 중요한 역할을 합니다. IPVS 모드에서는 서비스 로드 밸런싱을 할 때 다수의 클라이언트 IP를 처리하는데, ipset을 활용하면 많은 수의 IP 주소를 효과적으로 관리할 수 있습니다. 특히, 특정 IP 범위에 대한 접근 제어나 필터링이 필요할 때 ipset을 사용해 여러 IP를 하나의 규칙으로 처리함으로써 성능을 최적화하고 관리의 복잡성을 줄일 수 있습니다. 이를 통해 Kubernetes의 대규모 클러스터에서도 더 나은 확장성과 네트워크 성능을 제공할 수 있습니다.

ipvsadm

ipvsadm은 IP Virtual Server(IPVS)를 관리하는 명령줄 도구로, 네트워크 트래픽의 부하 분산을 설정하고 조정하는 역할을 합니다. IPVS는 커널 레벨에서 동작하는 로드 밸런싱 기법으로, 클러스터 환경에서 다수의 서버에 네트워크 요청을 효율적으로 분배할 수 있습니다. ipvsadm은 부하 분산에 사용할 실제 서버와 가상 서버, 그리고 분배 방식(라운드 로빈, 최소 연결, 해시 기반 등)을 설정하고 모니터링할 수 있는 기능을 제공합니다. 이를 통해 고가용성과 확장성을 갖춘 네트워크 서비스 구성을 쉽게 할 수 있습니다.

 

현재 활성화된 IPVS 연결 상태를 확인

ipvsadm -Ln -c

 

실제 확인 결과

 

첫 번째 연결: 클라이언트 IP 10.10.0.3의 포트 52766에서 로드 밸런서 IP 10.200.1.1의 포트 443으로 연결되었으며, 해당 요청은 백엔드 서버 IP 172.17.0.5의 포트 6443으로 전달되었습니다. 이 연결은 현재 ESTABLISHED 상태로, 남은 만료 시간은 14분 45초입니다.

 

IPVS의 패킷 전송량, 수신량, 드롭된 패킷 수 등의 통계 정보 확인

ipvsadm -Ln --stats

 

실제로 확인해본 결과입니다.

이 출력은 IPVS에서 관리하는 연결 상태와 트래픽 정보를 나타냅니다. Prot는 연결에 사용된 프로토콜(TCP 또는 UDP)을 표시하며, LocalAddress는 가상 서버(로드 밸런서)의 IP 주소와 포트를 나타냅니다. Conns는 현재 활성화된 연결 수, InPkts와 OutPkts는 각각 수신 및 전송된 패킷 수를 의미하며, InBytes와 OutBytes는 수신 및 전송된 데이터의 총 바이트 양을 나타냅니다. 마지막으로, RemoteAddress는 요청이 전달되는 백엔드 서버의 IP와 포트를 보여줍니다. 이 정보는 로드 밸런서와 백엔드 서버 간의 트래픽을 모니터링하는 데 유용합니다.

 

IPVS의 현재 전송 속도와 수신 속도 확인

ipvsadm -Ln --rate

 

이 출력은 IP Virtual Server(IPVS)에서 관리하는 연결과 네트워크 성능 정보를 보여줍니다. Prot는 사용 중인 프로토콜(TCP 또는 UDP)을 나타내며, LocalAddress는 가상 서버(로드 밸런서)의 IP 주소와 포트를 나타냅니다. CPS는 초당 생성된 연결 수를 의미하며, InPPS와 OutPPS는 각각 초당 수신된 패킷과 전송된 패킷 수를 나타냅니다. InBPS와 OutBPS는 초당 수신 및 전송된 데이터의 바이트 수를 나타내며, 이를 통해 실시간 네트워크 트래픽과 성능을 모니터링할 수 있습니다. 마지막으로, RemoteAddress는 백엔드 서버의 IP 주소와 포트를 나타내며, 로드 밸런서가 트래픽을 전달하는 대상 서버입니다.

 

conntrack

conntrack는 리눅스 커널의 네트워크 연결 추적 기능을 관리하는 도구로, 방화벽이나 네트워크 주소 변환(NAT) 설정에서 중요한 역할을 합니다. 네트워크 연결 상태를 추적하여 TCP, UDP 등 다양한 프로토콜의 연결 정보를 기록하고 관리하는 역할을 하며, 이를 통해 방화벽에서 특정 연결을 허용하거나 차단할 수 있습니다. conntrack은 네트워크 연결의 상태, 프로토콜, 소스 및 목적지 IP 등을 추적하여 세션 관리를 용이하게 하고, 문제가 발생할 경우 디버깅에도 유용한 정보를 제공합니다.

 
 

통신 흐름 분석하기