[k8s] Service (1)
1. 서비스란?
파드는 기본적으로 일회성이다. 기존 파드를 삭제하고 똑같은 파드를 생성해도 다른 IP를 가지게 되고 다른 노드에서 실행될 수도 있다.
파드의 IP는 스케쥴 된 이후 실행되기 전에 할당되기 때문에 미리 알기 어렵다. 이러한 불편함을 해결해주는 것이 서비스이다.
Cluster IP, NodePort, LoadBalancer, ExteralName 라는 4가지 서비스가 있다.
2. Cluster IP
타입 지정하지 않으면 사용되는 서비스로, 클러스터 내부의 파드에서는 ClusterIP를 이용해서 서비스에 연결된 파드로 접근할 수 있다.
클러스터 내부DNS를 사용하므로 외부에서는 사용할 수 없다.
클러스터를 생성하면 kube-proxy가 netfilter에 관련 rule을 생성한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: hostname-server
labels:
app: hostname-server
spec:
replicas: 2
selector:
matchLabels:
app: hostname-server
template:
metadata:
labels:
app: hostname-server
spec:
containers:
- name: hostname-server
image: takytaky/hostname
ports:
- containerPort: 80
app:hostname-server
라벨을 관리하는 디플로이먼트로 파드를 2개 생성한다. 해당 이미지의 웹페이지에는 hostname을 출력하는 구문이 있다.
apiVersion: v1
kind: Service
metadata:
name: clusterip-hostname-service
spec:
type: ClusterIP
selector:
# app=hostname-server인 파드는 이 서비스에 속함
app: hostname-server
ports:
- protocol: TCP
# ClusterIP는 80포트를 리스닝
port: 80
# 파드의 80포트로 포워딩
targetPort: 80
그리고 이 파드들을 하나로 묶어주는 Cluster IP를 생성한다.
생성한 내용들을 확인한다.
root@master:~/k8s_lab/service# kubectl get svc,deploy,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/clusterip-hostname-service ClusterIP 10.107.188.211 <none> 80/TCP 17m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hostname-server 2/2 2 2 17m
NAME READY STATUS RESTARTS AGE
pod/hostname-server-7c85cc96dc-hrjt4 1/1 Running 0 17m
pod/hostname-server-7c85cc96dc-ttmmw 1/1 Running 0 17m
해당 Cluster IP로 페이지 요청을 보내 호스트 이름을 확인하면 다음과 같이 2개의 파드가 응답하는 것을 볼 수 있다.
root@master:~# curl -sf http://10.107.188.211 | grep Hello
<p>Hello, hostname-server-7c85cc96dc-hrjt4</p> </blockquote>
root@master:~# curl -sf http://10.107.188.211 | grep Hello
<p>Hello, hostname-server-7c85cc96dc-ttmmw</p> </blockquote>
웹서비스의 세션을 유지하기 위해서는 spec.sessionAffinity
에 ClientIP
를 주면 된다.
3. NodePort
NodePort 서비스에 클러스터의 노드의 IP주소에 공개포트가(30000~32767) 열려 클러스터 외부에서도 요청을 보낼 수 있게 된다.
NodePort는 ClusterIP를 사용해 pod들에게 트래픽을 분산하기 때문에 자동으로 ClusterIP가 생성된다.
apiVersion: v1
kind: Service
metadata:
name: nodeport-hostname-service
spec:
type: NodePort
selector:
# app=nginx-app 인 파드들이 이 서비스에 속함
app: nginx-app
ports:
- protocol: TCP
# 노드의 30080포트로 요청을 받음
nodePort: 30080
# ClusterIP는 80포트를 리스닝
port: 80
# 파드의 80포트로 포워딩
targetPort: 80
위와 같이 NodePort 서비스를 만들면 클러스터의 모든 노드들의 30080포트가 열린다. 외부에서 아무 노드의 30080포트로 요청을 보내면 요청을 받은 노드는 트래픽을 자신의 파드 혹은 다른 노드의 파드에게 라우팅해준다.
댓글남기기