CloudNet 가시다님이 진행하는 Kubernetes Advanced Network Study 4주차 정리입니다.

 

요약

√ 쿠버네티스에서 동작하는 애플리케이션을 내/외부에서 유연하게 접속하기 위한 서비스라는 오브젝트가 있다!

√ 'iptables, ipvs, nftables' proxy mode 모두 Netfilter framework을 사용

 

더보기

 

0. 요약

▶ 클러스터 내부를 외부에 노출 - 발전 단계

1. 파드 생성 : K8S 클러스터 내부에서만 접속

2. 서비스(Cluster Type) 연결 : k8s 클러스터 내부에서만 접속 (Service ClusterIP)

  • 동일한 애플리케이션의 다수의 파드의 접속을 용이하게 하기 위한 서비스에 접속
  • 고정 접속(호출) 방법을 제공 : 흔히 말하는 '고정 VirtualIP'와 'Domain주소' 생성

3. 서비스(NodePort Type) 연결 : 외부 클라이언트가 서비스를 통해서 클러스터 내부의 파드로 접속

  • 서비스(NodePort Type)의 일부 단점을 보완한 서비스(LoadBalancer Type)도 있다!

▶ 서비스 종류

1) Cluster IP 타입
- Cluster IP가 L4 역할을 수행
- Control Plane 노드에 TestPod 생성 후 Service ClusterIP에 묶인 Pod 3개 존재
- Control Plane에 있는 분산률에 따라서 Node 1, Node 2, Node 3에 자동으로 분배

2) NodePort 타입

- Listen Port를 알고있다는 가정하에 Node 1에 들어올 경우 분산되어 나머지 Node에도 분산

3) LoadBalancer 타입

-  L4를 통해서 Node Port를 타고 들어갈수도 있고 iptables로 바로 접속도 가능

 

▶ 약자

  • S.IP : Source IP, 출발지(소스) IP
  • D.IP : Destination IP, 도착지(목적지) IP
  • S.Port : Source Port, 출발지(소스) 포트
  • D.Port : Destination Port, 도착지(목적지) 포트
  • NAT : Network Address Translation, 네트워크 주소 변환
  • SNAT : Source IP를 NAT 처리, 일반적으로 출발지 IP를 변환
  • DNAT : Destination IP를 NAT 처리, 일반적으로 목적지 IP와 목적지 포트를 변환

 

▶ k8s 서비스 소개 : kube-proxy 모드 - iptables, ipvs, nftables, eBPF

kube-proxy (optional, unless you have deployed your own alternative component in place of kube-proxy)

  • kube-proxy is a network proxy that runs on each node in your cluster, implementing part of the Kubernetes Service concept.
  • kube-proxy maintains network rules on nodes. These network rules allow network communication to your Pods from network sessions inside or outside of your cluster.
  • kube-proxy uses the operating systen packet filtering layer if there is one and it's available. Otherwise, kube-proxy forwards the traffic itself.
  • If you use a network plugin that implements packet forwarding for Services by itself, and providing equivalent behavior to kube-proxy, then you do not need to run kube-proxy on the nodes in your cluster.

 

  • runs on each node kubectl get ds -n kube-system kube-proxy
  • proxied UDP, TCP and SCTP
  • does not understand HTTP
  • provides load balancing
  • is only used to reach services

 

1. User space 프록시 모드 -> 현재는 미사용

  • Redirect, DNAT를 통해서 Service로 전송한 모든 요청 Packet은 kube-proxy로 전달 -> 포트 하나당 하나의 서비스가 맵핑
  • 즉 유저스페이스(kube-proxy)에서 커널 스페이스로 변환이 필요하여 그 만큼 비용이 든다
  • kube-proxy 프로세스가 문제 시 SPOF 발생 (대응이 어렵다)

 

2. Iptables 프록시 모드 (iptables APIs -> netfilter subsystem)

  • In this mode, kube-proxy configures packet forwarding rules using the iptables API of the kernel netfilter subsystem.
    > For each endpoint, it installs iptables rules which, by default, select a backend Pod at random
  • 1번 방식인 kube-proxy가 직접 proxy의 역할을 수행하지 않고 그 역할을 전부 netfilter에게 맡긴다
  • 이를 통해 service IP를 발견하고 그것을 실제 Pod로 전달하는 것은 모두 netfilter가 담당하게 되었고
  • kube-proxy는 단순히 netfilter의 규칙을 알맞게 수정하는 것을 담당할 뿐이다. 즉 kube-proxy는 rule만 관리하고 실제 데이터 트래픽 처리를 직접 하지 않는다
  • kube-proxy가 데몬셋으로 동작하여, SPOF 발생 시 자동으로 다시 띄워 동작한다! 혹시 문제가 생겨도 룰은 이미 설정되어 있으니 데이터 통신은 된다. (룰 추가, 삭제는 안되지만 'User space'에 비해서 좀 더 안정적이고 성능 효율도 좋다)

 

