이번 포스팅에서는 Kube Proxy에 대해 알아보려고 한다.
kube-proxy
그림 1. k8s Architecture
그림 1에서 다시금 k8s의 아키텍처를 들여다보면 각각의 Node에 Proxy가 존재하는 것을 확인 할 수 있다. 즉, Node는 kube-proxy(Proxy)를 실행하고 관리한다.
여기서 kube-proxy의 역할은 k8s Service에 클라이언트가 연결할 수 있도록 한다. (클라이언트가 Service에 묶인 Pod에 연결 할 수 있도록)
k8s에서 제공하는 kube-proxy 모드는 3가지가 존재하는데 베타 버전(현재 v1.9이 베타)을 제외한 나머지 모드는 아래와 같다.
- Userspace mode
그림 2. Userspace Mode
그림 2에서 Userspace Mode 방식을 확인 할 수 있다. k8s에서 각 Service는 Node에서 랜덤하게 Port를 선택하여 Open한다. (그림 2는 하나의 서비스에 대한 Port Open) 그리고 Opend된 Port(Proxy Port를 의미) 클라이언트의 요청을 해당 Pod로 redirect 하기 위해 사용된다.
한 번 그림 2의 전체 Flow를 훑어보면,
1) k8s API에 의해 Service가 생성되면 Node에 Proxy Port가 생성된다.
2) 클라이언트 요청이 들어온다.
3) iptables는 클라이언트가 요청한 ClusterIP와 Port를 확인하여 Proxy Port로 트래픽을 라우팅한다.
4) Service의 SessionAffinity (내부 속성)에 따라 관련 Pod 중 하나를 선택하여 트래픽을 전달한다.
이와 같은 순서로 실행되며 특히 kube-proxy에 의해 전달받은 Pod는 Round-Robin에 의해 한 쪽에 몰리지 않고 균형있게 실행 할 수 있도록 해준다.
- Iptables mode
그림 3. Iptables Mode
Iptables Mode는 Userspace Mode와는 다르게 Iptables에 의해 Pod로 트래픽이 전달된다. (그림 3 참조)
여기서 kube-proxy는 k8s의 apiserver에 의해 Service에 특정 이벤트 (추가, 삭제, 변경 등)이 생겼을 경우 관련된 IP와 Port를 Iptables에 업데이트한다.
때문에 Userspace Mode와 같이 Iptables -> Proxy와 같은 과정을 거치지 않는다. 그래서 장점으로 Iptables가 kernelspace에서 작업을 하기 때문에 성능면에서 Userspace 보다 낫다. (그래서 현재 디폴트 값이 Iptables Mode 인지도..)
그런데 Iptables Mode는 Pod가 응답하지 않을 경우 재시도를 하지 않는다. 응답하지 않는 Pod에 재시도를 하지 않는 것은 좋지만 Userspace Mode의 Round Robin과 다르게 매번 랜덤하게 Pod를 선택하기 떄문에 운이 나쁘면 응답이 없는 Pod에만 요청을 할 수 있다. (대응책으로 Readliness Probe를 설정해서 관리해주어야 한다.)
그림 4. Iptables Mode with Space
그림 4를 바탕으로 Iptables Mode의 예시와 함께 내부를 조금 더 알아보자.
위의 그림은 클라이언트 Pod와 Service의 Backend Pod (k8s Service로 묶인 Pods)인 Service Pod 1, 2, 3으로 구성되어 있다. 이를 바탕으로 클라이언트 Pod에서 Service에 접근 하면 다음과 같은 과정을 거친다.
1) k8s API에 의해 Service가 생성되면 Node에 kube-proxy에 의해 Iptables가 갱신된다.
2) 클라이언트 Pod의 Packet의 Target이 Service의 IP와 Port로 설정된다.
(여기서 Sevice의 IP와 Port는 각각 123.123.123.123 및 80으로 가정한다.
3) Kernel에서 요청 Packet이 Iptables의 Rules 중에 맞는 것이 있는지 확인한다.
4) Iptables에서 맞는 것이 있다면 Backend Pod 중에 아무거나(Random) 선택한다.
5) 지정된 Pod로 Packet를 전달하기전 Packet의 Target IP와 Port를 지정된 Pod의 것으로 수정한다.
IP : 123.123.123.123 -> 10.0.0.1 (지정된 Pod의 IP)
Port : 80 -> 8080 (지정된 Pod의 Port)
6) Packet을 전달된다.
위의 순서를 그림으로 확인해 보면 아래의 그림 5과 같다.
(그림 5와 약간 다르긴 하지만 이는 Flow를 구성하기 방식의 차이다.)
그림 5. Iptables Mode Flow
Reference
- https://callistaenterprise.se/blogg/teknik/2017/12/20/kubernetes-on-docker-in-docker/
'IT > Kubernetes' 카테고리의 다른 글
[Kubernetes] Namespace (0) | 2019.05.14 |
---|---|
[Kubernetes] Networking - Pods (0) | 2019.04.27 |
[Kubernetes] Liveness & Readiness Probe (0) | 2019.04.26 |
[Kubernetes] Storage - StorageClass (0) | 2019.04.21 |
[Kubernetes] Storage - PersistentVolume (0) | 2019.04.21 |
댓글