0과 1을 공부하다.

[Kube] Kubernetes - Pod (5) 본문

Study/Server

[Kube] Kubernetes - Pod (5)

Developer_Jay 2024. 7. 22. 00:44
728x90

 

본 게시글은 인프런 subicura 강사님의 초보를 위한 쿠버네티스 안내서 강의 수강 후 작성한 내용입니다.


Pod 이란 ?

  • Pod은 쿠버네티스에서 관리하는 가장 작은 배포 단위
  • 쿠버네티스와 도커의 차이점은 도커는 컨테이너를 만들지만 쿠버네티스는 컨테이너 대신 Pod을 만듬.
  • Pod은 한개 또는 여러 개의 컨테이너를 포함함.

Pod 생성 맛보기

  • 저장소에 저장된 이미지로 Pod 만들기
# Pod 생성
$ kubectl run echo --image ghcr.io/subicura/echo:v1

# 생성된 Pod 보기
$ kubectl get pod/echo

# Pod의 상세내용 보기
$ kubectl describe pod/echo

# echo의 로그 보기
$ kubectl logs -f echo

# echo 컨테이너 접속
$ kubectl exec -it echo -- sh

# Pod 제거
$ kubectl delete pod/echo

 

  • YAML로 Pod 생성하기
apiVersion: v1
kind: Pod
metadata:
  name: echo
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1

 

version, kind, metadata, spec는 리소스를 정의할 때 반드시 필요한 요소이다.

 

  • 정의 설명 예
version 오브젝트 버전 v1, app/v1, networking.k8s.io/v1, ...
kind 종류 Pod, ReplicaSet, Deployment, Service, ...
metadata 메타데이터 name과 label, annotation(주석)으로 구성
spec 상세명세 리소스 종류마다 다름
# Pod 생성
$ kubectl apply -f echo-pod.yml

# 생성된 Pod 보기
$ kubectl get pod/echo

# Pod의 상세내용 보기
$ kubectl describe pod/echo

# echo의 로그 보기
$ kubectl logs -f echo

# echo 컨테이너 접속
$ kubectl exec -it echo -- sh

# Pod 제거
$ kubectl delete pod/echo

컨테이너 상태 모니터링

livenessProbe

  • 컨테이너가 정상적으로 동작하는지 체크하고 정상적으로 동작하지 않는다면 컨테이너를 재시작하여 문제를 해결한다.
  • 정상이라는 것은 여러 가지 방식으로 체크할 수 있는데 아래 예시에서는 http get 요청을 보내 확인하는 방법을 사용한다.
apiVersion: v1
kind: Pod
metadata:
  name: echo-lp
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1
      livenessProbe:
        httpGet:
          path: /not/exist # 고의적으로 존재하지 않는 path 기입
          port: 8080 # 고의적으로 존재하지 않는 포트 기입
        initialDelaySeconds: 5
        timeoutSeconds: 2 # Default 1
        periodSeconds: 5 # Defaults 10
        failureThreshold: 1 # Defaults 3
# Pod 생성
$ kubectl apply -f echo-pod.yml

# 생성된 Pod 보기
$ kubectl get pod/echo

# ---- 
# 정상적으로 응답하지 않기 때문에 CrashLoopBackOff 상태로 변경된다.
NAME      READY   STATUS             RESTARTS     AGE
echo-lp   0/1     **CrashLoopBackOff**   2 (8s ago)   23s
#-----

# Pod 제거
$ kubectl delete pod/echo

 

 

readinessProbe

  • 컨테이너가 준비되었는지 체크하고 정상적으로 준비되지 않았다면 Pod으로 들어오는 요청을 제외한다.
  • livenessProbe와 차이점은 문제가 있어도 Pod을 재시작하지 않고 요청만 제외한다는 점이다.
apiVersion: v1
kind: Pod
metadata:
  name: echo-rp
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1
      readinessProbe:
        httpGet:
          path: /not/exist # 고의적으로 존재하지 않는 path 기입
          port: 8080 # 고의적으로 존재하지 않는 포트 기입
        initialDelaySeconds: 5
        timeoutSeconds: 2 # Default 1
        periodSeconds: 5 # Defaults 10
        failureThreshold: 1 # Defaults 3
# Pod 생성
$ kubectl apply -f echo-pod.yml

