Kubernetes 인 액션 5장 서비스: 클라이언트가 파드를 검색하고 통신을 가능하게 함
Devops/Kubernetes

Kubernetes 인 액션 5장 서비스: 클라이언트가 파드를 검색하고 통신을 가능하게 함

뉴비뉴 2023. 5. 24.

참고

다루는 내용

  • 단일 주소로 파드를 노출하는 서비스 리소스 만들기
  • 클러스터 안에서 서비스 검색
  • 외부 클라이언트에 서비스 노출
  • 클러스터 내에서 외부 서비스 접속
  • 파드가 서비스할 준비가 됐는지 제어하는 방법
  • 서비스 문제 해결
  • 파드는 일시적이다. 파드가 다른 파드를 위한 공간을 확보하려고 노드에서 제거하거나, 누군가 파드 수를 줄이거나, 클러스터 노드의 장애로 언제든 다른 노드로 이동할 수 있다.
  • Kubernetes는 노드에 파드를 스케줄링 한 후 파드가 시작되기 바로 전에 파드의 IP 주소를 할당한다. 따라서 클라이언트는 서버인 파드의 IP 주소를 미리 알 수 없다.
  • 수평 스케일링은 여러 파드가 동일한 서비스를 제공할 수 있음을 의미한다. 각 파드는 고유한 IP 주소가 있다. 클라이언트는 서비스를 지원하는 파드의 수와 IP에 상관하지 않아야 한다. 파드의 개별 IP 목록을 유지할 필요가 없다. 그 대신, 모든 파드는 단일 IP 주소로 액세스 할 수 있어야 한다.

5.1 서비스 소개

Kubernetes의 서비스는 동일한 서비스를 제공하는 파드 그룹에 지속적인 단일 접점을 만들려고 할 때 생성하는 리소스다. 각 서비스는 서비스가 존재하는 동안 절대 바뀌지 않는 IP 주소와 포트가 있다. 클라이언트는 해당 IP와 포트로 접속하는 다음 해당 서비스를 지원하는 파드 중 하나로 연결된다.

5.1.1 서비스 생성

서비스 연결은 서비스 뒷단의 모든 파드로 로드밸런싱 된다.

kubectl expose로 서비스 생성

expose 명령어는 레플리케이션컨트롤러에서 사용된 것과 동일한 파드 셀렉터(Selector)를 사용해 서비스 리소스를 생성하고 모든 파드를 단일 IP 주소와 포트로 노출한다.

YAML 디스크립터를 통한 서비스 생성

실행중인 컨테이너에 원격으로 명령어 실행

$ kubectl exec cslee-55ngi --curl -s http://10.111.241.253
You’ve hit cslee-55ngi

더블 대시를 사용하는 이유

명령어의 더블 대시(--)는 kubectl 명령줄 옵션의 끝을 의미한다. 더블 대시 뒤에 모든 것은 파드 내에서 실행돼야 하는 명령어다.

서비스의 세션 어피니티(Affinity) 구성

동일한 명령을 몇 번 더 실행하면 동일한 클라이언트에서 요청하더라도 서비스 프록시가 각 연결을 임의의 파드를 선택해 연결을 다시 전달 하기 때문에 요청할 때마다 다른 파드가 선택된다. 반면 특정 클라이언트의 모든 요청을 매번 같은 파드로 리디렉션하려면 서비스의 세션 어피니티 속성을 기본 값 None 대신 ClientIP로 설정한다.

LET ME) 세션 어피니티는 '클라이언트 요청을 매번 똑같은 파드로 연결하고 싶은 경우'나 그렇게 해야 할 경우에 사용하는 서비스. 특정 클라이언트가 특정 파드로 지속적으로 연결이 되게 하려면 세션 어피니티 사용

동일한 서비스에서 여러 개의 포트 노출

서비스는 단일 포트만 노출하지만 여러 포트를 지원할 수도 있다. 파드가 두 개의 포트 8080 8443를 수신한다면 하나의 서비스를 사용해 포트 80과 443을 파드의 포트 8080과 8443으로 전달할 수 있다.

