티스토리 뷰
About Service(1), Basic Concept
Date: Nov 15, 2019 5:19 PM
State: Writing
Basic Concept
Outline
클라이언트에서 실제 비즈니스 로직을 처리하는 Pod 들 사이에는 서비스가 있다. 클라이언트가 서비스의 아이피로 접근해 요청을 하면 서비스는 그 요청을 적절히 Pod에게 배분해준다.
-
이러한 업무 처리 방식은 클라이언트가 Pod의 아이피를 알 필요가 없게 만든다. 그런데 놀라운 것은 서비스도 Pod의 아이피를 몰라도 운영하는데 문제가 없다.
-
기존에 쿠버네티스를 사용하지 않는 환경에서는 3 Tier 기준으로 Web Server, WAS, DB 모두에 IP를 명시해줘야 한다. 물론 여기에 방화벽과 IPS, DDOS 등의 장비들이 더해지면 더욱 IP를 명시해주는 부분이 많아질 것이다.
-
이처럼 IP는 잘 파악 되고 있어야 하는 존재였다.
-
이와달리 쿠버네티스에서는 IP를 명시하지 않는다. 명시를 하지 않는 이유는 다음과 같다.
- Pod는 수명이 짧다 — Pod는 언제든 생겼다가 사라질 수 있는 존재이다. 갑작스런 장애가 발생했을 때는 삭제되어 다른 노드에서 새롭게 생겨 날 수 있고, 관리자의 판단에 따라 replica count를 줄여 운영하는 Pod의 숫자를 줄일 수도 있다.
- Pod의 IP 할당 시점 — Pod는 생성과 동시에 아이피가 할당 되는 것이 아닌 특정 노드에 배정되었을 때 할당 받게 되기 때문에 지속적으로 명확히 파악하여 관리할 수 없다.
- 수평적 확장에 따른 Pod 현황 파악의 어려움 — 클라이언트는 서비스의 뒷 편에 위치한 수 많은 포드들과 또 그 포드들의 아이피를 모두 관리 할 수 없다. 그렇기 때문에 해당 포드들을 모두 접근할 수 있는 하나의 서비스 아이피를 제공하여 서비스를 받을 수 있도록 한다.
-
Definition
포드들의 입구의 역할을 하며, IP 및 PORT를 배정받으면 별도로 수정하지 않는 이상 존재하는 동안 변경되지 않는다. 클라이언트가 서비스에 접속을 시도하면 서비스의 뒷편에 있는 Pod와 연결을 시켜준다. 이러한 방식으로 인해 클라이언트는 개별 Pod의 위치에 대해 알 필요가 없어지고, Pod는 노드 클러스터 내부에서 자유롭게 이동할 수 있게 된다.
Example
위 사진은 쿠버네티스 인 액션에서 발췌한 사진이다. External Client(외부 고객) 입장에서는 프론트엔드 서비스의 아이피만 만 알면 뒷편에 위치한 프론트엔드 포드의 수와 아이피를 몰라도 요청을 할 수 있다.
-
그리고, 프론트 엔드의 포드들의 백엔드 서비스의 아이피만 알면 뒷편에 위치한 백엔드 포드의 수와 아이피를 몰라도 요청을 할 수 있다.
-
이처럼 알아야 하는 정보의 양을 줄여주고, 결합도를 최소화하며, 단순화 해주는 것이 이번 글에서 설명하는 서비스의 특성이자 쿠버네티스란 명작의 특성이다. 이러한 특성은 이후에 작성될 글에 서도 느낄 수 있을 것이다.
-
그럼 이제 간단한 서비스를 만들어보도록 하겠다.
-
Exampe1-Basic Service
apiVersion: v1
kind: Service
metadata:
name: dev-svc-jordy
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: jordy
# jordy-svc.yaml
-
apiVersion: v1
kind: Pod
metadata:
name: jordy
labels:
app: jordy
spec:
containers:
- image: bearstark/jordy
name: jordy
ports:
- containerPort: 8080
protocol: TCP
# jordy-pod.yaml
-
apiVersion: v1
kind: Pod
metadata:
name: jordy2
labels:
app: jordy
spec:
containers:
- image: bearstark/jordy
name: jordy
ports:
- containerPort: 8080
protocol: TCP
# jordy-pod2.yaml
위 코드는 서비스와 이름이 다른 포드 2개를 생성하기 위한 yaml 이다. 코드를 따라 치고, 파일명은 주석을 참조하여 짓는다.
-
O YAML을 통한 컴퍼넌트 생성 명령어
kubectl create -f <fileName.fileExtension>
-
위 CREATE 명령어는 이제 많이 익숙해졌을 것이다.
그 후에 아래 명령어를 실행하고 결과를 확인 해보자.
-
O 전체 Pod 목록 조회
kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
jordy 1/1 Running 0 2m54s app=jordy
jordy2 1/1 Running 0 2m28s app=jordy
-
O 전체 서비스 목록 조회
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dev-svc-jordy ClusterIP 10.51.254.18 <none> 80/TCP 111s
kubernetes ClusterIP 10.51.240.1 <none> 443/TCP 21d
-
Pod 2개와 서비스 1개가 생성되었다.
Pod 2개 모두 Label이 app=jordy 로 설정 되어 있는데, 서비스의 셀렉터는 두 포드를 가리키도록 셀렉터에 app=jordy라고 입력되어있을까?
서비스의 상세 정보를 확인해보자.
-
O 특정 서비스 상세 조회
kubectl describe <kind of component> <component name>
kubectl describe services dev-svc-jordy
Name: dev-svc-jordy
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=jordy
Type: ClusterIP
IP: 10.51.254.18
Port: <unset> 80/TCP
TargetPort: 8080/TCP
Endpoints: 10.48.1.19:8080,10.48.2.33:8080
Session Affinity: None
Events: <none>
상세조회한 결과 selector가 app=jordy로 나온다. 또한 이 서비스의 클러스터 아이피가 10.51.254.18로 나온다. 이 클러스터 아이피는 클러스터 내부 아이피로 외부 접근인 Putty에서는 ping 혹은 curl를 날려도 응답을 받을 수 없다.
-
그래서 아래 yaml 노드js 이미지의 Pod를 생성하는데, 해당 이미지로 Pod 생성시 가동된 후에 처리하는 로직 따위가 없으므로 곧바로 종료되기 떄문에 sleep 명령어를 통해 계속해서 살아있도록 했다.
apiVersion: v1
kind: Pod
metadata:
name: diff-jordy
labels:
app: node
spec:
containers:
- image: node
name: diff-jordy
ports:
- containerPort: 8080
protocol: TCP
command: ["/bin/bash","-c", "--"]
args: [ "while true; do sleep 30; done;" ]
그 후에 exec 문을 활용해 특정 Pod로 접근해서 curl 날려보자.
-
kubectl exec <pod name> -- curl <cluster-inner-ip>
-
그러면 아래 응답 중 하나를 받을 수 있다.
you`ve hit jordy
you`ve hit jordy2
-
두 반응이 번갈아 나오는 이유는 서비스 자체가 로드밸런싱을 지원하므로 요청을 두 Pod에 나누어 반응하게끔 하기 떄문이다.
-
서비스의 YAML에 sessionAffinity를 설정하면 아이피 기반으로 세션이 생성 중인 Pod에 연결되게끔 하는 옵션을 줄 수도 있다.
...
spec:
clusterIP: 10.51.254.18
sessionAffinity: clientIp
...
-
다음 글에서 서비스에 대해 더 알아보도록 하겠다.
'Infra > Kubernetes' 카테고리의 다른 글
About Service(3), Exposing svc to external clients (0) | 2019.11.24 |
---|---|
About Service(2), Basic Concept 2 (0) | 2019.11.23 |
검색어 필터링 후 컴포넌트 삭제 Deleting components which are filtered by search text (0) | 2019.11.15 |
About Daemon Set (2) | 2019.11.12 |
About Replication Controller (0) | 2019.11.08 |
- Total
- Today
- Yesterday
- Delete
- kubernetes
- POD
- JVM
- 자바 메모리 구조
- Replication Controller
- Effective Java
- JMM
- Java
- k8s
- Java Memory Structure
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |