[K8s in Action] 5. 서비스: 클라이언트가 파드를 검색하고 통신을 가능하게 함

Sangmin Yoon·2021년 6월 29일
0

Kubernetes in Action

목록 보기
5/8
post-custom-banner

대다수의 애플리케이션은 외부 요청에 응답하기 위한 것이다. 마이크로서비스의 경우 파드는 대게 클러스터 내부의 다른 파드나 클러스터 외부의 클라이언트에서 오는 HTTP 요청에 응답한다. 파드에 직접 접근하는 것은 불가능하다. 왜냐하면 1) 파드는 일시적이고, 2) 파드가 시작되기 직전에 IP가 할당되므로 IP를 미리 알 수 없고, 3) 여러 파드가 단일 IP로 접근 가능해야 하기 때문이다.
그래서 서비스가 있다.

1. 서비스

서비스는 동일한 서비스를 제공하는 파드 그룹에 지속적인 단일 접점을 만들기 위해 생성하는 리소스다.

1) 서비스 생성

  • 아래 서비스는 포트 80의 연결을 허용하고 각 연결을 app=kubia 레이블 셀렉터와 일치하는 파드의 포트 8080으로 라우팅한다.
  • 서비스의 sessionAffinity 구성
    - 쿠버네티스는 None과 ClientIP 두 가지 유형의 서비스 세션 어피니티만 지원한다. 쿠키 기반 세션 어피니티 옵션이 없는데, 이는 쿠버네티스 서비스가 HTTP 수준에서 작동하지 않기 때문이다. 서비스는 TCP와 UDP 패킷을 처리하고 그들이 가지고 있는 payload는 신경쓰지 않는다.
  • 동일한 서비스에서 여러 개의 포트 노출

    - 파드가 포트 이름을 정의할 수 있다. 이름이 지정된 포트를 사용하는 경우, 나중에 파드 스펙에서 포트 번호만 변경하면 된다.

2) 서비스 검색
클라이언트 파드는 서비스의 IP와 포트를 어떻게 알 수 있을까?

  • 환경변수를 통한 서비스 검색
    - 컨테이너 내부에서 env 명령어를 실행하면 생성된 서비스들의 IP/포트 번호를 확인할 수 있다.
  • DNS를 통한 서비스 검색
    - kube-system 네임스페이스에는 kube-dns 파드가 있다. 이 파드는 DNS 서버를 실행하며 클러스터에서 실행 중인 다른 모든 파드는 자동으로 이를 사용하도록 구성된다.
    - 각 서비스는 내부 DNS 서버에서 DNS 항목을 가져오고 서비스 이름을 알고 있는 클라이언트 파드는 환경변수 대신 FQDN(Fully Qualified Domain Name)으로 액세스할 수 있다.

2. 클러스터 외부에 있는 서비스 연결

서비스가 클러스터 내에 있는 파드로 연결을 전달하는 것이 아니라, 외부 IP와 포트로 연결을 전달하는 경우.
1) 서비스 엔드포인트

  • 서비스는 파드에 직접 link되지 않고 그 사이에 엔드포인트가 있다. 엔드포인트는 서비스로 노출되는 파드의 IP 주소와 포트 목록이다.

2) 서비스 엔드포인트 수동 구성

  • 셀렉터 없이 서비스 생성
    - 포트 80으로 들어오는 연결을 허용하는 external-service 서비스를 정의했다. 서비스에 대한 파드 셀렉터를 정의하지 않았다. 따라서 이 경우 엔드포인트 리소스가 자동으로 생성되지 않는다.
  • 셀렉터가 없는 서비스에 관한 엔드포인트 생성
    - 엔드포인트 오브젝트는 서비스와 이름이 같아야 하고 서비스를 제공하는 대상 IP 주소와 포트 목록을 가져야 한다.

    - 서비스와 엔드포인트가 모두 서버에 게시되면 파드 셀렉터가 있는 일반 서비스처럼 서비스를 사용할 수 있다. 서비스가 만들어진 후 만들어진 컨테이너에는 서비스의 환경변수가 포함되며 IP:포트 쌍에 대한 모든 연결은 서비스 엔드포인트 간에 로드밸런싱한다.

