Today I Learned

[쿠버네티스 인 액션] 4. 레플리케이션과 그 밖의 컨트롤러: 관리되는 파드 배포 (2) 본문

쿠버네티스

[쿠버네티스 인 액션] 4. 레플리케이션과 그 밖의 컨트롤러: 관리되는 파드 배포 (2)

하이라이터 2022. 8. 25. 02:28
728x90

4.3 레플리케이션컨트롤러 대신 레플리카셋 사용하기

  • 레플리카셋은 레플리케이션컨트롤러를 대체하는 차세대 리소스이다.
  • 앞으로는 레플리카셋만 사용하겠지만 현장에선 여전히 레플리케이션컨트롤러도 사용되고 있으므로 잘 이해하는게 좋다.

4.3.1 레플리카셋과 레플리케이셔컨트롤러 비교

  • 레플리카셋은 레플리케이션컨트롤러와 똑같이 동작하지만 좀 더 풍부한 표현식을 사용하는 파드 셀렉터를 갖고 있다.
  • 레플리케이션컨트롤러는 특정 레이블이 있는 파드만 매칭시킬 수 있는 반면, 레플리카셋의 셀렉터는 특정 레이블이 없는 파드나 레이블의 값과 상관없이 특정 레이블의 키를 갖는 파드를 매칭시킬 수 있다.
  • 또한 레플리카셋은 하나의 레플리카셋으로 여러 파드 세트를 모두 매칭시켜 하나의 그룹으로 취급할 수 있다.
    (ex. env=production OR env=devl)
  • 레플리카셋은 레이블키의 존재만으로 파드를 매칭시킬 수도 있다. (ex. env=*)

4.3.2 레플리카셋 정의하기

  • 먼저 다음 예제처럼 kubia-replicaset.yaml이라는 새 파일을 생성한다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: kubia
spec:
  replicas: 3
  selector:
    matchLabels:
      app: kubia
  template:
    metadata:
      labels:
        app: kubia
    spec:
      containers:
      - name: kubia
        image: luksa/kubia
  • 레플리케이션컨트롤러와의 유일한 차이점은 파드를 가져야하는 레이블이 selector 바로 아래 있는 대신 selector.matchLabels 아래에 지정한다.
  • app=kubia 셀렉터와 매칭되는 이전에 실행한 세 개의 파드가 여전히 실행 중이기 때문에 레플리카셋을 생성해도 새 파드가 생성되지는 않는다. 레플리카셋은 기존 세개의 파드를 자신의 관리하에 둔다.


4.3.3 레플리카셋 생성 및 검사

$kubectl get rs

$kubectl describe rs

  • 보다시피 레프리케이션컨트롤러와 다르지 않으며, 셀렉터와 일치하는 세 개의 복제본이 있음을 보여준다.

4.3.4 레플리카셋의 더욱 표현적인 레이블 셀렉터 사용하기

  • 더 강력한 matchExpressions를 사용하도록 셀렉터를 작성해보자.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: kubia
spec:
  replicas: 3
  selector:
    matchExpressions:
      - key: app
        operator: In
        values:
         - kubia
  template:
    metadata:
      labels:
        app: kubia
    spec:
      containers:
      - name: kubia
        image: luksa/kubia
  • 셀렉터에 표현식을 추가할 수 있으며 각 표현식은 키, 연산자, 가능한 값이 포함돼야 한다.
    • In : 레이블의 값이 지정된 값 중 하나와 일치해야 한다.
    • NotIn : 레이블의 값이 지정된 값과 일치하지 않아야 한다.
    • Exists : 파드는 지정된 키를 가진 레이블이 포함되어야 한다(값은 중요하지않다). 이 연산자를 사용할 때는 값 필드를 지정하지 않아야 한다.
    • DoesNotExists : 파드에 지정된 키를 가진 레이블이 포함되어 있지 않아야 한다. 값 필드를 지정하지 않아야 한다.
  • 여러 표현식을 지정하면 모든 표현식이 true여아 셀렉터와 파드가 매칭된다.

4.3.5 레플리카셋 정리

  • 레플리케이션컨트롤러를 삭제하는 것과 같은 방법으로 레플리카셋을 삭제할 수 있다.
  • 레플리카셋을 삭제하면 모든 파드가 삭제된다.
$kubectl delete rs kubia

