IT/PaaS

쿠버네티스 시작하기(3) - 쿠버네티스 구성요소(2/2)

twofootdog 2019. 12. 19. 17:07

이번 장에서는 쿠버네티스(kubernetes) 클러스터의 구성요소 중 컨트롤러(Controller)에 대한 내용을 정리해보고자 한다. 

 

 

1. 컨트롤러(Controller)

이전 장에서 소개한 쿠버네티스 4개의 기본 오브젝트(Basic Object)로 애플리케이션을 설정하고 배포하는 것이 가능하지만, 이를 좀 더 편리하게 관리하기 위해서 쿠버네티스는 컨트롤러(Controller)라는 개념을 이용한다. 

컨트롤러는 기본 오브젝트들을 생성하고 이를 관리하는 역할을 해준다. 컨트롤러는 Replication Controller(aka RC), Replication Set, DaemonSet, Job, StatefulSet, Deployment 등이 있다. 

 

1-1. Replication Controller

Replication Controller는 지정된 숫자로 Pod를 가동시키고, 관리하는 역할을 한다. Replication Controller는 크게 3가지 파트로 구성되는데 selector, replicas, template 3가지로 구성된다.

  • selector : 라벨을 기반으로 하여 RC가 관리할 Pod를 가지고 오는데 사용된다.
  • replicas : RC에 의해 관리되는 Pod의 수인데, 그 숫자만큼 Pod의 수를 유지하도록 한다. 
  • template : Pod 기동 시 어떻게 Pod를 만들지에 대한 정보(도커이미지, 포트, 라벨 등)

또한 이미 돌고있는 Pod가 있는 상태에서 RC 리소스를 생성하면 그 Pod의 라벨이 RC의 라벨과 일치하면 새롭게 생긴 RC의 컨트롤을 받게 된다. 만약 해당 Pod들이 RC에서 정의한 replicas보다 많으면 replicas에 맞게 추가분의 Pod를 삭제하고, 모자르면 template에 정의된 Pod 정보에 따라서 새로운 Pod를 생성하는데, 기존에 생성되어 있는 Pod가 template에 정의된 스펙과 다를지라도 Pod를 삭제하지는 않는다. (예를들어 기존에 아파치 웹서버로 기동중인 Pod가 있고, RC의 template은 nginX로 Pod를 실행하게 되어 있더라고 기존에 돌고있는 아파치 웹서버 Pod는 삭제하지 않음)

아래는 Replication Controller의 오브젝트 스펙 예시이다.


apiVersion: v1
kind: ReplicationController
metadata:
  name: rc-nginx
spec:
  replicas: 3
  selector:
    app: my-nginx
  template:
    metadata:
      name: my-nginx
      labels: 
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
    

이 예제에서는 rc-nginx라는 이름의 RC를 정의했으며, label이 "app:my-nginx"인 Pod들을 관리하고 3개의 Pod가 항상 운영되도록 설정한다. Pod는 app:my-nginx라는 라벨을 가지면서 이름은 my-nginx이고 nginx이미지를 사용해서 생성하고 컨테이너의 포트는 80번 포트를 이용해서 서비스를 제공한다.

 

 

1-2. ReplicaSet

Replication Controller의 새버전이다. 큰 차이는 없고 Replication Controller는 Equality based selector를 이용하며, ReplicaSet은 Set based selector를 이용한다. 

 

 

1-3. 디플로이먼트(Deployment)

Deployment는 Replication Controller와 ReplicaSet의 좀 더 상위 추상화 개념이다. 

Deployment를 이해하기 위해서는 쿠버네티스에서 Deployment 없이 어떻게 배포하는지에 대해 이해를 해야 한다. 