3) 외부 서비스를 위한 alias 생성

  • ExternalName 서비스 생성
    - 서비스의 엔드포인트를 수동으로 구성해 외부 서비스를 노출하는 것보다, FQDN으로 외부 서비스를 참조하는 것이 더 간단한다.
    - someapi.somecompany.com에 공개 API가 있다면, 이를 가리키는 서비스를 정의할 수 있다.

3. 외부 클라이언트에 서비스 노출


외부에서 서비스를 액세스할 수 있는 방법은 다음과 같다.
1) NodePort로 서비스 유형 설정 2) 서비스 유형을 NodePort 유형의 확장인 LoadBalancer로 설정 3) 단일 IP 주소로 여러 서비스를 노출하는 Ingress 만들기

1) NodePort 서비스 사용

  • Service를 생성하고 유형을 NodePort로 설정하면 외부 클라이언트에 노출시킬 수 있다.
  • 위와 같이 NodePort 타입의 서비스를 만들면, 다음과 같은 결과가 나온다.
  • 이제 이 서비스는 다음 주소에서 액세스할 수 있다.
    - 10.111.243.223:80
    - Node 1 IP:30123
    - Node 2 IP:30123

2) 외부 로드밸런서

  • 클라우드 공급자가 제공하는 로드밸런서를 노드포트 대신 설정하기만 하면 된다. 로드밸런서의 IP 주소로 서비스에 액세스할 수 있다. 로드밸런서는 노드포트의 확장이기 때문.

4. Ingress 리소스로 서비스 외부 노출

  • Ingress가 필요한 이유
    - Ingress는 한 IP 주소로 수십 개의 서비스에 접근이 가능하도록 지원해준다. Ingress는 애플리케이션 계층(HTTP)에서 작동하며 쿠키 기반 세션 어피니티도 지원한다.
  • Ingress 동작 방식

    1. 클라이언트가 DNS로부터 Ingress Controller의 IP를 받는다.
    2. HTTP GET request를 Ingress Controller로 전송한다.
    3. Ingress Controller가 해당 헤더에서 클라이언트가 액세스하려는 서비스를 결정하고 서비스와 관련된 엔드포인트 오브젝트로 파드 IP를 조회한 다음 파드에 요청 전달한다.
  • TLS 트래픽을 처리하도록 Ingress 구성
    - 클라이언트와 Ingress Controller 사이에서만 TLS Connection이 이루어진다. 클러스터 내부에서는 TLS 필요 없다.

5. 파드가 연결을 수락할 준비가 됐을 때 신호 보내기

파드의 레이블과 서비스의 파드 셀렉터가 일치할 경우 엔드포인트에 파드가 추가되고 요청이 파드로 즉시 넘어간다. 그런데 만약 파드가 요청을 처리할 준비가 되지 않았다면?

1) Readiness Probe

  • 주기적으로 호출되며 특정 파드가 클라이언트 요청을 수신할 수 있는지 결정. Liveness Probe와 마찬가지로 3가지 유형(exec probe, HTTP GET probe, TCP Socket probe)가 있음.
  • Liveness Probe와 달리 컨테이너가 준비 상태 점검에 실패하더라도 컨테이너가 종료되거나 다시 실행되지 않는다.
  • 레디니스 프로브를 항상 정의하라.

6. 헤드리스 서비스로 개별 파드 찾기

클라이언트가 모든 파드에 연결해야 하는 경우 어떻게 해야 할까? 파드가 다른 파드에 각각 연결해야 하는 경우 어떻게 해야 할까?
1) 헤드리스 서비스 생성

  • Service spec에서 clusterIP를 None으로 설정하면 하나의 Service IP 대신 파드 IP들을 반환한다.
post-custom-banner

0개의 댓글