이 경우 굳이 두 개의 서비스를 만들 필요가 없다. 하나의 서비스를 사용해 멀티 포트 서비스를 사용하면 단일 클러스터 IP로 모든 서비스 포트가 노출된다.

LET ME)

targetPort: 파드의 애플리케이션 쪽에서 열려 있는 포트

port: 서비스 쪽에서 해당 파드를 향해 열려있는 포트를 의미한다.

5.1.2 서비스 검색

서비스를 만들면 파드에 액세스할 수 있는 안정적인 IP 주소와 포트가 생긴다. 이 주소는 서비스가 유지되는 동안 변경되지 않는다. 이 서비스의 파드는 생성되기도 하고 사리지기도 하고 파드 IP가 변경되거나 파드 수는 늘어나거나 즐어들 수 있지만, 항상 서비스의 IP주소로 액세스 할 수 있어야 한다.

그러나 클라이언트 파드는 서비스의 IP와 포트를 어떻게 알 수 있을까? 서비스를 생성한 다음 IP 주소를 수동으로 찾아서 클라이언트 파드의 구성 옵션에 IP를 전달해야 할까? 아니다. Kubernetes는 클라이언트 파드가 서비스의 IP와 포트를 검색할 수 있는 방법을 제공한다.

환경변수를 통한 서비스 검색

파드가 시작되면 Kubernetes는 해당 시점에 존재하는 각 서비스를 가리키는 환경변수 세트를 초기화 한다.

클라이언트 파드를 생성하기 전에 서비스를 생성하면 해당 파드의 프로세스는 환경변수를 검사해 서비스의 IP 주소와 포트를 얻을 수 있다.

$ kubectl delete po --all

서비스에 대한 환경변수를 보려면 먼저 모든 파드를 삭제하고 레플리케이션컨트롤러에서 새로 파드를 만들어야 한다.

$ kubectl exec cslee-5x5x5 env

컨테이너 내부에서 env 명령어를 실행해 환경변수를 조회할 수 있다.

|노트| 서비스 이름의 대시(-)는 밑줄(_)로 변환되고 서비스 이름이 환경변수 이름의 접두어로 쓰이면서 모든 문자는 대문자로 표시된다.

환경변수는 서비스의 IP와 포트를 찾는 한 가지 방법은 될 수 있지만 대개 DNS의 도메인을 사용하는 것이 일반적이지 않을까?

DNS를 통한 서비스 검색

파드 중 하나는 kube-dns 라고 불렀다. kube-system 네임스페이스에는 동일한 이름의 해당 서비스가 있다.

kube-system 네임스페이스에는 동일한 이름의 해당 서비스가 있다.

이름에서 알 수 있듯이 이 파드는 DNS 서버를 실행하며 클러스터에서 실행 중인 다른 모든 파드는 자동으로 이를 사용하도록 구성된다. (kubernetes는 각 컨테이너의 /etc/resolv.conf 파일을 수정해 이를 작성한다.) 파드에서 실행 중인 프로세스에서 수행된 모든 DNS 쿼리는 시스템에서 실행 중인 모든 서비스를 알고 있는 쿠버네티스의 자체 DNS 서버로 처리된다.

파드의 컨테이너 내에서 셀 실행

$ kubectl exec -it cslee-5g3g2g bash 
root@cslee-5g3g2g: /#
root@cslee-5g3g2g: /# curl http://cslee.default.svc.cluster.local You’ve hit cslee-5g3g2g
root@cslee-5g3g2g: /# curl http://cslee.default You’ve hit cslee-5g3g2g
root@cslee-5g3g2g: /# curl http://cslee You’ve hit cslee-5g3g2g

서비스 IP에 핑을 할 수 없는 이유

서비스로 curl은 동작하지만 핑은 응답이 없다.

