본문 바로가기
Devops

[Kubernetes] 쿠버네티스 오브젝트(Pod, ReplicaSet, Deployment)

by heekng 2022. 8. 29.
반응형

쿠버네티스 오브젝트 Pod, ReplicaSet, Deployment

이전에 쿠버네티스를 구성하고있는 master을 정리해보았습니다.

이번에는 쿠버네티스를 이용하며 사용하는 오브젝트를 정리해보려 합니다.

Pod

Pod은 쿠버네티스에서 관리하는 가장 작은 배포단위 입니다.

도커에서는 컨테이너를 관리하지만, 쿠버네티스의 Pod은 하나의 컨테이너 또는 여러 개의 컨테이너를 관리합니다.

Pod 생성 예시

# pod run
kubectl run echo --image ghcr.io/subicura/echo:v1

# 실행된 pod 확인
kubectl get pod

위와 같이 run 또는 apply 명령어로 pod을 생성할 수 있고, kubectl get pod 명령어로 현재 쿠버네티스에서 관리하는 pod 리스트를 확인할 수 있습니다.

Pod 생성 과정

Pod을 생성하라는 명령어를 내리면 나타나는 과정을 알아봅니다.

  1. Scheduler은 API Server을 통해 현재 할당되지 않은 Pod을 감시하고,
    Pod을 노드에 할당합니다.
  2. Kubelet은 API Server을 통해 노드에 할당된 Pod을 감시하고,
    자신에게 할당된 Pod의 정보를 확인하고 컨테이너를 생성합니다.
  3. Pod이 생성되었다면 Kubelet은 API Server에 해당 Pod이 생성되었다고 상태를 전달합니다.

yaml 파일로 Pod을 정의하고 생성하기

apiVersion: v1
kind: Pod
metadata:
  name: echo
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1
  • apiVersion: 해당 오브젝트의 버전을 명시합니다.
    • v1, app/v1, networking.k8s.io/v1, …등의 버전을 사용할 수 있습니다.
    • 이곳에서 간편하게 정리된 kind에 맞는 apiVersion을 확인할 수 있습니다.
  • kind: 어떤 오브젝트를 만들지 작성합니다.
  • metadata: 해당 오브젝트의 메타데이터를 정의합니다.
    • name과 label, annotation으로 구성되어있습니다.
  • spec: 상세 정보를 명세합니다.

컨테이너 정상 동작 체크하기 livenessProbe

쿠버네티스를 이용해 컨테이너를 동작시키면 쿠버네티스 입장에서 해당 컨테이너가 정상으로 동작하는지 확인할 수 있어야 합니다.

예를 들어 스프링 웹 애플리케이션을 띄웠을 때, 어떠한 이유로 실행되지 않았다면? 쿠버네티스가 다시 해당 컨테이너를 띄워 문제를 해결해야 합니다.

이 때 사용하는 방법은 livenessProbe입니다.

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
          port: 8080
        initialDelaySeconds: 5
        timeoutSeconds: 2 # Default 1
        periodSeconds: 5 # Defaults 10
        failureThreshold: 1 # Defaults 3

livenessProve는 http get 요청, tcpSocket, exec 등을 통해 정상 동작을 확인합니다.

readinessProbe

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
          port: 8080
        initialDelaySeconds: 5
        timeoutSeconds: 2 # Default 1
        periodSeconds: 5 # Defaults 10
        failureThreshold: 1 # Defaults 3

여러 컨테이너를 가진 Pod 생성하기

하나의 Pod에는 여러 컨테이너를 실행시킬 수 있다고 했습니다.
따라서 아래와 같이 Pod을 구성할 때, 여러 개의 컨테이너를 정의할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: counter
  labels:
    app: counter
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/counter:latest
      env:
        - name: REDIS_HOST
          value: "localhost"
    - name: db
      image: redis

위 yaml파일을 살펴보면, app 컨테이너와 db 컨테이너 두개를 정의했습니다.