애플리케이션의 배포 방식 중 많이 사용되는 방식이 블루/그린 배포 롤링 업데이트 배포이다.

  • 블루/그린 배포(Blue/Green Deploy) : 블루(이전) 버전에서 서비스 하고 있던 시스템을 그린(신규) 버전으로 배포한 후, 트래픽을 블루에서 그린으로 한번에 돌리는 방식. 가장 손쉬운 방법은 새로운 RC(Replication Controller)를 만들어서 새로운 탬플릿으로 Pod를 생성한 후에 Pod 생성이 끝나면 서비스(Service)가 새로운 Pod를 바라보게끔 옮기는 방식. 후에 문제가 없으면 예전 버전의 RC와 Pod는 삭제한다.
  • 롤링 업데이트 배포(Rolling Update Deploy) : Pod를 하나씩 업그레이드 해나가는 방식. 먼저 새로운 RC를 만든 후에 기존에 RC에서 replica수 하나를 줄이고, 새로운 RC에는 replica 수를 하나만 준다. 라벨을 같은 이름으로 해주면 서비스는 자연히 새로운 RC에 의해 생성된 Pod를 서비스에 포함시킨다. 다음으로 기존 RC의 replica를 하나 더 줄이고 새로운 RC의 replica를 하나 더 늘린다. 이런식으로 반복해서 이전 버전의 Pod는 모두 빠지고 새 버전의 Pod만 서비스 되게 된다. 

그런데 만약 배포가 잘못되는 경우 기존 RC의 replica수를 원래대로 올리고, 새버전의 replica 수를 0으로 만들어서 예전 버전의 Pod로 롤백해야 한다. 이 과정은 kubectl rolling-update 라는 명령으로 RC단우이로 컨트롤이 가능하지만, 그래도 여전히 작업이 필요하고, 배포 과정을 모니터링해야 한다. 또한 kubectl rolling-update는 클라이언트에서 실행하는 명령어로, 명령어 실행중에 클라이언트의 연결이 끊어지면 배포작업이 비정상적으로 끊어질 수 있다. 그리고 롤백과정 역시 수동 컨트롤이 필요할 수 있다.

때문에 이러한 과정을 자동화하고 추상화한 개념을 Deployment라고 보면 된다. Deployment는 Pod배포를 위해서 RC를 생성하고 관리하는 역할을 하며, 특히 롤백을 위한 기존 버전의 RC관리 등 여러가지 기능을 포괄적으로 포함하고 있다.

1-4. 고급 컨트롤러

RC, RS, Deployment는 웹서버와 같은 일반적인 워크로드에 대해 Pod를 관리하기 위한 컨트롤러이다. 그러나 실제 운영환경에서는 웹서버와 같은 일반적인 워크로드 이외에, 데이터베이스, 배치작업, 데몬서버와 같은 다양한 형태의 워크로드 모델이 존재하는데 이를 지원하기 위해서 쿠버네티스에서는 다양한 컨트롤러를 제공함으로써, Pod의 운영을 다양한 시나리오에 맞게 지원하고 있다.

 

1-4-1. DaemonSet(DS)

DaemonSet(이하 DS)은 Pod가 각각의 노드에서 하나씩만 돌개하는 형태로 Pod를 관리하는 컨트롤러이다. RC나 RS에 의해 관리되는 Pod는 여러 노드의 상황에 따라서 일반적으로 비균등적으로 배포가 되지만, DS에 의해 관리되는 Pod는 모든 노드에 균등하게 하나씩만 배포된다. 

이런 형태의 워크로드는 서버의 모니터링이나 로그 수집 용도로 많이 사용되는데, DS의 다른 특징 중 하나는, 특정 Node들에만 Pod가 하나씩만 배포되도록 Pod의 "nodeSelector"를 이용해서 설정 가능하다.

 

1-4-2. Job

워크로드 모델중에서 배치나 한번 실행되고 끝나는 형태의 작업이 있을 수 있다. 예를 들어 원타임으로 파일 변환 작업을 하거나, 또는 주기적으로 ETL 배치 작업을 하는 경우에는 웹서버처럼 계속 Pod가 떠 있을 필요 없이 작업 수행시에만 Pod를 띄우면 된다. 이러한 형태의 워크로드 모델을 지원하는 컨트롤러를 Job이라 한다.

Job에 의해서 관리되는 Pod는 Job이 종료되면 Pod를 같이 종료한다. Job을 정의할 때 보통 컨테이너 스펙 부분에 image 뿐만 아니라 컨테이너에서 Job을 수행하기 위한 커멘드(command)를 같이 입력한다.


apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

Job 컨트롤러에 의해서 실행된 Pod는 이 command의 실행결과에 따라서 Job이 실패한지 성공한지를 판단한다. Job이 종료되었는데 결과가 실패라면 Job을 재 실행할지 또는 그냥 끝낼지를 설정에 따라 결정한다.

