서비스 API 카테고리
-
클러스터 컨테이너에 대한 엔드포인트를 제공하거나 레이블과 일치하는 컨테이너의 디스커버리에 사용되는 리소스
- 서비스
- ClusterIP
- ExternalIP(ClusterIP의 한 종류)
- NodePort
- LoadBalancer
- Headless(None)
- ExternalName
- Node-Selector
- 인그레스
- 서비스
-
파드는 서비스를 사용하지 않고도 파드간 통신이 가능하나, 서비스를 사용하면 두 가지 큰 장점이 있음
- 파드에 트래픽 로드 밸런싱
- 서비스 디스커버리와 클러스터 내부 DNS
파드에 트래픽 로드 밸런싱
- 수신한 트래픽을 여러 파드에 로드 밸런싱
ClusterIP
- 클러스터 내부에서만 사용 가능한 가상 IP를 가진 엔드포인트 제공하는 로드 밸런서 구성
- spec.selector에 정의한 조건에 따라 트래픽 전송
|
|
- Endpoints에 app=sample-app 라벨을 가진 파드의 IP 정보가 있음
- Endpoints 항목에 아무것도 없을 경우 셀렉터 조건이 맞지 않을 가능성 있음
|
|
여러 포트 할당
- 하나의 서비스에 여러 포트 할당 가능 (바람직)
이름을 사용한 포트 참조
- 파드의 포트 정의에 이름을 지정하면 이름을 사용하여 참조 가능
|
|
클러스터 내부 DNS와 서비스 디스커버리
- 서비스에 속한 파드를 보여주거나 서비스명에서 엔드포인트를 반환하는 것
- 서비스 디스커버리 방법
- 환경 변수 사용
- DNS A 레코드 사용
- DNS SRV 레코드 사용
환경 변수를 사용한 서비스 디스커버리
- 파드 내부에서는 환경 변수에서도 같은 네임스페이스 서비스 확인 가능
-
이 포함된 서비스명은_
로 변경 후 대문자 변환됨- 파드 생성 후 서비스 생성 또는 삭제에 따라 변경된 환경 변수가 기존 파드에 자동 등록되지 않음
- 먼저 생성한 파드 재생성 필요
|
|
- spec.enableServiceLinks를 false로 지정시 환경 변수 추가 비활성화 (기본값 true)
DNS A 레코드를 사용한 서비스 디스커버리
- IP 주소를 편하게 관리하기 위해 기본적으로 자동 할당된 IP 주소에 연결된 DNS 명을 사용하는 것이 좋음
- 서비스명의 이름 해석이 수행되고 해당 ip로 요청이 발송
- 다른 네임스페이스의 경우 sample-cluster.default와 같이 네임스페이스명을 붙여 이름 해석해야 함
|
|
DNS SRV 레코드를 사용한 서비스 디스커버리
- 포트명과 프로토콜을 사용해 서비스를 제공하는 포트 번호를 포함한 엔드포인트를 DNS로 해석
_서비스 포트명._프로토콜.서비스명.네임스페이스명.svc.cluster.local
|
|
- 목적지 호스트명 sample-clusterip.default.svc.cluster.local과 포트번호 8080 해석 가능
클러스터 내부 DNS와 클러스터 외부 DNS
- 파드의 DNS 서버 설정을 명시적으로 하지 않으면 클러스터 내부 DNS 사용하여 이름 해석 수행
- 내부 이외의 레코드는 외부 DNS에 재귀 질의 해야함
노드 로컬 DNS 캐시
- 대규모 클러스터에서 성능 향상을 위해 각 노드의 로컬에 DNS 캐시 서버를 포함하는 구조도 존재
- 활성화한 환경에서 파드의 질의 대상은 같은 노드에 있는 로컬 DNS 캐시 서버
ClusterIP 서비스
- 클러스터 내부에서만 통신 가능한 가상 IP 할당
- 클러스터 외부에서 트래픽을 수신할 필요가 없는 환경에서 내부 로드 밸런서로 활용
ExternalIP 서비스
- 지정한 쿠버네티스 노드 IP 주소:포트에서 수신한 트래픽을 컨테이너로 전달하는 형태로 외부와 통신
- 특별한 이유가 없다면 NodePort 서비스를 사용하는것이 좋음
type: ExternalIP
를 지정하는 것이 아님 (ClusterIP에 해당함)
NodePort 서비스
- 모든 쿠버네티스 노드 IP 주소:포트에서 수신한 트래픽을 컨테이너로 전달하는 형태로 외부와 통신
- 모든 쿠버네티스 노드의 IP 주소에서 해당 포트를 listen 하기 때문에 충돌 주의
- 할당된 포트 번호를 지정할 필요가 없을 경우, 포트를 지정하지 않으면 빈 포트 번호가 자동으로 선택됨
설정 항목 | 개요 |
---|---|
spec.ports[].port | ClusterIP에서 수신할 포트 번호 |
spec.ports[].targetPort | 목적지 컨테이너 포트 번호 |
spec.ports[].nodePort | 모든 쿠버네티스 노드 IP 주소에서 수신할 포트 번호 |
NodePort 주의점
- 가용한 포트 범위는 대부분 30000 ~ 32767
- 여러 NodePort 서비스에서 같은 포트 사용 불가
LoadBalancer 서비스
- 클러스터 외부로부터 트래픽을 수신할 때 가장 실용적인 서비스
- 쿠버네티스 노드와 별도로 외부 로드 밸런스를 사용 -> 노드 장애에도 크게 문제가 되지 않음 (장애 발생한 노드에는 트래픽을 전송하지 않음)
- 장애 감지 까지 일시적으로 서비스 중단 현상이 발생할 수 있음
- 생성시 EXTERNAL-IP가
<pending>
상태임- 로드밸런서를 백그라운드에서 생성중이기 때문에 아직 미할당된 상태
- 정적으로 외부 LB에서 사용하는 IP 주소 지정 가능
- 방화벽을 지정하여 접속 제한 가능
|
|
그 외 서비스
세션 어피니티
- 트래픽을 서비스에 연결된 어느 하나의 파트에 전송되면, 그 파드에 계속 보내고 싶을 때 사용
- 최대 세션 고정 시간 설정 가능
노드 간 통신 제외와 발신 측 IP 주소 유지
- NodePort, LoadBalancer 서비스에서 노드에 도착한 요청은 2단계 로드 밸런싱이 이루어짐(레이턴시 오버헤드 발생)
- 발신 측 IP 주소가 유실되는 특징
- 데몬셋은 하나의 노드에 하나의 파드만 배치되므로 같은 노드에만 통신하고 싶은 경우
- NodePort 서비스의
spec.externalTrafficPolicy
를local
로 설정- 해당 노드의 요청은 그 노드상에 있는 파드에만 전송
- 두 개 이상의 파드 존재시 균등 전송
- 파드가 없다면 요청에 응답할 수 없으므로 가능하면 사용 X
- 해당 노드의 요청은 그 노드상에 있는 파드에만 전송
- LoadBalancer 서비스의
spec.externalTrafficPolicy
를local
로 설정- 별도의 헬스 체크용 NodePort가 있어 파드가 존재하지 않는 노드에는 요청이 전송되지 않음
헤드리스 서비스(None)
- 대상이 되는 개별 파드의 IP 주소가 직접 반환되는 서비스
- 로드 밸런싱을 위한 IP 주소는 제공되지 않음
- DNS 라운드 로빈을 사용한 엔드포인트 제공
- 스테이트풀셋이 헤드리스 서비스를 사용하는 경우에만 파드명으로 IP주소를 찾을 수 있음
- 생성 조건
- 서비스의 spec.type이 ClusterIP일 것
- 서비스의 spec.ClusterIP가 None일 것
- [옵션] 서비스의 metadata.name이 스테이트풀셋의 spec.serviceName과 같을 것
- 파드명으로 디스커버리하는 경우
ExternalName 서비스
- 외부도메인으로 CNAME 반환
- 다른 이름을 설정하고 싶거나, 클러스터 내부에서의 엔드포인트를 쉽게 변경하고 싶을 때 사용
외부 서비스와 느슨한 결합 확보
- 목적지가 변경되었을 때 ExternalName 서비스를 변경하는 것만으로 가능
- ClusterIP 서비스에서 ExternalName 서비스로 전환할 경우 spec.clusterIP를 명시적으로 공란으로 두어야함
None-Selector 서비스
- 서비스명으로 이름 해석시 자신이 설정한 멤버에 대해 로드 밸런싱 수행
- externalName을 지정하지 않고 셀렉터가 존재하지 않는 서비스 생성 + 엔드포인트 리소스 수동 생성하면 유연한 서비스 생성 가능
- 쿠버네티스 외부에 애플리케이션 서버에 대한 요청을 분산하는 경우에도 쿠버네티스 서비스 사용 가능
- 서비스 환경과 스테이징 환경에서 클러스터 내외부를 분리해도 애플리케이션에서 같은 ClusterIP로 보여줄 수 있음
인그레스
- 서비스들을 묶는 서비스들의 상위 객체
리소스와 컨트롤러
- 매니페스트를 쿠버네티스에 등록하는 것만으로는 아무 처리도 일어나지 않음
- 실제 처리를 하는 컨트롤러라는 시스템 구성 요소 필요
- 인그레스 리소스: 매니페스트에 등록된 API 리소스
- 인그레스 컨트롤러: 인그레스 리소스가 쿠버네티스에 등록되었을 때 어떠한 처리 수행
인그레스 종류
- 클러스터 외부 로드 밸런서를 사용한 인그레스
- GKE 인그레스
- 클러스터 내부 로드 밸런서를 사용한 인그레스
- Nginx 인그레스
클러스터 외부 로드 밸런서를 사용한 인그레스
- 인그레스 리소스 생성만으로 로드 밸런서의 가상 IP가 할당되어 사용 가능
- 순서(단계)
- 클라이언트
- -> L7 로드 밸런서(NodePort 경유)
- -> 목적지 파드
클러스터 내부에 인그레스용 파드를 배포하는 인그레스
- 인그레스 리소스에서 정의한 L7 수준의 로드 밸런싱 처리를 하기 위해 인그레스용 파드를 클러스터 내부에 생성해야 함
- 클러스터 외부에서 접속할 수 있도록 별도로 인그레스용 파드에 LoadBalancer 서비스를 생성하는 등의 준비 필요
- SSL 터미네이션이나 경로 기반 라우팅 등과 같은 L7 수준의 처리를 위해 부하에 따른 레플리카 수의 오토 스케일링 고려해야 함
- 순서(단계)
- 클라이언트
- -> L4 로드 밸런서(type: LoadBalancer)
- -> Nginx 파드(Nginx 인그레스 컨트롤러)
- -> 목적지 파드
정리
- 파드 서비스 디스커버리나 L4 로드 밸런싱 기능을 제공하기 위한 서비스 리소스
- L7 로드 밸런싱 기능을 제공하는 인그레스
- 서비스
- L4 로드 밸런싱
- 클러스터 내부 DNS를 사용한 이름 해석
- 레이블을 사용한 파드의 디스커버리
- 인그레스
- L7 로드 밸런싱
- SSL 터미네이션
- 경로 기반 라우팅
서비스 종류 | IP 엔드포인트 내용 |
---|---|
ClusterIP | 쿠버네티스 클러스터 내부에서만 통신 가능한 가상 IP |
ExternalIP | 특정 쿠버네티스 노드의 IP 주소 |
NodePort | 모든 쿠버네티스 노드의 모든 IP 주소(0.0.0.0) |
LoadBalancer | 클러스터 외부에서 제공되는 로드 밸런서의 가상 IP |
Headless(None) | 파드의 IP 주소를 사용한 DNS 라운드 로빈 |
ExternalName | CNAME을 사용한 느슨한 연결 확보 |
None-Selector | 원하는 목적지 멤버를 설정할 수 있는 다양한 엔드 포인트 |
인그레스 종류 | 구현 예제 |
---|---|
클러스터 외부 로드 밸런서를 사용한 인그레스 | GKE |
클러스터 내부에 인그레스용 파드를 배포하는 인그레스 | Nginx 인그레스 |