서비스는 실시간으로 파드가 종료되고 생성되는 환경에서 파드 간 연결을 자동으로 가능하게 하는 리소스이다.
1. 서비스의 필요성:
2. 서비스 타입:
3. 서비스 구성 요소:

레이블을 가진 nginx 디플로이먼트 파일
nginx-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hello
namespace: default
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginxdemos/hello
[root@k8s-master01 yaml]# kubectl apply -f nginx-deploy.yml
[root@k8s-master01 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-hello-689c8f77bb-98p6p 1/1 Running 0 34s 10.1.69.214 k8s-worker02 <none> <none>
[root@k8s-master01 yaml]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-hello-689c8f77bb-98p6p 1/1 Running 0 49s app=nginx,pod-template-hash=689c8f77bb
클러스터IP 타입의 nginx 서비스
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector: # 선택해야 할 POD
app: nginx # 파드 Label과 동일
type: ClusterIP
ports:
- name: tcp
port: 80
targetPort: 80
[root@k8s-master01 yaml]# kubectl apply -f nginx-clusterIP-svc.yml
service/nginx-svc created
[root@k8s-master01 yaml]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d
nginx-svc ClusterIP 10.100.103.135 <none> 80/TCP 44s
[root@k8s-master01 yaml]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 172.16.1.38:6443 7d
nginx-svc 10.1.69.214:80 4m56s
[root@k8s-master01 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-hello-689c8f77bb-98p6p 1/1 Running 0 15m 10.1.69.214 k8s-worker02 <none> <none>
nginx-svc 라는 이름으로 클러스터IP 타입의 서비스가 생성 되었다.
셀렉터를 이용해 서비스가 생성되면 자동으로 endpoint 가 만들어진다.
endpoint 로 클라이언트가 서비스 이름 또는 clusterIP로 호출 시 도착하는 실제 파드의 IP를 확인할 수 있다.
endpoint를 확인 했을 때 nginx 파드의 IP 주소로 조회되는 것을 볼 수 있다.
서비스 디스커버리
기존 nginx pod 를 삭제하고 새로 생성되는 pod 확인
[root@k8s-master01 yaml]# kubectl delete pod nginx-hello-689c8f77bb-98p6p
[root@k8s-master01 yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 28m 10.1.69.215 k8s-worker02 <none> <none>
nginx-hello-689c8f77bb-4w6t7 1/1 Running 0 38s 10.1.79.88 k8s-worker01 <none> <none>
busybox 파드에서 연결 테스트 (서비스로 connect)
[root@k8s-master01 yaml]# kubectl exec -it busybox -- sh
/ # wget -O- nginx-svc|grep nginx-svc
Connecting to nginx-svc (10.100.103.135:80)
- 100% |******************************************************************************************************************************| 12130 0:00:00 ETA
/ #
새로 생성된 파드로 서비스 디스커버리 되는 것을 볼 수 있다. (기존 10.1.69.214 -> 10.1.79.88)
[root@k8s-master01 yaml]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 172.16.1.38:6443 7d1h
nginx-svc 10.1.79.88:80 44m
[root@k8s-master01 yaml]# kubectl get pod -o wide
nginx-hello-689c8f77bb-4w6t7 1/1 Running 0 2m43s 10.1.79.88 k8s-worker01 <none> <none>
요약하자면 새로운 파드는 기존 파드와 달리 새로운 IP 주소를 할당 받았지만 파드 간 연결은 기존과 동일하게 서비스 이름인 nginx-svc를 이용해 정상적으로 접속 된다.
레플리카 2개로 늘렸을 때
[root@k8s-master01 ~]# kubectl scale deployment nginx-hello --replicas=2
[root@k8s-master01 ~]# kubectl get endpoints
NAME ENDPOINTS AGE
nginx-svc 10.1.69.216:80,10.1.79.88:80 17h
nginx-hello-689c8f77bb-4w6t7 1/1 Running 0 16h 10.1.79.88 k8s-worker01 <none> <none>
nginx-hello-689c8f77bb-9mlw4 1/1 Running 0 8m20s 10.1.69.216 k8s-worker02 <none> <none>
cluster-IP는 가상 IP로 동작하므로 실제 파드가 삭제되고 생성되어도 클라이언트는 동일하게 서비스 이름으로 연결하면 cluster-IP를 통해 정상적으로 변경된 실제 IP 주소로 연결된다.
이처럼 쿠버네티스는 DNS를 이용해 변경되는 파드의 IP내역을 관리한다.
노드포트 타입의 서비스 생성
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport-svc
namespace: default
spec:
ports:
- name: http
port: 80
protocol: TCP
nodePort: 30080
selector:
app: nginx
type: NodePort
[root@k8s-master01 yaml]# kubectl apply -f nginx-nodeport-svc.yml
service/nginx-nodeport-svc created
[root@k8s-master01 yaml]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d18h
nginx-nodeport-svc NodePort 10.108.219.96 <none> 80:30080/TCP 17s
nginx-svc ClusterIP 10.100.103.135 <none> 80/TCP 18h
[root@k8s-master01 yaml]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 172.16.1.38:6443 7d18h
nginx-nodeport-svc 10.1.69.216:80,10.1.79.88:80 37s
nginx-svc 10.1.69.216:80,10.1.79.88:80 18h
외부에서 노드포트 서비스의 정의한 포트 30080 으로 내부 nginx 파드로 접속이 가능하다.
[root@k8s-master01 yaml]# curl 172.16.3.100:30080
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAGPElEQVR42u1bDUyUdRj/iwpolMlcbZqtXFnNsuSCez/OIMg1V7SFONuaU8P1MWy1lcPUyhK1uVbKcXfvy6GikTGKCmpEyoejJipouUBcgsinhwUKKKJ8PD3vnzsxuLv35Q644+Ue9mwH3P3f5/d7n6/3/3+OEJ/4xCc+8YQYtQuJwB0kIp+JrzUTB7iJuweBf4baTlJ5oCqw11C/JHp+tnqBb1ngT4z8WgReTUGbWCBGq0qvKRFcHf4eT/ZFBKoLvMBGIbhiYkaQIjcAfLAK+D8z9YhjxMgsVUGc84+gyx9AYD0khXcMfLCmUBL68HMZ+PnHxyFw3Uwi8B8hgJYh7j4c7c8PV5CEbUTUzBoHcU78iIl/FYFXWmPaNeC3q4mz5YcqJPI1JGKql2Z3hkcjD5EUznmcu6qiNT+Y2CPEoH3Wm4A/QERW
노드포트 서비스의 단점
1. well-known 포트의 사용이 불가능하다. (30000 ~ 32767 포트만 사용 가능)
2. 노드의 IP 중 하나를 지정해야 하므로 서비스 안정성 및 부하분산 문제가 있다.
노드 IP가 변경되면 외부 접속용 IP 도 변경해야 한다.