[Xshell] 오브젝트 - Service

ClusterIP, NodePort, LoadBalancer

Service의 필요성

Pod 기초에서 Service는 원하는 Pod들을 골라서 보여줄 수 있어 Pod에 Label을 달아서 사용을 한다고 했다.

이외에도 Service는 Pod의 IP만으로는 한계가 있는데 이를 해결해주는 역할을 한다.

(1) Pod IP는 신뢰성이 낮다

Pod에 문제가 생기면 system이 이를 감지해서 Pod를 삭제하고 재생성하는데 이때, IP는 변경됨 (즉, 휘발성임)

(2) Pod는 외부에서 접근이 불가능하다


Service의 종류

Service의 기본 역할: 자신한테 연결되어 있는 Pod의 트래픽을 전달

Service는 종류에 따라서 Pod에 접근하는 방식이 다르다.


종류 특징 용도
ClusterIP 외부에서 접근 못함 인가된 사용자(운영자),
내부 대쉬보드,
Pod의 서비스상태 디버깅
NodePort 실질적으로 외부에서 접근 못함 내부망 연결,
데모나 임시 연결용
Load Balancer 외부IP를 통해 외부에 Service를 안정적으로 노출 외부 시스템 노출용

NodePort의 경우, 물리적인 호스트의 IP를 통해서 Pod에 접근할 수 있지만, 호스트IP는 보안적으로 내부망에서만 접근할 수 있도록 네트워크를 구성하기 때문에 Node의 port가 클러스터 밖에 있지만 내부망에서 접근할 때 쓰임. 다만, 일시적으로 외부 연동용으로 쓰이기도 함. (내부 환경에서 시스템을 개발하다가 외부에 간단한 데모를 보여줘야할 때 네트워크 중계기에 port forwarding을 해서 외부에서 내부 시스템을 연결 하는데, 이때 Node의 port를 잠깐 뚫어놓고 쓸 수 있음.)


[1] ClusterIP

Service를 Pod에 연결을 시켜 놓으면 서비스의 IP를 통해서 Pod에 접근할 수 있음.


Pod를 생성한다.

apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  labels:
     app: pod
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node1
  containers:
  - name: container
    image: kubetm/app
    ports:
    - containerPort: 8080

Service를 생성한다. Service의 기본 타입이 ClusterIP이다.

apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080


ClusterIP로 Service를 생성 후, k8s master에서 curl로 접근할 수 있음.

curl <ClusterIP>:<Port>/hostname

Pod-1에 접근하여 hostname을 찍도록 만든 이미지로 Pod를 생성했음.


Pod-1을 삭제하고 다시 생성하면 Pod의 IP는 달라지만, Service의 Cluster IP가 동일하므로 여전히 Cluster 내부에서 Pod-1에 접근할 수 있음.


[2] NodePort

노드 포트 타입도 기본적으로 클러스터IP가 할당이 됨.

여기에서 추가로, k8s 클러스터에 연결되어 있는 모든 Node한테 똑같은 port가 할당됨.
외부로부터 어느 Node던 간에 그 IP의 포트로 접속하면, 해당 Service에 연결이 됨.


apiVersion: v1
kind: Service
metadata:
  name: svc-2
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080
    nodePort: 30000
  type: NodePort
  externalTrafficPolicy: Local


1. Node로 Pod 접근

ClusterIP로 연결할 수 있는 Port와

Node로 접근했을 때 쓸 수 있는 Port 두 개가 있다.

curl <NodeIP>:<Port>/hostname

이때, node-1의 InternalIP: 192.168.56.31
node-2의 InternalIP: 192.168.56.32

우선, Service를 만들 때 externalTrafficPolicy: Local 없이 한다면, 다른 노드의 Pod에도 접근할 수 있으며


Service는 연결되어 있는 Pod들한테 트래픽을 분산해서 전달하기 때문에 각각의 Pod에 트래픽이 분산 돼서 가는 것을 확인할 수 있다.

(Pod-2를 Node2에 하나 더 생성 후)


2. externalTrafficPolicy

externalTrafficPolicy: Local 가 있다면, 해당 Node의 Pod에만 접근이 가능하다.



[3] Load Balancer

NodePort의 성격을 그대로 가지고

여기에서 추가로, Load Balancer라는게 생겨서 각각의 Node의 트래픽을 분산시켜주는 역할을 함.
이때, Load Banlancer는 우리 실습처럼 개별적으로 kubernetes를 설치했을 때 생기지 않음.
별도의 외부 접속 IP를 할당 해주는 플러그인이 설치가 되어 있어야 IP가 생김.


apiVersion: v1
kind: Service
metadata:
  name: svc-3
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080
  type: LoadBalancer

외부IP를 할당해주는 플러그인이 설치되어 있지 않으면 EXTERNAL_IP는 pending이라고 뜸.

kubectl get service svc-3


해당 게시글은 ‘대세는 쿠버네티스 초중급편’ 강의와 ‘컨테이너 인프라 환경 구축을 위한 쿠버네티스.도커_조훈’ 도서를 바탕으로 작성하였습니다.

Categories:

Updated:

Leave a comment