이는 서비스의 클러스터 IP가 가상 IP 이므로 서비스 포트와 결합된 경우에만 의미가 있기 때문이다.

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

Kubernetes 서비스 기능으로 외부 서비스를 노출하려는 경우가 있을 수 있다. 서비스가 클러스터 내에 있는 파드로 연결을 전달하는 게 아니라, 외부 IP와 포트로 연결을 전달하는 것이다. 이 경우 서비스 로드밸런싱과 서비스 검색(DNS) 모두 활용할 수 있다. 클러스터에서 실행 중인 클라이언트 파드는 내부 서비스에 연결하는 것처럼 외부 서비스에 연결할 수 있다.

5.2.1 서비스 엔드포인트 소개

서비스는 파드에 직접 연결되지 않는다. 대신 엔드포인트 리소스가 그 사이에 있다.

Endpoints: 이 서비스의 엔드포인트를 나타내는 파드 IP와 포트 목록

엔드포인트 리소스는 서비스로 노출되는 파드의 IP 주소와 포트 목록이다.

$ kubectl get endpoints cslee

파드 셀렉터는 서비스 스펙에 정의돼 있지만 들어오는 연결을 전달할 때 직접 사용하지는 않는다. 대신 셀렉터는 IP와 포트 목록을 작성하는 데 사용되며 엔드포인트 리소스에 저장된다. 클라이언트가 서비스에 연결하면 서비스 프록시는 이들 중 하나의 IP와 포트 쌍을 선택하고 들어온 연결을 대상 파드의 수신 대기 서버로 전달한다.

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

서비스의 엔드포인트를 서비스와 분리하면 엔드포인트를 수동으로 구성하고 업데이트할 수 있다.

파드 셀렉터 없이 서비스를 만들면 Kubernetes는 엔드포인트 리소스를 만들지 못한다. (파드 셀렉터가 없어, 서비스에 포함된 파드가 무엇인지 알 수 없다.)

셀렉터 없이 서비스 생성

LET ME) 즉 spec: selector: app: cslee 없이 서비스를 생성하였다.

서비스 이름은 엔드포인트 오브젝트 이름과 일치해야 한다.

포트 80으로 들어오는 연결을 허용하는 external-service라는 서비스를 정의하는 것이다.

서비스에 대한 파드 셀렉터를 정의하지 않았다.

셀럭터가 없는 서비스에 관한 엔드포인트 리소스 생성

셀렉터가 없는 서비스를 생성했기 때문에 엔드포인트 리소스가 자동으로 생성되지 않는다.

LET ME) 셀렉터를 지정하고 서비스를 만들면 엔드포인트가 생성된다.

대상 IP 주소와 포트 목록을 가져야 한다.

서비스와 '엔드포인트 리소스'가 모두 서버에 게시되면 파드 셀렉터가 있는 일반 서비스처럼 서비스를 사용할 수 있다.

서비스가 만들어진 후 만들어진 컨테이너에는 서비스의 환경변수가 포함되며

IP:포트 쌍에 대한 모든 연결은 서비스 엔드포인트 간에 로드밸런싱한다.

LET ME) 셀렉터만 지정하면 되는데 왜 셀렉터 없이 생성할까

나중에 외부 서비스를 Kubernetes 내에서 실행되는 파드로 마이그레이션하기로 결정한 경우 '서비스에 셀렉터를 추가해 엔드포인트를 자동으로 관리할 수 있다.' 서비스에서 셀렉터를 제거하면 Kubernetes는 엔드포인트 업데이트를 멈춘다. 이는 서비스의 실제 구현이 변경되는 동안에도 서비스 IP 주소가 일정하게 유지할 수 있음을 의미한다.

5.2.3 외부 서비스를 위한 별칭 생성

서비스의 엔드포인트를 수동으로 구성해 외부 서비스를 노출하는 대신

좀 더 간단한 방법으로 **FQDN(정규화된 도메인 이름)**으로 외부 서비스를 참조할 수 있다.

ExternalName 서비스 생성

