
Service란 무엇인가?
Kubernetes 서비스는 파드의 논리적 집합과 파드에 액세스하기 위한 정책을 정의하는 추상화다. 서비스를 사용하면 응용프로그램의 다른 부분이나 외부 클라이언트에 응용프로그램의 기능을 노출할 수 있다. 서비스는 포드에 트래픽을 로드 밸런싱하는 데 사용할 수 있으며 포드에 안정적인 DNS 이름 및 네트워크 정책을 제공하는 데도 사용할 수 있다.
Kubernetes에서 서비스는 서비스 유형, 서비스가 수신해야 하는 포트 및 서비스가 대상으로 해야 하는 포드를 지정하는 YAML 파일에 의해 정의된다. 그런 다음 서비스는 로드 밸런서를 생성하고 클러스터 내부 또는 외부에서 서비스에 액세스하는 데 사용할 수 있는 안정적인 IP 주소 및 DNS 이름을 할당한다.
예를 들어, 여러 포드로 구성된 웹 애플리케이션이 있으며 각각 애플리케이션 코드의 복사본을 실행할 수 있다. 웹 응용 프로그램에 액세스하려면 포드를 외부 클라이언트에 노출하는 서비스를 만들 수 있다. 서비스는 로드 밸런서를 생성하고 안정적인 IP 주소와 DNS 이름을 할당하게되는데 이 IP 주소는 웹 브라우저에서 웹 애플리케이션에 액세스하는 데 사용할 수 있다.
요약하면, Kubernetes 서비스는 안정적인 IP 주소와 DNS 이름을 사용하여 포드 집합의 기능을 응용 프로그램의 다른 부분이나 외부 클라이언트에 노출하는 방법이며 서비스의 일부인 포드에 대한 로드 밸런싱, 안정적인 DNS 이름 및 네트워크 정책을 제공한다.
예전 Pod와 관련한 포스팅을 확인 한다면 Pod는 변경이 잦다 변경이 잦다는건 클라이언트는 모든Pod IP의 최신 상태를 알고 있어야하며
클라이언트가 특정 Pod IP로 오프라인 상태의 Pod에 접근했다면 요청은 실패 하게된다

또한 Pod IP는 클러스터 내부에서만 접근할 수있다 그렇기 때문에 클러스터 외부에서 접근할 수 있는 방법이 필요하다
우리가 파드를 확인 해보기위한 port-forward는 개발단계에서만 사용 해야한다

이러한 Pod의 한계점을 극복 하기위해 Service라는 오브젝트가 필요하다 이 Service의 역할은 Pod를 추상화 하는 특징이 있는데
풀어보자면 특정 Pod들의 단일 엔드포인트를 생성하게되고 Service와 연결되어있는 집합으로 로드밸런싱을 수행하게된다
그림으로 살펴 보자면 클라이언트가 서비스에 통신을 요청하게되고 그러면 서비스는 자신이 받은 트레픽을 자신이 관리 하고있는
파드들로 트레픽을 포워드 하게된다

또한 서비스 리소스를 생성하게되면 자동으로 쿠버네티스가 서비스의 이름과 동일한 엔드포인트를 생성하게되는데 아래의 그림으로 확인해보자면 서비스가 관리하고있는 파드들의 address를 엔드포인트라는 오브젝트가 서비스 레지스트리 역할을 하게된다 즉 엔드포인트 오브젝트에는 서비스오브젝트가 전달할 파드들의 주소목록이 적혀있다고 생각하면되겠다. 그래서 파드가 생성되고 종료되는 변경에 따라서
엔드포인트의 address목록도 변경이된다

이렇게 파드 집합에 대한 단일 엔드포인트 서비스와 통신하는 2가지 방법이 있는데
컨테이너 환경번수에 설정된 Service IP와 Port를 이용하는 방법,
Service 이름으로 DNS 서버에 쿼리하여 Service IP를 알아내는 방법이 있다

환경변수를 이용하는 방법
그림으로 얘기를 해보겠다 payment라는 서비스를 배포하게되면 쿠버네티스는 이후에생성되는 Pod들에게 환경변수로
Service IP 와 Port를 추가하게된다 예를 들어 네이밍 규칙은 <serviceName>_SERVICE_HOST, <serviceName>_SERVICE_PORT 라는 환경변수로 노출시키게된다 그렇게되면 Order Pod는 정해진 IP와 Port로
원하는 Service로 요청을 실행할 수 있게된다 하지만 주의 사항으로는 Service를 클라언트 Pod보다 먼저 생성이되야하며 다른 네임스페이스에 있는 Service 환경변수는 설정되지 않는다

