charminseok
[쿠버네티스] 서비스 본문
IP 주소나 호스트 네임으로 요청하는 것과 다르게 쿠버네티스에서는 이런 방식으로 동작하지 않는다. 파드는 일시적이고, 파드의 IP 주소를 클라이언트가 알 수 없기 때문이다. 쿠버네티스느 이러한 문제를 해결하기 위한 방법으로 서비스를 제공한다.
서비스란?
동일한 서비스를 제공하는 파드 그룹에 지속적인 단일 접점을 만들때 생성하는 리소스
서비스가 존재하는한 절대 바뀌지 않는 IP와 포트번호를 가지고 있다. 해당 IP와 포트로 접속하면 파드 중 하나로 연결된다. 서비스는 다른 리소스와 같이 레이블 셀렉터를 통해 파드와 연결된다.
세션 어피니티
동일한 클라이언트에서의 요청을 매번 같은 파드로 리디렉션할 수 있다. 서비스의 spec 부분에 sessionAffinity: ClientIP로 주면 된다.
멀티 포트
한 파드가 두개의 포트를 수신한다면 두개의 서비스를 만들지 않고 멀티 포트 서비스를 사용하면 된다.
이름이 지정된 포트
각 파드의 포트에 이름을 지정하면 포트번호가 아니라 이 이름으로 사용할 수 있다. 이름으로 매핑되어있기 때문에 서비스의 스펙을 변경하지 않고 포트 번호를 수정할 수 있다.
서비스 검색
서비스를 만들면 파드에 연결할 수 있는 IP와 포트가 생기는 것은 알았다. 이 IP와 포트번호는 파드가 변경되어도 서비스가 유지되는 동안은 변하지 않는다. 하지만 이 IP와 포트번호를 클라이언트 파드는 어떻게 알 수 있는가?
1. 환경변수를 통한 서비스 검색
파드가 시작되면 쿠버네티스는 해당 시점에 존재하는 각 서비스를 가리키는 환경변수 세트를 초기화한다. 클라이언트 파드를 생성하기 전에 서비스를 생성하면 해당 파드의 프로세스는 환경변수를 검사해 서비스의 IP와 포트를 얻을 수 있다.
2. DNS를 통한 서비스 검색
쿠버네티스 클러스터 내 파드에서 어떤 도메인을 찾고자 할 때 kube-system 네임스페이스에 실행되고 있는 CoreDNS가 네임서버로 사용된다. 기존에 Kube-DNS가 이 역할을 했는데 1.12 버전부터 CoreDNS가 표준으로 채택되었다.
파드에서 실행 중인 프로세스에서 수행된 모든 DNS 쿼리는 시스템에서 실행 중인 모든 서비스를 알고 있는 쿠버네티스의 자체 DNS 서버로 처리된다.
3. FQDN을 통한 서비스 연결
동일한 네임스페이스에 있는 파드일 경우: <service-name>
네임스페이스가 다른 파드일 경우: <service-name>.<service-namespace>.svc.cluster.local
svc.cluster.local은 모든 클러스터의 로컬 서비스 이름에 사용되는 클러스트의 도메인 접미사이다.
클러스터 외부에 있는 서비스 연결
서비스는 파드를 직접 링크하지 않습니다. 대신 엔드포인트라 불리는 리소스가 파드와 서비스 사이에 있습니다. 서비스는 레이블 셀렉터를 사용하여 연결을 전달하는 것 대신 IP 와 포트 목록을 만들고 엔드포인트 리소스로 저장하는데 사용합니다. 클라이언트가 서비스에 연결하면 서비스 프록시는 이들 중 하나의 IP와 포트 쌍을 선택하고 들어온 연결을 대상 파드의 수신 대기 서버로 전달합니다.
외부 클라이언트에 서비스 노출
외부에서 서비스를 액세스할 수 있는 방법이 있다.
- 노드포트로 서비스 유형 설정: NodePort 서비스의 경우 각 클러스터 노드는 노드 자체에서 포트를 열고 해당 포트로수신된 트래픽을 서비스로 전달한다.
- 서비스 유형을 노드포트 유형의 확장인 로드밸런서로 설정: 로드밸런서는 트래픽을 모든 노드의 노드포트로 전달한다.
- 단일 IP주소로 여러 서비스를 노출하는 인그레스 리소스 만들기: HTTP 레벨에서 작동하므로 4계층 서비스보다 더 많은 기능을 제공할 수 있다.
노드포트 유형의 서비스를 만들면 쿠버네티스는 모든 노드에 특정 포트를 할당하고 서비스를 구성하는 파드로 들어오는 연결을 전달한다. 어떤 노드든 설정한 포트로 파드에 접근할 수 있다. 하지만, 연결을 보내는 노드에 장애가 생긴다면 더 이상 접근할 수 없기 때문에 앞단에 로드밸런서를 배치하는 것이 좋다.
로드 밸런서는 공개 IP 주소를 가지며 모든 연결을 서비스로 전달한다. 쿠버네티스가 로드밸런서를 지원하지 않는 환경에서 실행 중인 경우 로드밸런서는 프로비저닝되지 않지만 노드포트 서비스처럼 동작한다.
인그레스
로드밸런서 서비스는 자신의 공용 IP 주소를 가진 로드밸런서가 필요하지만, 인그레스는 한 IP 주소로 수십 개의 서비스에 접근이 가능하다. 또한, HTTP 계층에서 동작해 쿠키 기반 어피니티 등과 같은 기능도 제공한다.
해당 서비스에 접근하려면 도메인 이름이 인그레스 컨트롤러의 IP와 매핑되어야 한다.
$ kubectl get ingresses
위의 명령어로 인그레스 목록을 확인할 수 있다.
인그레스 동작 방식
클라이언트는 도메인 이름의 DNS 조회를 요청하고 DNS 서버가 인그레스 컨트롤러의 IP를 반환한다. 다음 클라이언트는 HTTP 요청을 인그레스 컨트롤러로 전송하고 host 헤더에서 도메인 네임을 지정한다. 컨트롤러는 해당 헤더에서 클라이언트가 액세스하려는 서비스를 결정하고 서비스와 관련된 엔드포인트 오브젝트로 파드 IP를 조회한 다음 클라이언트 요청을 파드에 전달한다.
인그레스는 호스트와 경로를 여러 서비스에 매핑할 수 있다.
- 동일한 호스트의 다른 경로로 여러 서비스 매핑
- 서로 다른 호스트로 서로 다른 서비스 매핑
레디니스 프로브
특정 레이블로 파드가 만들어지고 그 레이블에 매칭된 서비스가 원래 존재한다면, 그 파드가 만들어지는 순간부터 서비스의 요청 일부가 전달되기 시작한다. 하지만 파드가 생성되어도 요청을 처리할 준비가 되어 있지 않는 상황이 있을 수 있다. 그래서 파드가 완전히 준비될 때까지 새로 생성된 파드로 요청을 전달하지 않는 것이 좋다. 이럴 경우 사용하는 것이 레디니스 프로브다.
이전에 공부한 라이브니스 프로브와 비슷하게 레디니스 프로브를 정의할 수 있다. 레디니스 프로브는 주기적으로 호출되며 틀정 파드가 클라이언트의 요청을 처리할 수 있는지 결정합니다.
라이브니스 프로브와 같이 세 가지 유형이 있다.
- Exec 프로브
- HTTP HET 프로브
- TCP 프로브
라이브니스 프로브와 다른점은 컨테이너가 준비 상태 점검에 실패하더라도 컨테이너가 종료되거나 다시 시작되지 않는다. 라이브니스 프로브에 실패한다면 컨테이너를 제거하고 새로 실행하지만, 레디니스 프로브는 요청을 처리할 준비가 된 파드의 컨테이너만 요청을 수신하도록 한다.
'쿠버네티스' 카테고리의 다른 글
[쿠버네티스] 볼륨 (0) | 2022.11.07 |
---|---|
[쿠버네티스] 레플리카 컨트롤러 (1) | 2022.10.13 |
[쿠버네티스] 쿠버네티스 소개 (0) | 2022.09.30 |