서비스가 생성되면 파드는 서비스의 FQDN(정규화된 도메인 이름) 을 사용하는 대신

external-service.default.svc.cluster.local 도메인 이름으로 외부 서비스에 연결할 수 있다.

 

ExternalName 서비스는 DNS 레벨에서만 구현된다. 서비스에 관한 간단한 CNAME DNS 레코드가 생성된다.

|노트| DNAME 레코드는 IP 주소 대신 FQDN을 가리킨다.

https://magpienote.tistory.com/276#:~:text=%ED%95%9C%20%EA%B2%83%EC%9E%85%EB%8B%88%EB%8B%A4.-,ExternalName,%ED%98%B8%EC%B6%9C%ED%95%A0%20%EB%95%8C%20%EC%82%AC%EC%9A%A9%ED%95%A9%EB%8B%88%EB%8B%A4.

LET ME) k8s cluster안에 있는 컨테이너를 호출하는 것이 아니라 k8s안에서 외부 서비스를 호출할 때 사용합니다. 

*호출할 때는 service 이름으로 호출하지만, 실제로는 service 안에 DNS Server에 Pod의 이름과 Service의 이름이 붙여져서 도메인 이름으로 등록되어 매핑됩니다. - {serviceName}. {namespaceName}. svc.cluster.local으로 생성된다.
*service이름을 호출하면 {serviceName}. {namespaceName}. svc.cluster.local를 찾아가고 이안에 저장되어 있는 DNS를 호출합니다.

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

프론트엔드 웹 서버와 같은 특정 서비스를 외부에 노출해 외부 클라이언트가 액세스할 수 있게 하고 싶을 수도 있다.

  •  NodePort로 서비스 유형 설정: NodePort 서비스의 경우 각 클러스터 노드는 노드 자체에서 포트를 열고 해당 포트로 수신된 트래픽을 서비스로 전달한다. 이 서비스는 내부 클러스터 IP와 포트로 액세스할 수 있을 뿐만 아니라 모든 노드의 전용 포트로도 액세스할 수 있다.

  • 서비스 유형을 NodePort 유형의 확장인 로드밸런서로 설정: Kubernetes가 실행 중인 클라우드 인프라에서 프로비저닝된 전용 로드밸런서로 서비스에 액세스 할 수 있다. 로드밸런서는 트래픽을 모든 노드의 NodePort로 전달한다. 클라이언트는 로드밸런서의 IP로 서비스에 액세스한다.
  • 단일 IP 주소로 여러 서비스를 노출하는 인그레스 리소스 만들기: HTTP 레벨(네트워크 7 계층) 에서 작동하므로 4계층 서비스보다 더 많은 기능을 제공할 수 있다.

5.3.1 NodePort 서비스 사용

파드 세트를 외부 클라이언트에 노출시키는 첫 번째 방법은 서비스를 생성하고, 유형을 NodePort로 설정하는 것이다. NodePort 서비스를 만들면 Kubernetes는 '모든 노드에 특정 포트를 할당'하고(모든 노드에서 동일한 포트 번호가 사용된다) 서비스를 구성하는 파드로 들어오는 연결을 전달한다.

 

LET ME) nodePort: 외부에서 접속하기 위해 사용하는 포트

port: Cluster 내부에서 사용할 Service 객체의 포트

targetPort: Service 객체로 전달된 요청을 Pod(Deployment)로 전달할 때 사용하는 포트

NodePort 서비스 생성

유형을 NodePort로 설정하고 이 서비스가 모든 클러스터 노드에 바인딩돼야 하는 NodePort를 지정한다.

NodePort 서비스 확인

EXTERNAL_IP 열에 <nodes> 라고 표시돼 있고 클러스터 노드의 IP 주소로 서비스에 액세스할 수 있음을 나타낸다. PORT(S) 열에는 클러스터 IP의 내부 포트 (80)과 NodePort (30123)이 모두 표시된다.

  • 10.111.254.223:80
  • <첫 번째 노드의 IP>:30123
  • <두 번째 노드의 IP>:30123 등
  •  

