[Kubernetes] Service

김동주·2024년 5월 19일

Service
Kubernetes 서비스란 파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출시키는 것을 의미한다.
쿠버네티스는 파드에게 고유한IP 주소와 파드 집합에 대한 단일 DNS 명을 부여하고, 그것들 간에 로드-밸런스를 수행할 수 있다.
서비스는 seletor를 사용해서 pod의 label을 찾고 뒷단으로 연결시키기 때문에 만약 다른 pod에서 만ㄷ는 컨테이너의 label 이 셀렉터에서 찾는 label 과 같다면 서비스의 뒷단에 연결해버린다.
Service Type에는 총 4가지 종류가 있다.

Service Type

  • ClueterIP(default)
    • Pod 그룹의 단일 진입점(Virtual IP) 생성
  • NodePort
    • ClusterIP가 생성된 후
    • 모든 Worker Node에 외부에서 접속가능 한 포트가 예약
  • LoadBalancer
    • 클라우드 인프라스트럭처(AWS, Azure, GCP 등)나 오픈스택 클라우에 적용
    • LoadBalancer를 자동으로 프로 비전하는 기능 지원
  • ExternalName
    • 클러스터 안에서 외부에 접속 시 사용할 도메인을 등록해서 사용
    • 클러스터 도메인이 실제 외부 도메인으로 치환되어 동작

NodePort, LoadBalancer: 클러스터 외부에 노출하기 위한 것
ClusterIP: 클러스터 내부에서 사용하기 위한 것

1. Service - ClusterIP
Deploymnet Pod 생성 yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 3
  selector:
    matchExpressions:
      - key: app
        operator: In
        values:
          - nginx
      - key: env
        operator: Exists
  template:
    metadata:
      labels:
        app: nginx
        env: dev
    spec:
      containers:
        - name: nginx
          image: nginx:1.14
          ports:
            - containerPort: 8080
              protocol: TCP

ClusterIP Service 생성

apiVersion: v1
kind: Service
metadata:
  name: clusterip-svc
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP

kubectl get svc,ep,rs,pod명령어를 통해 확인

2. Service - nodePort
NodePort의 범위: 30000-32767
모든 노드를 대상으로 외부 접속 가능한 포트를 예약
ClusterIP를 생성 후 NodePort를 예약

NodePort Service 생성 yaml

apiVersion: v1
kind: Service
metadata:
  name: nodeport-svc
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
      nodePort: 30200

Node Port가 열린 모습을 확인할 수 있다.

kubectl expose deployment 명령어를 통해 바로 NodePort Service를 함께 생성할 수 있습니다.

3. Service - LoadBalancer

  • Public환경(AWS,Azure,GCP등)에서는 클라우드의 로드밸런서를 사용할 수 있지만 Private환경에서는 별로의 로드밸런서 장비를 사용한다. 그래서 MetalLB라는 온프레미스 환경(IDC)에서 사용할 수 있는 서비스(로드밸런서 타입)를 이용합니다.

하지만 왜 쿠버네티스에서 LoadBalancer를 사용할까?

  • Pod는 휘발성을 가져 불안정하다는 특징을 가지고 있다. 그래서 고정된 엔드포인트를 가지기 힘들다. 그래서 Pod는 상황에 따라 소멸-재생성을 반복한다. 그래서 고정된 IP를 가지기 힘들어 엔드포인트로 호출이 어렵다. 그래서 이러한 Pod의 불안정성을 보완하기위해 LoadBalancer 를 사용한다.

  • LoadBalancer를 사용하기 위해선 External IP를 생성해주어야 한다.

LoadBalancer Service 생성 yaml

apiVersion: v1
kind: Service
metadata:
  name: LoadBalancer-svc
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP

metalLB를 구축하지 않은채 Service를 올리면 외부와 통신할 로드밸런서 장비가 없어 영원히 Pending상태로 있을 것이다.

4. Service - ExternalName

  • 클러스터 내부에서 External(외부)의 도메인을 설정

ExternalName Service 생성 yaml

apiVersion: v1
kind: Service
metadata:
  name: externalname-svc
spec:
  type: ExternalName
  externalName: google.com

외부 IP
ExternalIP Service 생성 yaml

kind: Service
metadata:
  name: externalip
spec:
  selector:
    app: App
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8178
  externalIPs:
    - 90.11.23.10

DNS가 아닌 IP이용 방식 --> 실습해보자
내부에서는 ClusterIP를 지정할 수 있는 것처럼 외부에서도 직접 IP 주소를 주기위하여 Endpoints설정을 해준다.

apiVersion: v1 
kind: Service
metadata:
  name: external-svc-nginx
spec:
  ports:
    - port: 80
---------------------------
apiVersion: v1 
kind: Endpoints
metadata:
  name: external-svc-nginx
subsets:
  - addresses:
    - port: 35.224.32.125
    ports:
    - ports: 80

Service 특징

  • multi-port 지원
    Service는 하나의 포트가 아니라 여러 포트를 동시에 지원한다. 대표적으로 HTTP와 HTTPS포트를 들 수 있다.
apiVersion: v1
kind: Service
metadata:
  name: multi-port-svc
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080
	  protocol: TCP
      name: http
    - port: 443
      targetPort: 8081
      protocol: TCP
      name: https
  • 로드 밸런싱 알고리즘(sessionAffinity)
    보통 Pod가 여러개 있으면 특정 Pod가 아닌 여러 Pod에 랜덤으로 부하분산을 한다. 하지만 특정 부하분산이 아닌 특정 Pod에만 지속적인 연결을 하고싶을 때 Session Affinity를 사용한다.
    다음과 같이 sessionAffinity: ClientIP로 설정한다.
apiVersion: v1
kind: Service
metadata: sessionAffinity
  name: 
spec:
  type: ClusterIP
  sessionAffinity: ClientIP
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080

type: loadbalancer도 가능
웹에서 HTTP Session을 사용하는 경우와 같이 각 서버에 각 클라이언트의 상태정보가 저장되어 있는 경우에 유용하게 사용

참조 URL
https://bcho.tistory.com/1262
https://ssunw.tistory.com/entry/Service-Ingress
kubernets 공식 문서

profile
더욱 더 발전된 엔지니어가 되기 위한 개인 공부 블로그(DevOps/Cloud)

0개의 댓글