DevOps/Docker & K8S

쿠버네티스 파드 관리하기 (데몬셋, 스테이트풀셋, 잡, 크론잡, 파드 프리셋, CRD)

SKaSha 2020. 2. 12. 12:27

데몬셋

각 파드마다 동일한 로깅 에이전트를 가지고 있으면 각 노드에 중복으로 존재할수 있기때문에, 각 노드마다 실행이 필요한 단일 레플리카의 파드가 있다면 데몬셋을 이용하면 된다.
주로 로그 수집기나, 노드를 모니터링하는 데몬 등에 사용된다.

.spec.updateStrategy.type

데몬세트/스테이트풀셋의 파드를 업데이트할때 OnDeleteRollingUpdate 중 선택할 수 있다.
기본 값은 RollingUpdate이나, 쿠버네티스 1.5 이하 버전에서는 OnDelete가 기본 값이다.
RollingUpdate는 템플릿을 변경했을때 바로 변경되지만 OnDelete는 파드를 직접 제거해야 새로운 버전의 파드가 생성된다.

.spec.updateStrategy.rollingUpdate.maxUnavailable

업데이트시 한번에 삭제하는 파드의 갯수. (default 1)

.spec.minReadySeconds

새로 실행되는 파드가 준비상태가 되기 위한 최소 시간. (default 0)
따로 지정하지 않으면 기본값이 0이라 파드가 준비되는 대로 바로 사용가능하다.

스테이트풀셋

상태가 있는 파드들을 관리하기 위한 컨트롤러로써, 개별 Pod에 대한 디스크 볼륨 관리를 지원한다.
Replication Set 기반의 디스크 볼륨 관리는 하나의 컨트롤러로 여러 Pod에 대해 디스크를 각각 지정해서 관리할 수 없는 문제가 있었는데, 스테이트풀셋은 PVC (Persistent Volume Claim)를 템플릿 형태로 정의하여, Pod 마다 각각 PVC와 PV를 생성하여 관리할 수 있도록 한다.

.spec.podManagementPolicy

파드를 순서 없이 실행하거나, 특정 순서에 따라 파드를 시작하고 중지할 수 있는 기능을 제공한다.
예를 들어 마스터디비가 먼저 구동되고 슬레이브 디비가 구동되도록 할 수 있다.

  • OrderedReady (default)
    순서대로 파드를 관리한다.

  • Parallel
    파드들을 순서 없이 병렬로 실행되거나 종료되도록 할 수 있다.

.spec.updateStrategy.rollingUpdate.partition

스테이트풀셋에 변경사항이 있을 때, 지정된 값보다 큰 번호를 가진 파드들을 업데이트하고 이 값보다 작은 번호의 파드들은 업데이트하지 않으므로써 파드를 분할(partition)한다.
대부분의 케이스는 파티션을 사용할 필요가 없지만 업데이트를 준비하거나, 카나리의 롤 아웃 또는 단계적인 롤 아웃을 행하려는 경우에는 유용하다.

잡 (Job)

잡은 실행된 후에 종료해야 하는 성격의 작업을 실행할때 사용되는 컨트롤러이다.
디플로이먼트가 특정 개수의 파드를 실행하고 지속적으로 재시작하는 반면에 은 지정한 횟수만큼만 파드를 실행한다.

.spec.template.spec.restartPolicy
  • Never
    파드를 항상 성공으로 처리되도록 설정하여 컨테이너가 비정상 종료했을때 재시작을 막을수 있음.

  • OnFailure
    파드 안 컨테이너가 비정상 종료되었거나 실행이 정상적으로 완료되지 않았을때 컨테이너를 다시 시작하도록 한다.

.spec.backoffLimit

잡 실행이 실패했을때 자동으로 최대 몇번까지 재시작할지 설정. (default 6)
처음 재시작 실패 후, 10초를 기다렸다가 실행하고 그다음은 20초, 40초와 같은 형태로 재시작 대기 시간이 증가함.
파드 실행이 완료되면 재시작 횟수는 0으로 초기화됨.

.spec.completions