첫 번째 노드의 포트 30123에서 수신된 연결은 첫 번째 노드에서 실행 중인 파드 또는 두 번째 노드에서 실행 중인 파드로 전달될 수 있다.

LET ME) 여기서 보이는 IP 주소는 노드 IP 이다. 2개의 노드가 존재한다.

5.3.2 외부 로드밸런서로 서비스 노출

클라우드 공급자에서 실행되는 Kubernetes 클러스터는 일반적으로

클라우드 인프라에서 로드밸런서를 자동으로 프로비저닝하는 기능을 제공한다.

NodePort 대신 서비스 유형을 로드밸런서로 설정하기만 하면 된다.

로드밸런서는 공개적으로 액세스 가능한 고유한 IP 주소를 가지며 모든 연결을 서비스로 전달한다.

로드밸런서 서비스 생성

로드밸런서를 통한 서비스 연결

로드밸런서 IP 주소가 서비스의 external IP 주소로 표시된다.

NodePort와 달리 방화벽을 설정할 필요가 없다.

이미 언급했듯이 로드밸런서 유형 서비스는 추가 인프라 제공 로드밸런서가 있는 NodePort 서비스다.

5.4 Ingress 리소스로 서비스 외부 노출

Ingress가 필요한 이유

한 가지 중요한 이유는 로드밸런서 서비스는 자신의 공용 IP 주소를 가진 로드밸런서가 필요하지만, 인그레스는 한 IP 주소로 수십 개의 서비스에 접근이 가능하도록 지원해준다. 클라이언트가 HTTP 요청을 인그레스에 보낼 때, 요청한 호스트와 경로에 따라 요청을 전달할 서비스가 결정된다.


Service란

  • Kubernetes 환경에서 서비스(Service)는 파드들을 통해 실행되고 있는 애플리케이션을 네트워크에 노출(expose) 시키는 가상의 컴포넌트다.
  • 왜 서비스란 것이 필요하게 되었을까? 클러스터 안에서 애플리케이션을 구동시키는 데에 쓰이는 파드들의 반영속적인(ephemeral) 특성 때문이다. 쿠버네티스에서의 파드는 무언가가 구동 중인 상태를 유지하기 위해 동원되는 일회성 자원 으로 언제든 다른 노드로 옮겨지거나 삭제될 수 있다. 또한 파드는 생성될 때마다 새로운 내부 IP를 받게 되므로, 이것만으로 클러스터 내/외부와 통신을 계속 유지하기는 어렵다.
  • 따라서 쿠버네티스에서는 파드가 외부와 통신할 수 있도록 클러스터 내부에서 고정적인 IP를 갖는 서비스(Service)를 이용하도록 하고 있다. 서비스는 또한 디플로이먼트나 스테이트풀셋처럼 같은 애플리케이션을 구동하도록 구성된 여러 파드들에게 단일한 네트워크 진입점 을 부여하는 역할도 한다.

targetPort: 파드의 애플리케이션 쪽에서 열려있는 포드를 의미한다.

서비스로 들어온 트래픽은 해당 파드의 <클러스터 내부 IP>:<targetPort> 로 넘어가게 된다.

 

port: 서비스 쪽에서 해당 파드를 향해 열려있는 포트를 의미한다.

Service 유형

Kubernetes 에서 서비스의 유형은 크게 4가지로 분류된다. 명세(spec) 상에 type가 별도로 지정되지 않았다면 ClusterIP 로 고정된다.

  1. ClusterIP
  2. NodePort
  3. LoadBalancer
  4. Ingress

1. ClusterIP

ClusterIP는 파드들이 클러스터 내부의 다른 리소스들과 통신할 수 있도록 해주는 가상의 클러스터 전용 IP다.

apiVersion: v1
kind: Service
metadata:
  name: cslee