SPOF란?
Single Point of Failure의 약자로, 단일 장애점이라고 한다.

시스템 구성 요소 중 하나가 고장나면 전체 시스템이 마비되는, 즉 시스템의 안정성을 위협하는 요소를 의미한다. 마치 건물을 지탱하는 기둥 하나가 무너지면 전체 건물이 무너지는 것과 같은 이치입니다.

SPOF를 제거해야 하는 이유?
- 시스템 안정성 향상 : SPOF를 제거하면 시스템의 안정성을 높이고, 장애 발생 시에도 시스템의 일부 기능을 유지할 수 있습니다.
- 가용성 증대 : 시스템 가용성을 높여 서비스 중단 시간을 최소화하고, 사용자에게 안정적인 서비스를 제공할 수 있습니다.
- 리스크 관리 : 단일 장애점에 대한 의존도를 낮춰 시스템 전체에 대한 위험을 분산시키고, 리스크를 관리 할 수 있습니다.

SPOF를 제거하는 방법??
- 중복 구성 : 동일한 기능을 하는 여러 개의 구성 요소를 마련하여 한쪽에 문제가 발생하더라도 다른 구성 요소가 역할을 대신하도록 합니다.
- 분산 시스템 : 시스템을 여러 개의 작은 단위로 분산시켜 각 단위가 독립적으로 작동하도록 합니다.
- 장애 복구 : 장애 발생 시 자동으로 시스템을 복구하거나 다른 시스템으로 전환하는 기능을 구현하빈다.

 

3. IPVS 프록시 모드 (kernel IPVS, iptables APIs -> netfilter subsystem) [커널에서 동작]

  • In ipvs mode, kube-proxy uses the kernel IPVS and iptables APIs to create rules to redirect traffic from Service IPs to endpoint IPs.
    > The IPVS proxy mode is based on netfilter hook function that is similar to iptables mode, but uses a hash table as the underlying data structure and works in the kernel space. That means kube-proxy in IPVS mode redirects traffic with lower latency than kube-proxy in iptables mode, with much better performance when synchronizing proxy rules. Compared to the iptables proxy mode, IPVS mode also supports a higher throughput of network traffic.
  • IPVS Mode는 Linux Kernel에서 제공하는 L4 Load Balancer인 IPVS가 Service Proxy 역할을 수행하는 Mode이다.
  • Packet Load Balancing 수행 시 IPVS가 iptables보다 높은 성능을 보이기 때문에 IPVS Mode는 iptables Mode 보다 높은 성능을 보여준다
  • IPVS 프록시 모드는 iptables 모드와 유사한 넷필터 후크 기능을 기반으로 하지만, 해시 테이블을 기본 데이터 구조로 사용하고 커널 스페이스에서 동작한다.
  • 이는 IPVS 모드의 kube-proxy는 iptables 모드의 kube-proxy 보다 지연 시간이 짧은 트래픽을 리다이렉션하고, 프록시 규칙을 동기화할 때 성능이 훨씬 향상됨을 의미한다.
  • 다른 프록시 모드와 비교했을 떄, IPVS 모드는 높은 네트워크 트래픽 처리량도 지원한다.

 

4. nftables 프록시 모드 (nftables API -> netfilter subsystem)

This proxy mode is only available on Linux nodes, and requires kernel 5.13 or later.

  • a mode where the kube-proxy configures packet forwarding rules using nftables.
  • In this mode, kube-proxy configures packet forwarding rules using the nftables API of the kernel netfilter subsystem. For each endpoint, it installs nftables rules which, by default, select a backend Pod at random.
  • The nftables API is the successor to the iptables API and is designed to provide better performance and scalability than iptables. The nftables proxy mode is able to process is also able to more efficiently process packets in the kernel (though this only becomes noticeable in clusters with tens of thousands of services)
  • As of Kubernetes 1.31, the nftables mode is still relatively new, and may not be compatible with all network plugins; consult the documentation for your network plugin.

5. eBPF 모드 + XDP

 

★★★★★ [Sam.0] Netfilter and iptables - https://netpple.github.io/2022/netfilter-iptables/, A Deep Dive into iptables and Netfilter Architecure - https://netpple.github.io/2021/deep-dive-iptables-netfilter-architecture/

 

A Deep Dive into Iptables and Netfilter Architecture

netfilter와 iptables를 이해하기에 좋은 자료입니다.

netpple.github.io

정독 - https://docs.google.com/presentation/d/1tXS3N0196WmdaWYa0ZLVpIMt7uDQdBO6PGdq25z0gvs/edit#slide=id.p

 

Netfilter & iptables

Netfilter & iptables sam.0

docs.google.com

 

[ Kubernetes kube-proxy Mode ]

추가 정리 예정

 

1. ClusterIP

: 서비스에 묶인 pod는 selector에 의해 레이블 설정됨

