본문 바로가기

Docker & Kubenetes

Kubernetes Service

각 Pod 들은 Kubernetes Cluster 내에서만 유효한 가상의 IP를 부여받고 같은 Cluster 내 Pod들 끼리 통신이 가능하다.

예를 들면, Pod A 에서 Pod B로 통신 중에 에러에 의해 재기동 되면 Node 2 에 생성이 될 수도 있는데 이때 Pod B에는 새로운 IP가 부여된다.

Pod A의 입장에서는 Pod B와 통신하려면 Pod B의 IP를 알아야 통신이 가능하기 때문에 관리자가 Pod A에 등록되어 있는 Pod B의 IP 주소를 수정해줘야 통신이 가능하다. 또한 Pod의 IP는 가상의 IP로 Cluster 내부에서만 유효하기 때문에 외부 클라이언트가 접근하지 못한다. 즉 APP을 Pod로 배포해도 접근이 안되기 때문에 사용을 못하는 것이다.

이러한 불편함 때문에 SVC(Service)를 사용하여 매번 바뀌는 Pod의 IP 대신 Service 를 거쳐 통신하도록 하여 Pod간 통신이나 외부에서 Pod로 접근하기 편하게 구현한다.

Service는 하나의 Deployment를 네트워크에 공개하며, Deployment에는 하나의 로직을 수행하는 Pod나 Replica들이 묶여있다. Deployment는 Deployment안의 Pod들의 IP는 계속 변하지만 하나로 묶여 변하지 않는 IP를 제공하고 해당 IP를 가지고 다른 Pod에서 통신이 가능하다.

 

즉, 외부에서는 IP를 계속 추적할 필요 없이 서비스IP 하나만 기억하면 되며 서비스에서 Pod들 사이에 로드 밸런싱 기능을 제공하여 가장 여유로운 Pod와 연결된다(로드 밸런싱 알고리즘에 따라 달라지기도 한다)

 

서비스를 통해 외부로 부터 접근이 가능하게 만들기도, 내부에서만 접근 할 수 있도록 할 수도 있다.

 

서비스에 의해 공개되는 Pod들의 IP는 endpoints 라는 리소스로 관리되는데 서비스는 endpoints로 등록된 Pod 들에 트래픽을 보내게 되며 endpoints를 관리하는 컨트롤 플레인의 Endpoints Controller가 endpoints 들을 관리하며 endpoint의 추가, 제거 등을 수행한다.

 

Lable을 기반으로 Pod들을 묶어서 애플리케이션을 Export 시키는 Virtual IP를 생성한다.

해당 Service에 매핑된 Pod들의 IP는 ETCD에 저장되고 Virtual IP를 통해 진입하면 매핑된 Pod들에게 로드밸런싱을 제공하여 안정적인 운영환경을 제공한다.

이를 Service API라고 한다.

7-1. 쿠버네티스 Service 개념과 종류 강의 중

Deployment YAML파일에 label을 적용하여 Pod에 app:webui라는 Label을 지정해 준다.

Service YAML 파일에는 app:webui 라는 label을 갖고 있는 Pod에 80포트로 로드밸런싱 해주고, Virtual IP는 10.96.100.100으로 생성한다.

Service Type

Cluster IP

Private LoadBalancer로 ClusterIP는 클러스터 내부에서만 접근 가능한 서비스다.

서비스에 의해 관리되는 Pod들에 접근할 수 있고 kube-proxy를 통해 클라이언트를 클러스터 내에 있는 특정 Pod로 연결할 수 있으며 트래픽을 특정 파드로 전달하는 역할을 수행한다.

selector의 label이 동일한 Pod들을 묶어 Virtual IP을 생성한다.

클러스터 내부에만 사용 가능하고 IP할당 생략 시 10.96.0.0/12 범위에 랜덤하게 생성된다.

쿠버네티스가 지원하는 기본적인 형태의 서비스다.

 

만약 YAML파일을 작성한다면 아래와 같다.

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: ClusterIP		# 생략 가능
  ports:
  - protocol: TCP
    targetPort: 9376	# 애플리케이션(파드)을 노출하는 포트
    port: 80		# 서비스를 노출하는 포트
  selector:		# 이 서비스가 적용될 파드 정보를 지정 (선택이나 권장 사항)
    app: crong
    type: frontend

만약, 여러 개의 포트 적용이 필요할 땐 어떻게 해야할까??

이런 경우는 spec.ports에 리스트 형태로 추가해주면 된다. 이때 name의 처음과 끝 값은 영문/소문자 및 숫자 이어야 한다.

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: ClusterIP
  ports:
  - name: http
    protocol: TCP
    targetPort: 9376
    port: 80
  - name: https
    protocol: TCP
    targetPort: 9377
    port: 443
  selector:
    app: crong
    type: frontend

NodePort

NodePort는 클러스터의 모든 워커 노드에 포트를 통하여 자신을 노출시킬 수 있다.

Port Forwarding을 생각하면 되며, 외부 네트워크에 연결된 노드의 특정 포트를 통해 트래픽이 들어오면 서비스에 의해 특정 Pod로 트래픽을 전달할 수 있다.

내부적으로 ClusterIP 유형을 사용하기 때문에 특정 포트로 트래픽이 들어오면 클러스터에 속한 아무 워커노드로 들어와도 특정 Pod로 전달된다.

외부에서 워커노드의 IP를 알고 있어야 하며 해당 노드가 고장나게 되면 클러스터에 접근할 수 없으며, 로드밸런싱이 되지않아 트래픽이 몰릴 수 있다는 단점이 있다.

출처 : Google Cloud

LoadBalancer

LoadBalancer를 자동으로 프로 비전하는 기능 지원, 권한이 있어야 생성 가능하다.

Public 클라우드에서만 운영 가능하며 물리적 장비와 연동하여 사용할 수 있다. LoadBalancer는 내부는 NodePort 유형을 사용하고, 외부는 물리적 Load balancer 장비나 MetalLB와 같은 소프트웨어 레이어를 추가한 것이다

외부에서 접근가능한 IP를 제공하고, 이 IP로 들어온 트래픽을 내부적으로 사용되는 NodePort 서비스로 전달한다. NodePort는 들어온 트래픽을 다시 내부의 IP 서비스를 통해 최종적으로 파드에게 전달한다.

ExternalName

서비스에 selector 대신 DNS name을 직접 명시할 때 사용한다.

spec.externalName 항목에 필요한 DNS 주소를 기입하면, 클러스터의 DNS 서비스가 해당 주소에 대한 CNAME 레코드를 반환한다.

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: prod
spec:
  type: ExternalName
  externalName: crongblog.tistory.com

 

 

 

출처 : 

https://seongjin.me/kubernetes-service-types/

 

쿠버네티스에서 반드시 알아야 할 서비스(Service) 유형

파드는 특성상 생성될 때마다 내부 IP 주소가 계속 변화하게 된다. 쿠버네티스의 서비스(Service)는 이러한 파드에 탑재된 애플리케이션이 외부와 상호 통신이 가능하도록 만들어준다. 이번 글에

seongjin.me

https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0

 

Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

Recently, someone asked me what the difference between NodePorts, LoadBalancers, and Ingress were. They are all different ways to get…

medium.com