Pod
Pod은 쿠버네티스에서 관리하는 가장 작은 배포 단위이다. Docker와 비교해보면, Docker는 컨테이너를 만들지만 쿠버네티스에서는 Pod을 바탕으로 컨테이너를 관리한다. 또한, Pod에는 여러개의 컨테이너를 포함할 수 있다.
일반적으로 쿠버네티스는 YAML 설정파일을 만들어서, 작업을 하기 때문에 이를 통해 Pod을 만들어 보자.
아래 조건의 Pod을 만들자.
apiVersion: v1
kind: Pod
metadata:
name: mongodb
labels:
app: mongo
spec:
containers:
- name: mongodb
image: mongo:4
해당 Pod을 생성하고, 조회 해보자.
# Pod 생성
kubectl apply -f echo-pod.yml
# Pod 목록 조회
kubectl get pod
이러한 Pod은 아래와 같은 내부 로직을 통해서 생성되며, 관리된다.
Scheduler는 할당되지 않은 Pod을 찾고, node인 minikube에 할당한다. node 안에 kubelet이 할당된 Pod을 생성하게 된다.
작은 서비스가 각자의 역할을 충실히 하는 마이크로 서비스의 끝판왕이다.
쿠버네티스는 컨테이너가 계속해서 서비스를 할 수 있도록, 체크하는 livenessProbe, readinessProbe를 통해 Pod 내부의 컨테이너를 관리할 수 있다.
livenessProbe는 Get 방식으로 요청을 해당 서비스에 보내, Health를 체크하는 방식이며, readiness는 컨테이너가 서비스가 되지 않으면 Pod으로 들어오는 요청을 제외하는 방식이다. 보통 livenessProbe와 readinessProbe를 함께 쓰는 전략을 활용하며, 환경에 따라 적절하게 조정할 수 있다.
둘다 YAML 설정 파일의 Spec 부분에 추가하고 Pod을 생성하면 된다.
apiVersion: v1
kind: Pod
metadata:
name: mongodb
labels:
app: mongo
spec:
containers:
- name: mongodb
image: mongo:4
livenessProbe:
httpGet:
path: /
port: 3000
readinessProbe:
httpGet:
path: /
port: 3000
쿠버네티스의 Pod은 다중 컨테이너가 들어갈 수 있는데 (예: app, db) 이렇게 한다면, app이 localhost로 db에 접근할 수 있는 구조가 된다.
컨테이너 간의 네트워크가 같은 Pod에 있기 때문에 가능하며, 쿠버네티스가 네트워크를 알아서 세팅해준다(진짜 좋다..)
ReplicaSet
일반적으로 Pod 단독으로 구성하지 않고, Deployment와 ReplicaSet을 바탕으로 Pod을 관리한다. ReplicaSet은 Pod을 정해진 수 만큼 복제하고 관리하게 해준다. ReplicaSet을 구성하면 Pod은 자동으로 만들어지며, 쉽고 간단하게 Pod을 복구하는 기능을 갖출 수 있다.
exam2.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: mongodb
spec:
replicas: 3
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongodb
image: mongo:4
여기 spec의 selector는 Pod을 체크하는 label의 조건이며, replicas는 원하는 pod개수, template는 Pod의 명세인데, 앞선 Pod 생성 yml 파일과 똑같다.
kubectl get po,rs를 하면, replicaset.apps/mongodb로 ReplicaSet과 함께 mongodb가 생성된 것을 확인할 수 있다.
spec에서 정의한 replicas:3을 맞추기 위해서 추가로 2개의 Pod을 띄운 것을 확인할 수 있다.
ReplicaSet은 원하는 개수의 Pod을 유지한다. 여기서 주의해야 할 점은 Pod의 Label을 이용하여 Pod을 체크한다. Label을 다시 확인하기 위해서 kubectl get pod --show-labels를 입력해보자.
yml 파일의 spec에서 정의한 selector에 따라서, RelicaSet Controller는 API와 통신하며 정의한 Replicas의 개수와 맞는지 체크하고, 이와 다르면 새로운 Pod을 복제하여 Pod의 개수를 유지해준다. 따라서, label이 겹치지 않게 신경써줘야 한다.
하지만, 실전에서 ReplicaSet을 단독으로 쓰지 않고, 앱의 버저닝을 관리할 수 있도록 하는 Deployment라는 Object로 관리한다.
Deployment
exam3.yml
yml 파일의 변화가 kind에서 replicaSet에서 Deployment object로 변경되었다. 또한, metadata의 이름이 mongodb-deploy로 바꾸었다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deploy
spec:
replicas: 3
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongodb
image: mongo:4
똑같이, apply -f로 실행하고, kubectl get all
deployment object는 Pod을 업데이트하거나 이력을 관리할 수 있다. 특히, 특전 버전으로의 롤백, 무중단 배포를 하는 롤링 업데이트 방식을 사용할 수 있다.
여기서 이미지 태그를 변경하여 다시 deploy 해보자. 기존 mongodb-deploy가 순차적으로 업데이트 되었다 (이때, 업데이트가 아니라 제거하고 새로운 버전의 Pod을 생성한 것임)
이때 내부적으로 Ver2의 ReplicaSet을 생성하고, 기존 replicaset에 존재하는 Pod을 하나씩 제거하고, 새로운 Pod을 Ver2의 ReplicaSet으로 생성하는 작업을 한다. 즉, 롤링 업데이트를 진행한다. 이러한 점은 kubectl describe deploy/mongodb-deploy를 통해서 확인할 수 있다.
Scaled up 혹은 Scaled Down을 통해서 replica set 사이의 Pod이 생성되고, 제거된다.
또한, Deployment는 상태를 기록하고 있어, 이전의 버전으로 롤백 혹은 특정 버전으로 롤백이 가능하다.
kubectl rollout history deploy/mongodb-deploy
특정 버전으로 롤백은 아래와 같이 입력하면 된다.
kubectl rollout undo deploy/mongodb-deploy --to-revision=2
'블로그 > 데이터 엔지니어링' 카테고리의 다른 글
[K8s] 쿠버네티스 알아보기 (0) | 2024.01.17 |
---|---|
[K8s] 왜 쿠버네티스일까? (0) | 2024.01.17 |
[k8s] 컨테이너 오케스트레이션 등장과 개념 (0) | 2024.01.17 |
GA4와 Bigquery로 행동 로그 쌓기 삽질하며 배운 점 (0) | 2022.05.22 |