Virtual IPs and Service Proxies
Kubernetes 클러스터의 모든 노드는 kube-proxy를 실행한다고함. 이 kube-proxy는 ExternalName 이외의 유형의 서비스에 대해 가상 IP 형식을 구현한다고함
왜 round-robin DNS를 사용하지 않는가?
서비스에 프록시를 사용하는 이유(kube-proxy)
- 레코드 TTL을 고려하지 않고 만료 된 후에도 이름 조회 결과를 캐싱하는 DNS 구현의 긴 이력이 있음
- 앱들은 DNS를 단 한번 룩업하며, 해당 결과를 무기한 캐시함
- 앱과 라이브러리가 올바른 재결정이 이루어지더라도, DNS 레코드의 TTL이 낮거나 0이면 DNS에 부하가 높아 관리하기가 어려워 질 수 있음
유저 스페이스 프록시 모드
- 이 모드에서 kube-proxy는 서비스와 앤드포인트 오브젝트들의 추가 삭제를 감시한다. 감시 대상은 마스터!
- 각 서비스를 위해 이 모드는 로컬 노트 상에 랜덤으로 포트를 오픈함(프록시 포트)
- 프록시 포트에 대한 모든 연결은 서비스들의 백엔드 파드들 중에 하나에 프록시됨
- kube-proxy는 사용할 백엔드 파드를 결정할 때 서비스의 SessionAffinity 설정을 고려함
- 마지막으로 유저 스페이스 프록시는 서비스의 clusterIP (가상) 및 포트에 대한 트래픽을 캡처하는 iptables 룰을 등록함
- 이 규칙은 해당 트래픽을 백엔드 파드를 프록시하는 프록시 포트로 리디렉션함
- 기본적으로 사용자 공간 모드의 kube-proxy는 라운드 로빈 알고리즘을 통해 백엔드를 선택함
iptables 프록시 모드
- 이 모드에서 kube-proxy는 서비스와 앤드포인트 오브젝트들의 추가 삭제를 감시한다. 감시 대상은 제어 평면!
- 각 서비스에 대해 iptable 규칙을 등록
- 룰은 서비스들의 clusterIP와 포트에 대한 트래픽을 잡고, 서비스들의 백엔드 파드들 중 하나에 트래픽을 리다이렉션함
- 각 앤드 포인트 오브젝트를 위해, 백엔드 파드를 선택하는 iptable 규칙을 등록함
- 트래픽을 다루기 위해 iptables을 사용하는 것은 좀 더 낮은 시스템 오버헤드를 가지는데, 이유는 트래픽은 리눅스 넷필터로부터 다루어지기 때문임(유저스페이스와 커널 스페이스 사이에 전환이 필요없음)
- 이 접근 방식은 더욱 안정적이라고 함
- kube-proxy가 iptables 모드에서 실행 중인 상태에서, 선택된 첫 파드가 응답하지 않는다면, 연결이 실패함
- kube-proxy는 첫 번째 파드에 대한 연결이 실패했음을 감지하고 다른 백엔드 파드로 자동으로 다시 시도함
- Pod 준비 프로브를 사용하여 백엔드 포드가 제대로 작동하는지 확인함
- 즉 iptables 모드의 kube-proxy는 정상으로 테스트 된 백엔드만 볼 수있으며, kube-proxy를 통해 트래픽이 실패한 파드로는 전송되지 않음
IPVS 프록시 모드(IP Virtual Server)
- - kube-proxy는 서비스와 앤드포인트들를 감시함
- 주기적으로 쿠버네티스 서비스 및 앤드포인트들과 IPVS 규칙을 동기화함
- ipvs 모드에서 kube-proxy는 Kubernetes Services and Endpoints를 감시하고 그에 따라 IPVS 규칙을 생성하기 위해 netlink 인터페이스를 호출함
- Kubernetes Services 및 Endpoints와 함께 IPVS 규칙을 주기적으로 동기화함
- 제어 루프는 IPVS 상태가 요구된 상태로 매치하는 것을 보장함
- 서비스에 접근했을 때, IPVS는 백앤드 파드들 중 하나에 트래픽을 줌
- IPVS 프록시 모드는 넷필터 훅 기능에 기반하여 iptables 모드와 비슷하나, 해쉬 테이블을 이용하며 커널 스페이스에서 동작함.
- IPVS 프록시 모드에서 Kube-proxy는 iptable mode kube-proxy보다 낮은 레이턴시에 트래픽을 리다이렉트하며, 프록시 룰을 동기화할 때 더좋은 퍼포먼스로 트래픽을 리다이렉트 함
- 다른 프록시 모드랑 비교해보면, IPVS 모드는 네트워크 트래픽의 좀더 높은 스루풋을 제공함
load balancing option
- round-robin
- least connection
- destination hashing
- source hashing
- sortest expected delay
- never queue
해당 vm linux host에서 IPVS 세팅이 필요함
Multi-Port Service
여러 포트를 노출할 필요가 있을 때(몇몇 서비스들을 위해)
서비스 오브젝트에서 여러 포트를 정의할 수 있음
서비스를 위해 여러 포트를 사용할 때, 포트들의 이름이 주어져야함
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
Discovering Service
쿠버네티스는 서비스를 찾기 위해 2가지 프라미어리 모드를 지원함
-
enviroment variables
1) 노드에서 파드를 실핼할 때, kubelet이 각 활성화 서비스에 대한 환경 변수를 셋함
-
DNS
1) 클러스터에 addon을 이용하여 DNS 서비스 셋업을 할 수 있음
2) CoreDNS와 같은 cluster-aware DNS Server
3) Namespace: my-namespace, Service: my-service
- dns : my-service.my-namespace
4) Kubernates는 DNS SRV Record를 지원함(portName: http, protocol: tcp)
- dns src query : _http._tcp.my-service.my-namespace(포트 번호를 알기위해)
5) 쿠버네티스 DNS 서버는 오직 ExternalName 서비스들에 접근하기 위한 방법임
Headless Services
-
로드벨런싱과 단일 서비스 IP가 필요없을때 사용
-
clusterIP를 None으로 지정해야함
-
Kubernetes의 구현에 묶이지 않고 헤드리스 서비스를 사용하여 다른 서비스 검색 메커니즘과 인터페이스 할 수 있음
-
헤드리스 (headless) 서비스의 경우, 클러스터 IP를 할당받지않으며, KUBE-프록시는 이 서비스를 처리하지 않음
-
그들을 위해 플랫폼으로부터 로드 벨렁신이나 프록시 수행을 하지 않음
-
DNS가 자동으로 구성되는 방법은 서비스에 선택기가 정의되어 있는지 여부에 따라 다릅니다.
with selectors
- endpoints controller는 api에 endpoints 레코드들을 만듬
- 서비스를 지원하는 파드를 직접 가리키는 레코드 (주소)를 반환하기 위해 DNS 환경구성을 수정함
without selectors
- Endpoints 레코드를 만들지 않지만 DNS 시스템은 찾고 환경구성한다.
1) CNAME records for externalName-type Services
2) A records for any Endpointes that share a name with the Servie, for all other types
출처
[1] https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
[2] https://arisu1000.tistory.com/27839?category=787056