이렇게 하나의 Pod에 컨테이너를 여러개 실행시킨다면 localhost로 네트워크를 공유하고, 디렉토리를 공유할 수 있습니다.

이전에 도커를 사용하면서 여러 컨테이너를 띄우고, 컨테이너간 리소스 공유를 해야한 적이 있었는데…
그 당시에 쿠버네티스를 알았다면 더 쉽게 해결할 수 있었겠네요 ㅠㅠ

ReplicaSet

Pod을 하나만 만들면 해당 Pod이 어떠한 이유로 문제가 생겼을 때, 자동 복구되지 않습니다.
이 때 사용하는 것이 ReplicaSet인데요, ReplicaSet은 Pod을 설정한 값만큼 복제한 후 관리할 수 있도록 만듭니다.

Pod replicaSet 만들기

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

  • spec.selector: label의 체크 조건
  • spec.replicas: Pod의 개수
  • spec.template: 생성할 Pod의 정의
    • spec.template의 경우 위에서 사용했던 Pod의 명세와 동일합니다.
    • label을 정의하고, spec.selector에서 해당 label을 선택해야 replicaSet을 적용할 Pod을 지정할 수 있습니다.

ReplicaSet의 동작 원리

ReplicaSet의 동작 원리 또한 Pod과 유사합니다.

하지만 ReplicaSet Controller가 작동한다는 점만 유의하면 됩니다.

여전히 Pod의 할당은 Scheduler가 합니다.

label

label은 어떤 오브젝트인지 식별할 수 있는 역할을 합니다.

kubectl get pod --show-labels명령어로 해당 Pod의 label과 함께 조회가 가능합니다.

Deployment

배포(Deployment)는 쿠버네티스에서 가장 많이 이용하는 오브젝트입니다.

Deployment는 ReplicaSet을 이용해 Pod을 업데이트, 이력관리 등을 합니다.

Deployment의 꽃은 롤백인 것 같습니다!

Deployment 만들기

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-deploy
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

이전에 ReplicaSet과 다른점은 kind 뿐이라고 봐도 무방합니다.

새로운 버전을 배포했다면?

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-deploy
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:v2

위에서 만들었던 Deployment의 컨테이너 이미지 버전만 v2로 변경했습니다.

이렇게 버전이 달라진 Dployment를 적용하면, 기존의 Pod을 그대로 둔 상태에서 새로운 버전의 Pod을 올립니다.

ReplicaSet의 25% 만큼을 기본값으로 Pod을 생성, 정상 동작시 이전 버전의 Pod 제거를 반복하고, 새로운 버전의 Pod이 모두 정상 실행됩니다.

버전 돌아가기

Deployment는 변경된 상태를 기록합니다.

# 히스토리 확인
kubectl rollout history deploy/echo-deploy

# revision 1 히스토리 상세 확인
kubectl rollout history deploy/echo-deploy --revision=1

# 바로 전으로 롤백
kubectl rollout undo deploy/echo-deploy

# 특정 버전으로 롤백
kubectl rollout undo deploy/echo-deploy --to-revision=2

배포 전략

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-deploy-st
spec:
  replicas: 4
  selector:
    matchLabels:
      app: echo
      tier: app
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 3
      maxUnavailable: 3
  template:
    metadata:
      labels:
        app: echo
        tier: app
    spec:
      containers:
        - name: echo
          image: ghcr.io/subicura/echo:v1
          livenessProbe:
            httpGet:
              path: /
              port: 3000

이전과 달라진 점은 strategy가 추가되었다는 점입니다.

rollingUpdate의 maxSurge, maxUnavailable의 값을 조절해 새로운 버전으로 변경될 시 동시에 만들 Pod의 개수를 조절할 수 있고, 기본값은 replicas 값의 25%입니다.

마침

Pod, ReplicaSet, Deployment에 대해 알아보고 사용방법을 알아봤습니다.

Pod을 ReplicaSet이 감싸고, ReplicaSet을 Deployment가 감싸고 있다는 느낌을 많이 받았습니다.

감사합니다.

반응형