작업이 완료되었다고 판단하기 전에 지정된 파드가 성공적으로 실행되어야 하는 횟수 (default 1)

.spec.parallelism

한 번에 몇개의 파드를 실행할지 지정 (default 1)

잡의 종류

  • 단일 잡
    파드 하나만 실행된다.
    파드가 정상적으로 실행종료 되면 잡 실행이 완료 됨.
    .spec.completions, .spec.parallelism을 따로 지정하지 않는다.

  • 완료 갯수가 지정되어 있는 병렬 잡
    .spec.completions는 양수로 설정한다. 해당 값만큼 파드가 성공하면 잡이 완료됩니다.
    .spec.parallelism는 따로 지정하지 않는다.

  • 워크 큐가 있는 병렬 잡
    .spec.completions는 따로 지정하지 않는다.
    .spec.parallelism는 양수로 설정한다.
    .spec.completions를 지정하지 않으면 기본 값이 .spec.parallelism와 동일하게 설정된다.
    최소한 파드 1개가 정상적으로 종료된 후 모든 파드가 실행 종료되면, 잡은 정상적으로 종료처리 됨.
    파드 1개가 정상적으로 실행 종료되면 다른 파드는 더 이상 동작하지 않거나 어떤 작업 처리 결과는 내지 않고 모두 종료 과정을 실행함.

.spec.activeDeadlineSeconds

특정 시간동안 잡이 완료되지 않으면 모든 파드 실행을 종료한다.
지정된 시간을 초과하여 잡이 실패했다면, 종료 이유가 reason: DeadlineExceeded로 표시된다.

.spec.ttlSecondsAfterFinished

잡은 정상적으로 실행되거나 실패하였을때 파드가 자동으로 제거 되지 않는다.
TTL mechanism을 이용하여 지정된 필드의 시간뒤에 잡이 제거되도록 할 수 있다.
쿠버네티스 버전 1.12에서부터 [alpha]로 지원한다.

잡 패턴

  • 각 파드는 독립적으로 동작하는것을 전제로 둔다.
    잡에서 파드를 병렬로 실행하였을때 파드들이 서로 통신하면서 동작하지 않는다.

  • 여러 개의 잡을 생성하기보다 여러 작업을 수행하는 잡 하나를 사용하는게 좋다.
    잡을 생성하는 오버헤드는 크기 때문에 작업이 많아질수록 하나의 잡에서 여러개의 작업을 처리하는게 좋다.

  • 여러 개의 파드를 생성하기보다 여러 작업을 수행하는 파드 하나를 사용하는게 좋다.
    위와 동일하게 파드를 생성하는 오버헤드는 크기 때문에 하나의 파드에서 여러개의 작업을 처리하는게 좋다.

  • Work queue를 사용한다면 카프카나 RabbitMQ 같은 큐 서비스를 워크 큐로 구현하도록 기존 프로그램이나 컨테이너를 수정해야한다.
    워크 큐를 사용하지 않으면 그냥 기본 설정 그대로 컨테이너를 사용하므로 비효율적이다

https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-patterns

크론잡 (CronJob)

잡을 시간 기준으로 관리하도록 하며, 지정한 시간에 잡을 실행하거나 주기적으로 잡을 반복 실행할 수 있다.

.spec.schedule

리눅스의 cron 명령어에서 사용하는 옵션 형식을 그대로 사용함.

.spec.startingDeadlineSeconds

지정된 시간에 크론잡이 실행되지 못했을때 필드 값으로 설정한 시간까지 지나면 크론잡이 실행되지 않게 함.
이 필드 값을 설정하지 않으면, 실행 시간이 좀 지나더라도 제약 없이 잡이 실행되도록 한다.

.spec.concurrencyPolicy

크론잡이 실행하는 잡의 동시성을 관리함.

  • Allow (default)
    크론잡이 여러개 잡을 동시에 실행할 수 있게함.

  • Forbid
    크론잡이 여러개 잡을 동시에 실행할 수 없게함.
    만역 이전 잡이 실행중일때 다음 잡을 실행해야할 시간이 되면, 해당 시간에 새로운 잡을 생성하지 않고 다음 지정된 시간에 잡을 실행시킨다.

  • Replace
    이전에 실행한 잡이 실행 중인 상태에서 새로운 잡을 실행할 시간이 되면 이전에 실행중인 잡을 새로운 잡으로 대체한다.