DNS 서버를 이용하는 방법
쿠버네티스가 처음 클러스터를 구성할때 DNS 서버에 해당하는 Pod를 실행하게되는데 이 DNS 서버 IP를 컨테이너에 있는
/etc/resolve.conf파일에 등록을 하게된다 예를 들면 아래의 Order Pod 안에 있는 컨테이너가 payment라는 서비스이름으로
요청을 실행하게 되면 쿠버네티스에서 resolve.conf 파일에 있는 네임서버 주소를 보고 DNS서버로 쿼리하게되고 쿼리한결과로
DNS 서버에서 네임을 찾게된다면 그에 해당하는 IP를 리턴하게된다 resolv.conf 파일을 확인해보면 도메인접미사가있는데
클러스터 내부에사용되는 접미사라고 생각하면되겠다 그렇기 때문에 Service의 이름인 payment만 사용해도 resolv.conf에있는 접미사가 붙어서 DNS 서버 조회를 한다고 보면 되겠다
Survice 접근 범위에 따른 분류
Survice Type으로는 ClusterIP, NodePort, LoadBalancer 가 있으며 타입에 따라 클라이언트가 서비스에 접근할 수 있는 방식이 달라진다 또한 LoadBalancer 타입은 NodePort, ClusterIP기능을 포함한다

ClusterIP
ClusterIP는 Service에서 타입을 지정하지 않았을때 default값이다 Pod IP 처럼 외부에서 접근할 수 없는것처럼
ClusterIP도 외부에서 접근할 수 없는 IP를 할당받는다 그렇기때문에 외부에서 사용할 Pod가아니라 내부 클러스터에서만
사용한다면 서비스 타입을 ClusterIP로 선언하면되겠다 또한 선언하게되면 Internal IP만 할당이되며 External IP는 할당받지 못한다
그렇기 때문에 클러스터 외부에서 Internal IP로는 접속이 불가하며 클러스터 내부에있는 Pod에서는 접속이 가능하다

NodePort
노드에 포트를 할당해놓고 외부의 트래픽을 전달 받기위한 서비스 타입이다 Service를 보면 Cluster IP처럼 Internal IP는 할당을 받지만
External IP는 할당받지않는다 다만 노드에 외부 트래픽을 수신하기위한 노드 포트만 오픈한다고 생각하면되겠다 그렇기 때문에 노드 포트로 들어온 트래픽을 service가 전달 받게되며 받은 서비스를 Pod집합으로 포워드하는 형태이다

NodePort의 한계점
NodePort를 사용할때 클라이언트는 노드의 IP를 예약해서 사용을 하게되는데 만약 지정된 노드가 사용할 수없게된다면
클라이언트는 노드가 다운이된줄도 모르고 계속해서 요청을 보낼탠데 이요청은 계속 실패하게된다 그렇기 때문에 중간에서 건강한 상태의노드로 트래픽을 전달할 수 있도록 로드밸런서를 둬서 노드의 상태를 확인하고 건강하지않는 노드로는 요청을 보내지않는 방법을 사용하게된다.

LoadBalancer
클라우드 서비스의 Load Balancer를 프로비져닝 하고 External IP를 할당 받을 수 있게되고 아래의 그림을 확인해보면
order라는 서비스는 Internal IP 뿐만아니라 External IP 까지 할당을 받게된다 다시말해 Internal IP는 클러스터 내부 Pod의 집합과 통신을하기위한 엔드포인트로 사용되며 External IP는 클러스터 외부에서 내부 서비스로 접근 하기위한 IP로 사용된다

다음 포스팅에서는 Cluster IP를 직접 선언해서 사용해보겠다
기술 출처
서비스
파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법 쿠버네티스를 사용하면 익숙하지 않은 서비스 디스커버리 메커니즘을 사용하기 위해 애플리케이션을 수정할
kubernetes.io
'DevOps > K8s' 카테고리의 다른 글
[K8s] 쿠버네티스 livenessProbe로 파드 헬스 체크 (0) | 2023.02.14 |
---|---|
[K8s] 쿠버네티스 Deployment를 이용한 RollingUpdate (0) | 2022.12.27 |
[K8s] 쿠버네티스 Deployment의 개념 (2) | 2022.12.22 |
[K8s] 쿠버네티스 ReplicaSet의 개념 (0) | 2022.12.22 |
[K8s] 쿠버네티스 Label과 Selector (0) | 2022.12.21 |