spec:
  selector:
    app: cslee
  type: ClusterIP
  ports:
  - name: http
    port: 8000
    targetPort: 80
    protocol: TCP

$ kubectl proxy --port=8000

이제 다음과 같은 Kubernetes API를 통해 서비스에 접근할 수 있다.

http://localhost:8000/api/v1/namespaces/default/services/cslee-svc:80/proxy/

언제 사용해야 할까?

Kubernetes 프록시를 사용해서 서비스에 접근해야 할 몇 가지 경우가 있다.

  1. 서비스를 디버깅하거나 어떤 이유로 노트북/PC 에서 직접 접근할 때
  2. 내부 대시보드 표시 등 내부 트래픽을 허용할 때

이 방식에서는 권한 있는 사용자가 kubectl 을 실행해야 하기 때문에,

서비스를 외부에 노출하는데 사용하거나 실서비스에서 사용해서는 안 된다.

2. NodePort

NodePort 서비스는 서비스에 외부 트래픽을 직접 보낼 수 있는 가장 원시적인 방법이다. 이름에서 암시하듯이, NodePort는 모든 Node(VM)에 특정 포트를 열어 두고, 이 포트로 보내지는 모든 트래픽을 서비스로 포워딩한다.

apiVersion: v1
kind: Service
metadata:  
  name: cslee-nodeport
spec:
  selector:    
    app: cslee
  type: NodePort
  ports:  
  - name: http
    port: 80
    targetPort: 8080
    nodePort: 30036
    protocol: TCP

기본적으로 NodePort 서비스는 일반 ClusterIP 서비스와는 2가지 차이가 있다. 우선, 타입이 NodePort 이다. 그리고 node에 어떤 포트를 열어줄지 지정하는 nodePort라는 추가 포트가 있다. 이 포트를 지정하지 않으면, 아무 포트나 선택된다. 대부분의 경우 Kubernetes가 포트를 선택하도록 두어야 한다. thockin 이 말했듯이, 어떤 포트가 사용 가능한지에는 많은 주의사항이 있다.

LET ME) minikube의 경우 EXTERNAL-IP가 없다. 그러므로 내부 테스트는 POD 내부로 접근(exec)하여 curl INTERNAL-IP를 입력해주고, 포트는 NodePort 를 입력해주면 된다. EX) curl 192.168.58.2:30036

언제 사용해야 할까?

  1. 포트당 한 서비스만 할당할 수 있다.
  2. 30000-32767 사이의 포트만 사용할 수 있다.
  3. Node나 VM의 IP 주소가 바뀌면, 이를 반영해야 한다.

이런 이유들 때문에 실서비스에서 이 방법으로 서비스를 직접적으로 노출시키는 걸 추천하지 않는다. 항상 사용 가능한 상태가 아니여도 되는 서비스를 운영하거나 비용에 민감 하다면, 이 방법이 적합할 것이다. 이런 어플리케이션의 좋은 예는 데모 앱이나 임시로 사용되는 것들이다.

LoadBalancer

LoadBalancer 서비스는 서비스를 인터넷에 노출하는 일반적인 방식이다.

LET ME)

$ kubectl expose replicaset cslee --type=LoadBalancer --port=8080

$ kubectl get svc

언제 사용해야 할까?

서비스를 직접적으로 노출하기를 원한다면, LoadBalancer가 기본적인 방법일 것이다. 지정한 포트의 모든 트래픽은서비스로 포워딩 될 것이다. 필터링이나 라우팅 같은 건 전혀 없다. 즉 HTTP, TCP, UDP, Websocket, gRPC 등등 거의 모든 트래픽 종류를 보낼 수 있는 것을 뜻한다.

 

가장 큰 단점은 LoadBalancer로 노출하고자 하는 각 서비스 마다 자체의 IP 주소를 갖게 된다는 것과, 노출하는 서비스 마다 LoadBalancer 비용을 지불해야 하기 때문에 값이 비싸진다는 것이다.

Ingress

