사전 지식
kube-proxy에서 사용하는 IPVS 모드는 리눅스 커널에서 제공하는 핵심 네트워크 기술을 가지고 동작합니다.
1.IPVS(IP Virtual Serve)
- 리눅스 커널에서 제공하는 L4 로드벨런서
- IPVS는 Netfilter 안에서 동작(Netfilter를 백엔드로 사용)
- TCP/UDP 요청을 처리
2.Ipset
- 리눅스 커널에서 네트워크 객체 집합을 그룹화하고 관리하는 도구
- IP주소, 네트워크, 포트 등
- iptable로 관리하는 룰셋이 많아질 때, 성능이 저하되는 것을 방지하고 효율적으로 네트워크를 관리할 수 있는 도구.
ipvs proxy mode에서는 아래와 같이 네트워크의 목적에 따라, 다양한 쿠버네티스 집합들로 구성됩니다.
IPVS Proxy 모드란?
- IPVS Proxy 모드는
kube-proxy
에서 IPVS가 서비스의 Proxy 역할을 수행하는 모드입니다. - 이전에 포스팅하였던 iptables 모드와 비교하였을 때 성능이 우수합니다.(iptables를 사용하기는 합니다.)
- iptables 모드와 유사한 Netfilter 후크 기능을 기반으로 하지만, 해시 테이블을 기본 데이터 구조로 사용하고 커널 스페이스에서 동작하여 성능이 우수.
- 기존 iptables의 규칙 개수를 현저히 줄여, 더 높은 성능을 제공한다.
- 다양한 부하분산 알고리즘을 제공합니다.
- 라운드 로빈(rr): 우선순위를 두지 않고, 대상 목저지 파드로 돌아가면서 요청을 전달
- 최소 연결(lc): 목적지 파드의 연결 개수가 가장 적은 곳을 수선 전달
- 목적지 해싱(dh): 목적지 IP 주소로 해시값을 계산하여 목적지 파드를 결정하여 전달
- 출발지 해싱(sh): 출발지 IP 주소로 해시값을 계산하여 목적지 파드를 결정하여 전달
- 최단 지연(sed): 응답 속도가 가장 빠른 목적지 파드를 선택
- 이외에도 다양한 부하분산 알고리즘을 제공합니다.
실습환경
- kind(쿠버네티스 클러스터)
- control-plane-node(172.17.0.5)
- worker1(172.17.0.2)
- worker2(172.17.0.2)
- worker3(172.17.0.3)
- 파드 CIDR: 10.10.10.0/16
- 서비스 CIDR: 10.200.1.0/24
kind 설정 추가 : ipvs 모드 사용을 위해 아래 설정 추가
networking.kubeProxyMode: ipvs
: kube-proxy ipvs 모드 사용strictARP: true
: ARP 패킷을 보다 엄격하게 처리, IPVS로 로드벨런싱 할 때 ARP 패킷이 잘못된 인터페이스로 전달하는 것을 방지
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"
실습 워크로드 구성 : 통신 실습을 위해 아래 리소스를 생성합니다.
- pod
- service
- client
# 파드 생성
cat <<EOT> 3pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: webpod1
labels:
app: webpod
spec:
nodeName: myk8s-worker
containers:
- name: container
image: traefik/whoami
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: webpod2
labels:
app: webpod
spec:
nodeName: myk8s-worker2
containers:
- name: container
image: traefik/whoami
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: webpod3
labels:
app: webpod
spec:
nodeName: myk8s-worker3
containers:
- name: container
image: traefik/whoami
terminationGracePeriodSeconds: 0
EOT
# 서비스 생성
cat <<EOT> svc-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-clusterip
spec:
ports:
- name: svc-webport
port: 9000 # 서비스 IP 에 접속 시 사용하는 포트 port 를 의미
targetPort: 80 # 타킷 targetPort 는 서비스를 통해서 목적지 파드로 접속 시 해당 파드로 접속하는 포트를 의미
selector:
app: webpod # 셀렉터 아래 app:webpod 레이블이 설정되어 있는 파드들은 해당 서비스에 연동됨
type: ClusterIP # 서비스 타입
EOT
# 실습용 클라이언트 : 마스터 노드에 배치
cat <<EOT> netpod.yaml
apiVersion: v1
kind: Pod
metadata:
name: net-pod
spec:
nodeName: myk8s-control-plane
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOT
실습 워크로드 확인
kube-proxy 설정확인(configmap)
kube-proxy는 kube-proxy configmap을 통해 설정을 관리합니다.
이러한 kube-ipvs0 네트워크 설정들은 커널 파라미터들을 통해 제어된다고 합니다.
IPVS 모드 네트워크 정보 확인
IPVS 모드에서는 kube-ipvs0
이라는 dummy 네트워크 인터페이스가 생성됩니다. 해당 인터페이스에 서비스의 VIP로 연결된 것을 확인할 수 있습니다.
모든 노드에서도 동일하게 kube-ipvs0
네트워크 인터페이스를 확인할 수 있습니다.
ipvsadm
ipvsadm 툴을 이용하여 IPVS를 관리하고 부하분산 정보를 확인할 수 있습니다.
Service에서 부하분산되는 Endpoint 정보가 IPVS 목록에도 동일한 것을 확인할 수 있습니다.
ipvs 테이블 삭제 후 재생성ipvsadm -C
옵션을 주어 ipvs 테이블을 모두 삭제하여도 kube-proxy
가 이를 감지하여, 다시 테이블이 재생성되는 것을 확인할 수 있습니다.
ipset
ipset 명령어로 ipset 정보를 확인할 수 있습니다.
목적에 따라, Iptables의 규칙이 비슷한 네트워크 객체들을 그룹화하여 --match-set
옵션을 통해 효율적으로 룰을 사용할 수 있습니다.
iptables 모드에서는 서비스와 부하분산되는 엔드포인트(파드)가 늘어날 때마다, iptables의 규칙 수가 기하급수적으로 증가하여 관리하기도 힘들어지고, 성능에 문제도 발생하게 됩니다.
IPVS 모드를 사용하면 커널에서 동작하는 Ipset과 ipvs를 활용하여 iptables 규칙수를 줄이고, 성능을 최적화할 수 있습니다.
IPVS 정보 확인 및 서비스 접속 확인
ipvs 테이블을 모니터링하여, 서비스 접속 시, ipvs의 정보를 확인합니다.
부하분산 확인
iptables 모드에서 랜덤 확률 부하 분산이 아닌, 스케줄링 알고리즘을 사용하여 더 정확하게 부하 분산되는 것을 확인할 수 있다.
결론
IPVS 모드는 커널 레벨에서 로드밸런싱을 수행하여 높은 성능과 확장성을 제공하므로, 대규모 클러스터 환경에서 더 효과적으로 동작합니다. 또한, 다양한 로드밸런싱 알고리즘을 지원하여 트래픽을 효율적으로 제어할 수 있습니다. 반면, iptables 모드는 서비스 규모가 커질수록 성능 저하가 발생하기 때문에, IPVS 모드를 사용하는 것을 권장합니다.
'Kubernetes > Network' 카테고리의 다른 글
Istio & Service Mesh- KANS 7주차 (4) | 2024.10.20 |
---|---|
Ingress와 Kubernetes Gateway Api - KANS 6주차 (0) | 2024.10.13 |
MetalLB를 활용한 LoadBalancer 서비스의 동작 원리 이해 - KANS 5주차 1 (2) | 2024.10.06 |
Calico CNI 기본 네트워크 이해 & 네트워크 모드 - KANS 3주차 (4) | 2024.09.22 |
Pause 컨테이너 & Flannel CNI - KANS 2주차 (2) | 2024.09.08 |