Engineering/Kubernetes (K8S)

[Kubernetes] 쿠버네티스 서비스(Service) - Deep Dive -(1)

[앙금빵] 2021. 12. 26.

1. 서비스(Service)의 필요성

 

파드가 다른 파드에게 서비스를 제공하는 서비스를 사용하려면 다른 파드를 찾는 방법이 필요하다. 일반적으로 서버의 정확한 IP 주소나 Host 이름을 지정하여 각 Application을 구성하는 것과 달리 쿠버네티스에서 동일한 작업을 수행하면 아래와 같은 문제점이 발생한다.

 

ephemeral(일시적)인 파드의 특성

Pod는 언제든 사라질 수 있으며 실행중인 노드가 실패할 수도 있고 누군가 Pod를 삭제할 수도 있고 비정상 노드에서 Pod가 제거될 수 있다.

 

만약 Deployment 서비스를 사용한다면 이러한 Pod의 비영구적인 특성으로 인해 Pod Group이 특정 시점이 지난 Pod Group과 다를 수 있다.

 

Pod는 고유한 IP주소가 있지만, 클라이언트는 서비스를 지원하는 Pod의 수와 IP에 상관하지 않아야 하며 모든 Pod는 단일 IP주소로 Access할 수 있어야 한다.

 

쿠버네티스는 이러한 문제점을 해결하기 위해 Service라는 리소스 유형을 제공한다. Service는 어떤 파드가 어디에서 존재하는지(어떤 IP를 가지는지)에 관계없이 파드 중 하나로 연결하여 요청을 처리하도록 한다.


2. 서비스(Service) 특징

 

  • 서비스가 생성되면 정적 IP를 할당받고 서비스가 존속되는 동안 변경되지 않는다.
  • 서비스는 동일한 서비스를 제공하는 하나 이상의 파드 그룹의 정적 위치를 나타낸다.
  • 서비스의 IP와 포트로 유입된 요청은 그 순간 서비스에 속해 있는 파드 중 하나에게 전달된다.

참조: kubernetes-in-action 2nd Edition

 

서비스에는 여러 종류가 있으나 주로 사용하는 서비스 타입은 크게 3가지이다.

① Cluster IP 타입
쿠버네티스 내부에서만 포드에서 접근할 때 사용한다. 외부로 Pod를 노출하지 않기 때문에 쿠버네티스 클러스터 내부에서만 사용되는 Pod에 적합하다.

② NodePort 타입
Pod에 접근할 수 있는 포트를 Cluster의 모든 Node에 동일하게 개방한다. 따라서 외부에 Pod에 접근할 수 있는 서비스 타입이다. 접근할 수 있는 포트는 랜덤으로 정해지지만 특정 포트로 접근하도록 설정할 수도 있다.

③ LoadBalancer 타입
클라우드 플랫폼에서 제공하는 Load Balancer를 동적으로 Provisioning하여 포드에 연결한다. NodePort 타입과 마찬가지로 외부에서 포드에 접근할 수 있는 서비스 타입이다. 일반적으로 AWS, GCP 등과 같은 클라우드 플랫폼 환경에서만 이용할 수 있다.


3. 서비스(Service) 접근 방법

 

서비스를 지원하는 Pod가 여러 개 일 수 있다. 서비스 연결은 서비스 뒷단의 모든 Pod로 Load Balancing이 되는데, 그렇다면 정확하게 어떤 Pod가 서비스의 일부분인지 아닌지를 정의할까?

 

바로 레이블 셀렉터(Label Selector)이다. Deployment에서 Label Selector를 통해 동일한 세트에 속하는 Pod를 지정하는 메커니즘과 같이 Service에도 그대로 사용된다.

참조: kubernetes-in-action 2nd Edition

 

ClusterIP 특징

 

① 클러스터 내부에 새로운 IP를 할당

② 여러 Pod를 바라보는 LoadBalancer 기능을 제공

③ 서비스 이름을 내부 도메인 서버에 등록하여 Pod 간에 서비스 이름으로 통신

 

ClusterIP 서비스 생성

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

yaml 파일로 jonghyun이라는 서비스를 정의하였다.

① 포트 80의 연결을 허용

② 각 연결을 app=jonghyun Label Selector와 일치하는 Pod의 포트 80으로 라우팅한다.

 

Service Yaml 파일 문법 정리

spec_type
서비스가 어떤 타입인지 나타낸다. 서비스 종류에는 ClusterIP, NodePort, LoadBalancer 등을 설정한다.

spec_selector

selector 항목은 이 서비스에서 어떠한 라벨을 가지는 Pod에 접근할 수 있게 만들지 결정한다.

spec_ports_port
생성된 서비스는 k8s 내부에서만 사용할 수 있는 고유한 IP를 할당받는다. port항목에는 서비스의 IP에 접근할 때 사용할 포트를 설정한다.

spec.ports.targetPort
selector 항목에서 정의한 Label에 의해 접근 대상이 된 Pod들이 내부적으로 사용하고 있는 Port를 입력한다.

 

root@k8s-m:~# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
jonghyun     ClusterIP   10.111.251.171   <none>        80/TCP    2m25s
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   45d

 

yaml 파일 적용 후 서비스 리소스를 조회하면 서비스에 내부 Cluster IP가 할당되었는지 확인할 수 있다.

 

클러스터 내에서 서비스 테스트

여러 방법으로 클러스터 내에서 서비스로 요청을 보낼 수 있다.

  1. 서비스의 클러스터 IP로 Request를 하고 Response를 Log로 남기는 Pod 생성
  2. k8s node로 SSH 접속 후 curl 명령 실행
  3. kubectl exec 명령어로 기존 Pod에서 curl 명령을 실행

 


참조

 

댓글