1.1 통신 흐름

요약 : 클라이언트(TestPod)가 'CLUSTER-IP' 접속 시 해당 노드의 iptables 룰(랜덤 분산)에 의해서 DNAT 처리가 되어 목적지(backend) 파드와 통신

  • 클러스터 내부에서만 'CLUSTER-IP'로 접근 가능 -> 서비스에 DNS(도메인) 접속도 가능
  • 서비스(Cluster IP 타입) 생성하게 되면, apiserver -> (kubelet) -> kube-proxy -> iptables 에 rule(룰)이 생성됨
  • 모든 노드(마스터 포함)에 iptables rule이 설정되므로, 파드에서 접속 시 해당 노드에 존재하는 iptables rule에 의해서 분산 접속이 됨

1.2 실습 구성

https://qwakcheol.tistory.com/18

 

[Kubernetes Advanced Networking Study] K8S Flannel CNI & PAUSE

CloudNet@ 가시다님이 진행하는 Kubernetes Advanced Networking Study 2주차 정리입니다.  1. 쿠버네티스 소개▶ 기초 이론master (control-plane, leader) : 마스터, 컨트롤 플레인, 리더node(worker node) : 노드, 워커노

qwakcheol.tistory.com

: 2주차 스터디에서 진행했던 kind 설치 (by vagrant + virtualbox)

툴 설치 확인
도커 정보 확인
k8s v1.31.0 버전 확인
노드 labels 확인
kind network 중 컨테이너(노드) IP(대역) 확인
파드 CIDR과 Service 대역 확인 : CNI는 kindnet 사용
feature-gates 확인
노드마다 할당된 dedicated subnet (podCIDR) 확인
kube-proxy configmap 확인
mypc

* docker run 시도 시 아래 에러 발생
: docker: Error response from daemon: invalid config for network kind: invalid endpoint settings:
user specified IP address is supported only when connecting to networks with user configured subnets.

해결 방법 : docker restart.... (해당 에러메시지로 구글링 시 네트워크를 생성할 때 CIDR 블록도 지정해야 한다.. 그냥 옵션을 삭제하여 자동으로 할당된 주소를사용하라 하였으나..
docker restart 후 다시 docker run 시도 시 성공..♨)

 

mypc 컨테이너 확인
설치 확인
pod 생성 확인
파드와 서비스 사용 네트워크 대역 정보 확인
확인
spec.ports.port와 spec.ports.targetport가 어떤 의미인지 이해 필요
서비스 생성 시 엔드포인트를 자동으로 생성, 수동으로 설정 생성도 가능

 

1.3 서비스(Cluster IP) 접속 확인
: 9000번이 서비스에 붙는 포트이고 Destination Port를 Target Port로 변환
: 클러스터 IP 접속할 때는 9000번 포트 사용
: 9000번 포트로 연결이 요청되면 Pod의 80번으로 연결된다!!

▶ 클라이언트(TestPod) Shell에서 접속 테스트 & 서비스(ClusterIP) 부하분산 접속 확인

webpod 파드의 IP 확인 및 변수에 지정

 

* net-pod와 webpod1의 IP가 동일하여 webpod delete 후 다시 apply 하여 진행 

 

net-pod 파드에서 webpod 파드의 IP로 직접 curl 로 반복 접속
서비스 IP 변수 지정 : svc-clusterip의 clusterIP 주소
iptalbes rule에 의해서 라우팅 처리됨
TCP 80, 9000 포트별 접속 확인

 

Link layer에서 동작하는 ebtables

 

1.4 IPTABLES 정책 확인

▶ iptables NAT 테이블

PREROUTING > KUBE-SERVICES > KUBE-SVC > KUBE-SEP

: iptables 체인은 규칙의 연결 그룹이며 규칙에 매칭이 되면 해당 패킷을 어떻게 처리할지 결정하게 된다.

일반적으로 허용 혹은 차단하게 되며, 혹은 다른 체인으로 넘길 수 있다.

 

IPTABLES 규칙을 확인해보면, ClusterIP로 접속 시 랜덤 부하분산 되고 DNAT 처리되어 파드로 접속.

ClusterIP의 정체는 바로 노드에 설정되어 있는 IPTABLES 규칙에 의해 처리되고, IPTABLES 규칙은 서비스 리소스를 생성하게 되면, kube-proxy에 의해서 규칙이 추가된다.

 

KUBE-SERVICE chain 안에 9000번 체인 확인

 

1.5 파드 1개 장애 발생 시 동작 확인

▶ 동작 확인을 위한 모니터링

3pod.yaml apply 후 확인
레이블 삭제 후 확인 >> 레이블과 셀럭터는 쿠버네티스 환경에서 매우 많이 활용
결과 확인 후 다시 레이블 생성

☞ 쿠버네티스의 Endpoint Controller 는 지속적으로 엔드포인트를 Watch 하고 List에 추가, 삭제를 한다