Yebali

Kubernetes의 Service 본문

Backend Common

Kubernetes의 Service

예발이 2024. 3. 3. 23:56

Service란 Pod에서 실행되고 있는 애플리케이션을 네트워크에 노출시키는 컴포넌트이다.

보통 Pod은 일회성 자원이기 때문에 언제든 다른 노드로 옮겨지거나 삭제될 수 있다.

그때마다 Pod는 새로운 내부 IP를 부여받기 때문에 지속적으로 클러스터 내/외부와 통신을 유지하기 어렵다.

따라서 Kubernetes은 Pod가 외부와 지속적으로 통신할 수 있도록 클러스터 내부에 고정적인 IP을 가지는 Service를 사용하도록 하고 있다. 또한 같은 애플리케이션으로 구성된 여러 Pod들의 단일 진입점을 제공하는 역할을 한다.

ClusterIP

Pod들이 클러스터 내부에서 다른 리소스들과 통신할 수 있도록 단일 진입점(IP)을 제공하는 Service이다.

'ClusterIP'로 들어온 클러스터 내부 트래픽을 해당 파드의 '<Pod IP>:<targetPort>'로 매핑해 주며, 클러스터 내부에서만 접근이 가능하다.

apiVersion: v1
kind: Service
metadata:
  name: clusterip-service
spec:
  type: ClusterIP
  clusterIP: 10.100.100.100 # 이 IP를 단일 진입점으로 사용한다.
  selector:
    app: webui # 해당 label을 가진 Pod에 대해 적용
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80 # Pod에서 노출하는 Port
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webui
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx

 

NodePort

외부에서 노드의 IP와 Port로 들어오는 요청을 받아 해당 Port와 연결된 Pod로 트래픽을 전달하는 Service이다.

이때 클러스터 내부로 들어온 트래픽을 Pod로 보내기 위한 ClusterIP가 자동으로 생성된다.

apiVersion: v1
kind: Service
metadata:
  name: nodeport-service
spec:
  type: NodePort
  clusterIP: 10.100.100.100
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30200 # 이 포트를 외부에 노출한다.

 

모든 노드에서 NodePort가 생성되며 '<Node IP>:<nodePort>'로 접속하면 요청을 처리할 수 있다.

이때 nodePort로 사용할 수 있는 범위는 30000~32767이다.

 

LoadBalancer

별도로 외부 로드밸런서를 제공하는 클라우드 환경을 고려하여, 해당 로드밸런서를 클러스터의 서비스로 프로비저닝하는 Service이다.

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80 # 서비스를 노출하는 포트
      targetPort: 80 # 애플리케이션(파드)를 노출하는 포트
  clusterIP: 10.0.171.239 # 클러스터 IP
  selector:
    app: myapp
    type: frontend
status:
  loadBalancer: # 프로비저닝된 로드 밸런서 정보
    ingress:
    - ip: 192.0.2.127

 

 

ExternalName

클러스터 내부에서 selector대신 DNS name을 직접 명시할 때 쓰인다.

apiVersion: v1
kind: Service
metadata:
  name: exteralname-service
spec:
  type: ExternalName
  externalName: google.com

 

 

HeadlessService

ClusterIP가 없는 Service로 단일 진입점이나 IP가 필요하지 않을 때 사용한다.

IP는 생성되지 않지만 Service와 연결된 Pod의 endPoint로 DNS 레코드가 생성되고 Kubernetes의 Core DNS에 등록되어
DNS resorving을 할 수 있게 된다.

Pod의 DNS주소는 '<Pod-IP-Addr>.namespace.pod.cluster.local'로 생성된다.

apiVersion: v1
kind: Service
metadate:
  name: headless-service
spec:
  type: ClusterIP
  clusterIP: None # clusterIP를 None으로 해주는 것이 Headless Service이다.
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

 

➜  Desktop kubectl describe service headless-service
Name:              headless-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=webui
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.0.6:80,10.244.1.2:80,10.244.2.2:80 # Pod들의 IP
Session Affinity:  None
Events:            <none>

---
# Pod 하나 만들어서 bash 접속
➜  Desktop kubectl run -it testpod --image=centos:7 /bin/bash

# /etc/resolv.conf을 보면 요청하는 Domain Name에 default.svc.cluster.local을 자동으로 resorving 한다
[root@testpod /]# cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

---

# 아래 DNS
[root@testpod /]# curl 10-244-1-2.default.pod.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 

 

 

참고자료

- https://kubernetes.io/ko/

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

- https://www.youtube.com/watch?v=6n5obRKsCRQ&list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c

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

'Backend Common' 카테고리의 다른 글

Kubernetes의 Ingress  (0) 2024.03.16
Kubernetes의 kube-proxy  (0) 2024.03.04
Kubernetes의 Job, CronJob  (0) 2024.03.03
Kubernetes의 Pod와 Controller  (0) 2024.03.03
Kubernetes의 Control Plane와 Node, Namespace  (0) 2024.03.03