4.4 데몬셋을 사용해 각 노드에서 정확히 한 개의 파드 실행하기

  • 클러스터의 모든 노드에, 노드 당 하나의 파드만 실행되길 원하는 경우가 있을 수 있다(ex. 로그 수집기, 리소스 모니터).


4.4.1 데몬셋으로 모든 노드에 파드 실행하기

  • 모든 클러스터 노드마다 파드를 하나만 실행하려면 데몬셋(DemonSet) 오브젝트를 생성해야 한다.
  • 데몬셋에 의해 생성되는 파드는 타깃 노드가 이미 지정되어 있고 쿠버네티스 스케줄러를 건너뛰는 것을 제외하면 레플리케이션컨트롤러 또는 레플라키셋과 매우 유사하다.
  • 레플리카셋이 클러스터에 원하는 수의 파드 복제본이 존재하는지 확인하는 반면, 데몬셋에는 원하는 복제본 수라는 개념이 없다.
  • 데몬셋의 역할은 파드 하나가 각 노드에서 실행중인지 확인하는 것이다. 새 노드가 클러스터에 추가되면 데몬셋은 즉시 새 인스턴스를 새 노드에 배포한다.

4.4.2 데몬셋을 사용해 특정 노드에서만 파드를 실행하기

  • node-Selector 속성을 지정해서 데몬셋이 특정 노드에만 배포하도록 지정할 수 있다.
  • 이 속성을 지정하지 않으면 데몬셋은 클러스터의 모든 노드에 파드를 배포한다.

예제를 사용한 데몬셋 설명

  • SSD를 갖는 모든 노드에서 실행돼야 하는 ssd-monitor라는 데몬이 있다고 가정해보자.
  • 해당하는 모든 노드에 disk=ssd 레이블을 추가하고 해당 레이블이 있는 노드만 선택하는 노드 셀렉터를 사용해 데몬셋을 작성한다.

 데몬셋 YAML 정의 생성

  • 5초마다 표준 출력으로 "SSD OK"를 출력하는 모의 ssd-monitor 프로세스를 실행하는 데몬셋을 생성한다.
  • 이미 모의 컨테이너 이미지가 도커 허브에 푸시되어있으므로 다음과 같이 데몬셋에 대한 YAML을 작성한다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ssd-monitor
spec:
  selector:
    matchLabels:
      app: ssd-monitor
  template:
    metadata:
      labels:
        app: ssd-monitor
    spec:
      nodeSelector:
        disk: ssd
      containers:
      - name: main
        image: luksa/ssd-monitor

데몬셋 생성

$kubectl create -f ssd-monitor-daemonset.yaml
$kubectl get ds

  • 아직 노드에 disk=ssd 레이블을 추가하지 않아서 생성된 파드가 없다.
  • 레이블을 추가하면 데몬셋은 노드의 레이블이 변경됐음을 감지하고 해당 레이블이 있는 모든 노드에 파드를 배포한다.

필요한 레이블을 노드에 추가하기

$kubectl label node gke-kubia-pool-1-01349329-2vbq disk=ssd

  • node 중 하나에 disk=ssd 레이블을 추가하면 데몬셋이 파드를 바로 생성한다.

노드에서 레이블 제거하기

$kubectl label node gke-kubia-pool-1-01349329-2vbq disk=hdd --overwrite

  • 노드에서 레이블을 제거하면 실행중이던 데몬셋의 파드는 종료된다.

4.5 완료 가능한 단일 태스크를 수행하는 파드 실행

  • 레플리케이션컨트롤러, 레플리카셋, 데몬셋은 완료됐다고 간주되지 않는 지속적인 태스크를 실행한다. 이런 파드의 프로세스는 종료되면 다시 시작한다.
  • 그러나 프로세스가 종료된 후에 다시 시작되지 않는 완료 가능한 태스크(completable task)가 필요할 수 있다.

4.5.1 잡 리소스 소개

  • 잡(Job)은 파드의 컨테이너 내부에서 실행 중인 프로세스가 성공적으로 완료되면 컨테이너를 다시 시작하지 않는 파드를 실행할 수 있다.
  • 노드에 장애가 발생한 경우 해당 노드에 있던 잡이 관리하는 파드는 레플리카셋 파드와 같은 방식으로 다른 노드에 다시 스케줄링된다.
  • 프로세스 자체에서 장애가 발생한 경우(에러코드를 리턴), 잡에서 컨테이너를 다시 시작할 것인지 설정할 수 있다.
  • 관리되지 않는 파드에서 작업을 실행하고 완료될 때까지 기다릴 수 있지만 작업이 수행되는 동안 장애가 발생하는 경우 수동으로 다시 수행해야 한다는 문제가 있다.