# 생성된 Pod 보기
$ kubectl get pod/echo

# ---- 
# pod을 재시작하지 않고 제외한다. (READY 0)
NAME      READY   STATUS    RESTARTS   AGE
echo-rp   0/1     Running   0          16s
#-----

# Pod 제거
$ kubectl delete pod/echo

 

 

livenessProbe + readinessProbe

  • 보통 livenessProbe와 readinessProbe를 같이 적용한다.
  • 상세한 설정은 애플리케이션 환경에 따라 적절하게 조정한다.
apiVersion: v1
kind: Pod
metadata:
  name: echo-health
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1
      livenessProbe:
        httpGet:
          path: /
          port: 3000
      readinessProbe:
        httpGet:
          path: /
          port: 3000

다중 컨테이너

pod은 여러개의 컨테이너를 가질 수 있다.

apiVersion: v1
kind: Pod
metadata:
  name: counter
  labels:
    app: counter
spec:
  containers:
    - name: app # app 컨테이너
      image: ghcr.io/subicura/counter:latest
      env:
        - name: REDIS_HOST
          value: "localhost"
    - name: db # DB 컨테이너
      image: redis
# Pod 생성
$ kubectl apply -f echo-pod.yml

# Pod 목록 조회
$ kubectl get pod

# ------
# 2개의 컨테이너가 실행됨.
NAME      READY   STATUS    RESTARTS   AGE
counter   2/2     Running   0          27s
# ------

# Pod 로그 확인
$ kubectl logs counter app
$ kubectl logs counter db

# 컨테이너 접속
$ kubectl exec -it counter -c app -- sh

$ curl localhost:3000 # 1씩 redis에 기록하여 증가함

# redis에 접근하여 데이터 확인
$ telnet localhost 6379 
GET count
quit

# Pod 제거
$ kubectl delete -f echo-pod.yml

 


ReplicaSet(복제셋)

  • Pod을 단독으로 만들면 Pod이 어떤 문제(서버가 죽어서 Pod이 사라졌다던가)가 생겼을 때 자동으로 복구되지 않는다.
  • 이러한 Pod을 정해진 수만큼 복제하고 관리하는 것이 ReplicaSet 이다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: echo-rs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: echo
      tier: app
  template:
    metadata:
      labels:
        app: echo
        tier: app
    spec:
      containers:
        - name: echo
          image: ghcr.io/subicura/echo:v1

 

ReplicaSet은 label을 체크해서 원하는 수의 Pod이 없으면 새로운 Pod을 생성한다. 이를 설정으로 표현하면 다음과 같다.

 

정의 설명

spec.selector label 체크 조건
spec.replicas 원하는 Pod의 개수
spec.template 생성할 Pod의 명세

 

위 예시 코드를 바탕으로 해석하면 app: echo, tier: app이라는 pod이 없으면 template에 정의된 내용을 생성한다.

# ReplicaSet 생성
$ kubectl apply -f echo-rs.yml

# 리소스 확인
$ kubectl get pod,replicaset

# ------
# ReplicaSet과 Pod이 함께 생성됨.
NAME                READY   STATUS    RESTARTS   AGE
pod/echo-rs-hm8tb   1/1     Running   0          57s

NAME                      DESIRED   CURRENT   READY   AGE
replicaset.apps/echo-rs   1         1         1       57s
# ------- 

# 라벨 확인
$ kubectl get pod --show-labels
# --------
NAME            READY   STATUS    RESTARTS   AGE     LABELS
echo-rs-hm8tb   1/1     Running   0          7m25s   app=echo,tier=app
# ---------

# app의 라벨을 제거
$ kubectl label pod/echo-rs-hm8tm app-

$ kubectl get pod --show-labels # 새로운 pod이 생성된다.

 

스케일 아웃

  • replicas: 1 을 replicas: 4 으로 변경
  • 레플리카 셋은 label 단위로 확인하기 때문에 label이 겹치지 않게 정의 해야 한다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: echo-rs
spec:
  replicas: 4
  selector:
    matchLabels:
      app: echo
      tier: app
  template:
    metadata:
      labels:
        app: echo
        tier: app
    spec:
      containers:
        - name: echo
          image: ghcr.io/subicura/echo:v1

 

 


참고 사이트

 


728x90
Comments