.spec.successfulJobsHistoryLimit (default 3)

정상적으로 실행 종료 된 잡의 내역을 몇개까지 저장할지 지정한다.

.spec.failedJobsHistoryLimit (default 1)

비정상적으로 실행 종료 된 잡의 내역을 몇개까지 저장할지 지정한다.

파드 프리셋

파드 프리셋은 어드미션 컨트롤러라고 불리는 오브젝트의 한 유형으로, 파드 생성 시간에 파드에 추가적인 런타임 요구사항을 주입하기 위한 API 리소스이다.
주어진 파드 프리셋이 적용되도록 파드에 명시하기 위해서는 레이블 셀렉터를 사용한다.

대표적으로 주어진 레이블과 일치하는 모든 파드에 볼륨을 마운트하도록 정보를 추가하는 예시가 있는데, 파드 프리셋을 통하여 파드 템플릿 작성자에게 파드에 대한 모든 정보를 명시적으로 작성하지 않아도 된다.
파드 프리셋을 위한 디자인 제안

동작원리

  1. 사용 가능한 모든 PodPresets을 검색한다.
  2. PodPreset의 레이블 셀렉터들 중 하나라도 생성되는 파드의 레이블과 일치하는 것이 있는지 확인한다.
  3. PodPreset에 의해서 정의된 다양한 리소스가 생성되는 파드에 병합되도록 시도한다.
  4. 오류 시, 파드의 병합 오류를 문서화하는 이벤트를 발생시키고, PodPreset으로 부터 주입된 어떤 리소스도 없이 파드를 생성한다.
  5. 수정된 파드 스펙의 결과에 어노테이션을 달아 PodPreset에 의해서 수정되었음을 표시한다. 해당 어노테이션은 다음의 양식을 따른다. podpreset.admission.kubernetes.io/podpreset-<파드-프리셋 이름>: "<리소스 버전>".

각 파드는 0개 이상의 파드 프리셋에 일치될 수 있고, 각 PodPreset은 0개 이상의 파드에 적용될 수 있다.
하나의 PodPreset이 한 개 이상의 파드에 적용되었을 때, 쿠버네티스는 해당 파드의 스펙을 수정한다.
Env, EnvFrom, VolumeMounts의 변경에 대해서는, 쿠버네티스가 파드 내의 모든 컨테이너의 컨테이너 스펙을 수정한다.
Volume 변경에 대해서는, 쿠버네티스는 해당 파드의 스펙을 수정한다.

특정 파드의 파드 프리셋 비활성화

podpreset.admission.kubernetes.io/exclude: "true"

오퍼레이터 커스텀 리소스 정의 (CRDs)

표준 쿠버네티스 오브젝트는 단순한 스테이리스 어플리케이션에는 적합하지만 그 이상은 한계가 있다.
스테이트풀셋이 제공하는 것보다 더 복잡한 관리가 필요한 어플리케이션이라면 사용자가 CRDs(Custom Resource Definitions)라는 새로운 유형의 쿠버네티스 오브젝트를 직접 생성할 수 있다.
CRD를 이용하면 쿠버네티스 시스템 내부에 녹아들어서 kubectl과 같은 쿠버네티스 기본 명령어들을 함께 사용하는 것이 가능해진다.

커스텀 리소스를 이용해서 사용자가 원하는 상태를 선언해 두면 커스텀 컨트롤러가 그 상태를 맞추기위해 필요한 작업을 수행합니다.
대표적인 방법으로는 코어OS사의 오퍼레이터 패턴과 구글의 Knative가 있습니다.

하지만 CRDs를 사용하게 되면 커스텀 리소스를 위한 저장공간이 추가로 필요하게 되고, 이는 예상치 못한 장애를 유발할 수도 있습니다.