4.5.2 잡 리소스 정의

apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
  • 잡은 batch API 그룹과 v1 API 버전에 속한다.
  • YAML은 luksa/batch-job 이미지를 실행할 job 유형의 리소스를 정의한다. 이 이미지는 정확히 120초 동안 실행된 후 종료되는 프로세스를 호출한다.
  • 파드 스펙(spectification)에서는 restartPolicy 속성으로 컨테이너에서 실행중인 프로세스가 종료될 때 쿠버네티스가 수행할 작업을 지정할 수 있다.
  • restartPolicy 속성의 기본값은 Always이지만, 잡 파드는 무한정 실행되지 않으므로 onFailure나 Never로 명시적으로 설정해야 한다.

4.5.3 파드를 실행한 잡 보기

  • kubectl create 명령으로 잡을 생성하면 즉시 파드가 시작되는 것을 볼 수 있다.
  • 2분이 지나면 더 이상 파드 목록에 표시되지 않고 잡이 완료된(completed) 것으로 표시된다.
  • 파드 목록을 조회할때 --show-all(또는 -a) 스위치를 사용하지 않으면 기본적으로 완료된 파드는 표시되지 않는다. 표시되는듯

  • 파드가 완료될 때 파드가 삭제되지 않은 이유는 해당 파드의 로그를 검사할 수 있게 하기 위해서다.


4.5.4 잡에서 여러 파드 인스턴스 실행하기

  • 잡은 두 개 이상의 파드 인스턴스를 생성해 병렬 똔느 순차적으로 실행하도록 구성할 수 있다.
  • 이는 잡 스펙에 completions와 paralledlism 속성을 설정해 수행한다.

순차적으로 잡 파드 실행하기

apiVersion: batch/v1
kind: Job
metadata:
  name: multi-completion-batch-job
spec:
  completions: 5
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
  • 잡을 두 번 이상 실행해야 하는 경우 잡의 파드를 몇번 실행할지 completions에 설정할 수 있다. 이 잡은 차례로 다섯 개의 파드를 실행한다.

병렬로 잡 파드 실행하기

  • 잡 파드를 하나씩 차례로 생성하는 대신 여러 파드를 병렬로 실행할 수도 있다. parallelism을 2로 정하면 두 개까지 병렬로 실행할 수 있다.
apiVersion: batch/v1
kind: Job
metadata:
  name: multi-completion-batch-job
spec:
  completions: 5
  parallelism: 2
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job

잡 스케일링

  • 잡이 실행되는 동안 잡의 parallelism 속성을 변경할 수도 있다.
  • 레플리카셋을 스케일링하는 것과 유사하며, kubectl scale 명령을 사용해 수행할 수 있다.
$kubectl scale job multi-completion-batch-job --replicas 3

4.5.5 잡 파드가 완료되는 데 걸리는 시간 제한하기

  • 파드 스펙에 activeDeadlineSeconds 속성을 설정해 파드의 실행 시간을 제한할 수 있다.
  • 파드가 이보다 오래 실행되면 시스템이 종료를 시도하고 잡을 실패한 것으로 표시한다.


4.6 잡을 주기적으로 또는 한번 실행되도록 스케줄링하기

  • 쿠버네티스에서의 크론 작업은 크론잡(CronJob) 리소스를 만들어 구성한다. 잡 실행을 위한 스케줄은 크론 형식으로 지정한다.

4.6.1 크론잡 생성하기

  • 매 15분마다 실행되는 배치잡을 생성해보자.
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: batch-job-every-fifteen-minutes
spec:
  schedule: "0,15,30,45 * * * *"
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: periodic-batch-job
        spec:
          restartPolicy: OnFailure
          containers:
          - name: main
            image: luksa/batch-job

4.6.2 스케줄된 잡의 실행 방법 이해

  • 잡 리소스는 대략 예정된 시간에 크론잡 리소스에서 생성된다. 잡이나 파드가 상대적으로 늦게 생성되고 실행될 수 있다.
  • 예정된 시간을 너무 초과해 시작되어서는 안된다는 엄격한 요구사항이 필요하다면 크론잡 스펙의 startingDeadlineSeconds 필드를 지정해 데드라인을 설정할 수 있다.
728x90
Comments