만약 Job이 끝나기 전에 쿠버네티스 클러스터의 특정 노드에서 장애가 났다면 어떻게 될까? 방법은 두가지가 있는데, 장애 발생 시 다시 시작하게 하거나 또는 다시 시작하지 않게 할 수 있다. 다시 시작하는 것은 작업의 상태가 보장된 상태에서 다시 시작되는 것이 아닌, 다시 처음부터 작업이 재시작되는 것이기 때문에 resume이 아닌 restart 개념이다. 따라서 처음부터 다시 시작하더라도 데이터가 겹치거나 문제가 없는 형태라야 한다.

또한 같은 작업을 여러번 수행해야 하는 경우, 같은 Pod를 순차적으로 여러번 실행할 수 있도록 설정 가능하다. Job 설정에서 completion 횟수를 주면, 같은 작업을 completion 횟수만큼 순차적으로 반복한다.

만약 여러 작업을 처리하는데 순차성이 필요없고 병렬로 처리하고 싶다면, Job 설정에서 parallelism에 동시 실행할 수 있는 Pod 수를 주면, 지정된 수 만큼 Pod를 실행하여 completion 횟수를 병렬로 처리한다. (예를들어 completion이 5, parallelism이 2이면 동시에 2개의 Pod가 병렬로 실행되며 2회, 3회로 실행되어 총 5회 실행된다)

 

 

1-4-3. CronJob

Job 컨트롤러에 의해서 실행되는 배치성 작업 중 주기적으로 자동화해서 실행할 필요가 있는데, 이런 경우 CronJob 컨트롤러를 사용한다. 

CronJob 컨트롤러는 unix cron 명령어처럼, 시간에 따른 실행조건을 정의해 놓을 수 있고, 이에 따라 Job 컨트롤러를 실행하여 정의된 Pod를 실행할 수 있게 한다. 아래는 CronJob 의 오브젝트 스펙 설정의 예이다.


apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: batch-visualizer-backend-migrator-cronjob
spec:
  schedule: '0 * * * *'
  concurrencyPolicy: Replace
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: batch-visualizer-backend-migrator
              image: twofootdog/project-repo:batch-visualizer-backend-migrator
              command: ["bin/sh", "-c"]
              args: ["requestDate=$(date '+%Y%m%d%H%M%S'); java -jar -Dspring.profiles.active=dev -Duser.timezone=KST /app.jar --job.name=BatchVisualizerJob version=VERSION_STRING requestDate=$requestDate"]
                restartPolicy: OnFailure

설정 방법은 Job과 비슷하고 다른점은 스펙 설정 부분의 schedule 이란 항목이 있고, 반복조건을 unix cron과 같이 설정하면 된다. 

 

 

1-4-4. StatefulSet

마지막으로 1.9에 정식 릴리즈된 StatefulSet이 있다. RS/RC나 다른 컨트롤러로는 데이터베이스와 같이 상태를 가지는 애플리케이션을 관리하기 어렵다. 그래서 이렇게 데이터베이스 등과 같이 상태를 가지고 있는 Pod를 지원하기 위해서 StatefulSet 이라는 것이 새로 소개되었는데, 이를 이해하기 위해서는 쿠버네티스 디스크 볼륨에 대한 이해가 필요하므로 다음에 정리할 예정이다.

 

 

참고

https://bcho.tistory.com/1256?category=731548

 

쿠버네티스 #2 - 개념 이해 (1/2)

쿠버네티스 #2 개념 이해 (1/2) 조대협 (http://bcho.tistory.com) 쿠버네티스를 공부하면서 가장 헷갈리는 부분이 용어와 컨셉이다. 이 컨셉만 잘 이해하면 쿠버네티스를 쉽게 이해하고 사용할 수 있지만, 적어도..

bcho.tistory.com

https://bcho.tistory.com/1257?category=731548

 

쿠버네티스 #3- 개념이해 (2/2) 컨트롤러

쿠버네티스 #3 개념이해 (2/2) : 고급 컨트롤러 조대협 (http://bcho.tistory.com) 고급 컨트롤러 RC,RS,Deployment는 웹서버와 같은 일반적인 워크로드에 대해 Pod를 관리하기 위한 컨트롤러이다. 실제 운영환경..

bcho.tistory.com