위의 예와는 다르게, Ingress는 서비스의 한 조율가 아니다. 여러 서비스들 앞에서 “스마트 라우터” 역할을 하거나 클러스터의 진입점(entrypoint) 역할을 한다.

기본 GKE Ingress 컨트롤러는 HTTP(S) Load Balancer를 만들어 준다. 이것은 백엔드 서비스로 경로와 서브 도메인 기반의 라우팅을 모두 지원한다. 예를 들어, foo.yourdomain.com 으로 들어오는 모든 트래픽을 foo 서비스로 보낼 수 있고, yourdomain.com/bar 경로로 들어오는 모든 트래픽을 bar 서비스로 보낼 수 있다.

LET ME) 우리가 전 회사에서 했던 프로젝트도 이런식으로 마이크로 아키텍처로 관리하고, 그 서비스들을 Ingress로 연결하여 트래픽을 관리하였다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cslee-ingress
spec:
  backend:
    serviceName: cslee
    servicePort: 8080
  rules:
  - host: foo.mydomain.com
    http:
      paths:
      - backend:
          serviceName: foo
          servicePort: 8080
  - host: mydomain.com
    http:
      paths:
      - path: /bar/*
        backend:
          serviceName: bar
          servicePort: 8080

$ kubectl create deployment web --image=gcr.io/google-sample/hello-app:1.0

$ kubectl expose deployment web --type=NodePort --port=8080

$ minikube service web --url

언제 사용해야 할까?

Ingress는 아마도 서비스를 외부에 노출하는 가장 강력한 방법이겠지만 가장 복잡한 방법일 수 있다. Google Cloud Load Balancer와 Nginx, Contour, Istio 등과 같은 많은 Ingress 컨트롤러 타입이 있다. 그리고 SSL 인증서를 서비스에 자동으로 프로비저닝해주는 cert-manager 같은 Ingress 컨트롤러 플러그인도 많다.

동일한 (보통 HTTP) L7 프로토콜을 사용하는 여러 서비스들을 같은 IP 주소로 외부에 노출한다면 Ingress가 가장 유용할 것이다.

요약

5장에서는 각 서비스를 제공하는 파드 인스턴스 수에 관계없이 쿠버네티스 서비스 리소스를 생성해 애플리케이션에서 사용 가능한 서비스를 노출하는 방법을 배웠다.

  • 안정된 단일 IP 주소와 포트로 특정 레이블 셀렉터와 일치하는 여러 개의 파드를 노출한다.
  • 기본적으로 클러스터 내부에서 서비스에 액세스(ClusterIP)할 수 있지만 유형을 노드포트 또는 로드밸런서로 설정해 클러스터 외부에서 서비스에 액세스할 수 있다.
  • 파드가 환경변수를 검색해 IP 주소와 포트로 서비스를 검색할 수 있다.
  • 관련된 엔드포인트 리소스를 만드는 대신 셀렉터 설정 없이 서비스 리소스를 생성해 클러스터 외부에 있는 서비스를 검색하고 통신할 수 있다.
  • EnternalName 서비스 유형으로 외부 서비스에 대한 DNS CNAME 별칭을 제공한다.
  • 단일 인그레스로 여러 HTTP 서비스를 노출한다. (단일 인그레스 컨트롤러 IP 사용)
  • 파드 컨테이너의 레디니스 프로브는 파드를 서비스 엔드포인트에 포함해야 하는지 여부를 결정한다.
  • 헤드리스 서비스를 생성하면 DNS로 파드 IP를 검색할 수 있다.
  • 다양한 상황에서 문제 해결
  • 구글 쿠버네티스/컴퓨트 엔진에서 방화벽 규칙 수정
  • kubectl exec로 파드 컨테이너에서 명령어 실행
  • 기존 파드의 컨테이너에서 bash 셸 실행
  • kubectl apply 명령어로 쿠버네티스 리소스 수정
  • kubectl run --generator=run-pod/v1로 관리되지 않는 애드혹 파드 실행

댓글

💲 추천 글