티스토리 뷰

반응형

4장. 레플리케이션과 그 밖의 컨트롤러 : 관리되는 파드 배포

  • pod 가 있고 이걸 죽으면 다시 재생시키겠다 : 레플리카셋, 레플리카 컨트롤러(웹서버같은 친구들)
  • pod 가 있는데요 작업 끝나면 죽이거나 작업 크론잡을 돌려요 : 잡, 크론잡
  • pod 가 있는데요 노드당 한 대 씩 배정 : 데몬셋(로그 , 프로메테우스)
  • (개인 의견: 에어플로가 레플리카셋 , airflow 위에 태스크들은 잡 형태가 되지 않을까,,)

4.0 다루는 내용

  • 파드의 안정적인 유지
  • 동일한 파드의 여러 인스턴스 실행
  • 노드 장애시, 자동으로 파드 재스케줄링
  • 파드의 수평스케줄링
  • 각 클러스터 노드에서 시스템 수준의 파드 실행
  • 배치 잡 실행
  • 잡을 주기적으로, 또는 한번만 실행하도록 스케줄링
  • 파드 : 배포 가능한 기본 단위
  • 파드를 수동적으로 개입(생성, 감독, 관리)없이 컨트롤러를 통해 실제 파드를 생성하고 관리

4.1. 파드를 안정적으로 유지하기

  • 쿠버네티스 주요 이점 : 컨테이너들이 클러스터 어딘가에서 계속 실행되게 할 수 있다.
  • 주 프로세스에 crash 가 발생하면, kubelet 이 컨테이너를 다시 시작하게 한다.
    • kubelet : api 서버와 통신, 노드의 컨테이너 관리
  • 메모리 누수로 OOM이 발생할 수 있는 경우, 애플리케이션의 상태를 외부에서 체크해 해결 가능
    • 프로세스는 계속 실행될 수 있다.

쿠버네티스 컴포넌트 | Kubernetes

라이브니스 프로브 소개(liveness probe)

  • 컨테이너가 살아있는지 확인하는 주된방법
  • HTTP GET 프로브
    • 지정한 IP 주소, 포트, 경로에 HTTP GET 요청을 수행
    • 서버가 오류 응답코드를 리턴하거나 응답하지 않으면 프로브는 실패로 간주하고 컨테이너를 다시 시작
    • TCP 소켓 프로브
      • 컨테이너의 지정된 포트에 TCP를 연결하려고 시도
      • 성공적으로 연결이 되지 않으면 컨테이너가 다시 시작
    • Exec 프로브
      • 컨테이너 내부에 임의의 명령을 실행하고, 명령의 종료 상태 코드를 확인
      • 상태 코드가 0이면 검사 성공. 다른 코드는 오류로 간주
  • 파드를 정의하는 YAML 작성 및 생성 (HTTP GET 라이브니스 프로브 포함)
  • $ kubectl get pod <pod name> -o yaml apiVersion: v1 # 해당 YAML 디스크립터에서 사용한 쿠버네티스 API 버전 kind: Pod # 쿠버네티스 오브젝트/리소스 유형 metadata: # 파드 메타데이터 (이름, 레이블 등...) ... spec: # 파드 정의/내용 (파드 컨테이너 목록, 볼륨 등...) containers: - image: luksa/kubia-unhealthy # 문제가 있는 애플리케이션을 포함하는 이미지 name: kubia livenessProbe: # Http Get을 수행할 라이브니스 프로브 httpGet: path: / # 네트워크 포트 HTTP 요청에서 요청할 경로 port: 8080 # 프로브가 연결해야 하는 네트워크 포트

다섯 번의 요청 후에 쿠버네티스가 프로브를 실패한 것으로 간주하여 컨테이너를 다시 시작

동작 중인 라이브니스 프로브 확인

라이브니스 프로브의 기능 확인 가능

$ kubectl get po kubia-liveness

NAME             READY   STATUS    RESTARTS   AGE
kubia-liveness   1/1     Running   1          2m

컨테이너가 다시 시작된 이유 확인 가능
(컨테이너가 종료되면 동일한 컨테이너가 재시작되는 것이 아닌, 새로운 컨테이너가 생성)

$ kubectl describe po kubia-liveness

(생략)

Exit Code:    137         # 128 + x (9 : 프로세스 강제 종료)

(생략)

Killing container ...

라이브니스 프로브의 추가 속성 설정

추가적인 매개변수 지정
(예시 : 초기 지연 설정) - 반드시 지정해야 함

livenessProbe:
  httpGet:
    path:/
    port: 8080
  initialDelaySeconds: 15 # 첫 번째 프로브 실행 전 15초 대기

효과적인 라이브니스 프로브 생성

  • 애플리케이션의 내부만 체크하고, 외부 요인의 영향을 받지 않도록 해야함
    (ex : 프론트엔드 웹서버가 백엔드 데이터베이스에 연결할 수 없을 때 실패를 반환해서는 안됨)
  • 많은 연산 리소스 사용하면 안됨, 시간이 오래 걸리지 않아야 됨
  • 재시도 루프를 구현하지 말아야 함 (실패 임계값으로 대처 가능)
  • 크래시가 발생하거나 라이브니스 프로브가 실패한 경우 컨테이너를 다시 시작해 컨테이너를 계속 실행함
  • 파드를 호스팅하는 노드에서 Kubelet에 의해 수행
  • 노드 자체에 크래시가 발생하는 경우, 포드의 대체 폼을 생성해야 하는 것은 컨트롤 플레인의 몫
    (직접 생성한 파드는 노드 자체가 고장나면 아무 것도 할 수 없음)
    -> 애플리케이션이 다른 노드에서 시작되도록 하기 위해 레플리케이션컨트롤러 or 유사한 메커니즘으로 파드 관리해야 함

4.2 레플리케이션컨트롤러 소개

  • 쿠버네티스는 파드를 항상 실행되게 유지하기 위해 레플리케이션 컨트롤러(Replication Controller)라는 리소스를 활용한다.
  • 레플리케이션 컨트롤러는 노드가 (클러스터에서 사라지는 경우나 노드에서 파드가 제거되는 경우 등) 파드가 사라지면, 해당 파드의 복사본을 만든다.

img

레플리케이션 컨트롤러의 동작

  • 실제 파드의 수가 의도하는 수와 일치하는 지 항상 확인한다.(많거나 적으면 추가 혹은 제거)
  • 레플리케이션 컨트롤러의 세가지 요소
    • 레이블 셀렉터(label selector): 레이블 기반으로 파드를 가지고온다.
    • 레플리카 수(replica count): 관리되는 파드의 수
    • 파드 템플릿(pod template): 파드에 대한 정보(도커 이미지, 포트, 라벨등)
  • 주의 : 레이블 셀렉터와 파드 템플릿을 변경해도 기존 파드에 영향을 미치지 않는다.(삭제 안됨)
  • img
  • 레플리케이션 컨트롤러 사용 이점
    • 기존 파드가 사라지면, 새 파드를 시작해 파드가 항상 실행된다.
    • 클러스터 노드가 장애가 발생하면, 장애가 발생한 노드에서 실행중인 모든 파드에 관한 교체 복제본이 생성된다.
    • 수동 + 자동으로 파드 쉽게 스케일 아웃가능

레플리케이션 컨트롤러 생성

쿠버네티스 api 서버에 json 또는 yaml 디스크립터를 게시해 레플리케이션컨트롤러를 만든다.

apiVersion: v1
kind : ReplicationController
metadata:
 name : kubia # 레플리케이션컨트롤러 이름
spec:
 replicas : 3 # 파드 인스턴스 수
 selector :  # 관리하는 파드 선택
  app: kubia
 template: # 새 파드에 사용할 파드 템플릿
  metadata:
   labels:
    app:kubia
   spec:
    containers:
    - name: kubia
      image: luksa/kubia
      ports:
      - containerPort: 8080
  • 템플릿의 파드 레이블은 레플리케이션 컨트롤러의 레이블 셀렉터와 완전히 일치해야한다.
    • (그렇지 않으면 컨트롤러에서 새 파드 무한정 생성할 수있다.)
  • 이런 경우를 방지하기 위해 api 서버는 레플리케이션컨트롤러의 정의를 검증하고, 잘못 구성된 경우, 이를 받아들이지 않는다.
  • 셀렉터를 지정하지 않으면 자동으로 설정된다.

생성 명령어

$ kubectl create -f kubia-rc.yaml
replicationcontroller "kubia" created
  • 레플리케이션 컨츠롤러 작동확인(의도한 파드 인스턴스 3개 생성)
kubectl get pods
NAME    READY   STATUS  RESTARTS    AGE
...
  • 레플리케이션 컨트롤러 정보 얻기
kubectl get rc
NAME    DESIRED   CURRENT  READY    AGE
...
  • 레플리케이션 컨트롤러의 세부 정보 표시
kubectl describe rc kubia

세부 정보 표시
  • 노드 장애 대응(노드가 여러 개 : 구글 쿠버네티스 엔진일 경우)
    • 레플리케이션 컨트롤러는 노드의 파드가 다운됐음을 감지하자마자 파드를 대체하기 위해 새 파드를 기동
      • 장애가 발생한 노드는 상태가 NotReady 로 변경되고 새 파드가 하나 생긴다.
      • 노드가 다시 부팅되는 경우, 노드가 Ready 상태로 돌아오고 Unknown 상태의 파드는 삭제된다.

레플리케이션 컨트롤러의 범위 안팎으로 파드 이동하기

  • 레이블 셀렉터와 일피하는 파드만 관리한다.
  • 파드의 레이블을 변경하면 레플리케이션컨트롤러의 범위에서 제거되거나 추가가 가능하다.

img

파드 템플릿 변경

  • 레플리케이션 컨트롤러의 파드 템플릿은 언제든지 수정이 가능하다.
  • 레플리케이션 콘트롤의 파드 템플릿을 편집해 컨테이너 이미지를 변경하고, 기존 파드를 삭제함으로써 , 새로운 템플릿을 사용해 기존 파드를 새로운 파드로 교체 가능하다.

img

(그리 설명 : 레플리케이션컨트롤러의 파드템플릿을 변경하면, 변경 이후에 생성된 파드만 영햐응ㄹ 미치며, 기존 파드는 영향을 밪기 않는다.)

수평파드 스케줄링

레플리케이션 컨트롤러 스케일업, 다운하기

  • 방법1
kubectl scale rc kubia --replicas=10
  • 방법2
kubectl edit rc kubia # 텍스트 편집기로 spec.replicas 필그 수정

레플리케이션 컨트롤러 삭제

  • kubectl delete 를 활용한 레플리케이션 컨트롤러 삭제는 파드도 함께 삭제됨
  • 레플리케이션 컨트롤러만 삭제하고 파드는 실행상태로 두는 방법
kubectl delete rc kubia --cascade=false

img

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

  • 초기에는 레플리케이션 컨트롤러가 파드를 복제하고, 노드 장애 발생 시, 재스케줄링하는 유일한 구성요소 였다.
  • 추후에, 레플리카셋이라는 유사한 리소스 도입 = 차세대 레플리케이션 컨트롤러
  • 초기에 히스토리 및 기존서비스의 유지보수를 위해 레플리케이션 컨트롤러를 설명한다.
  • 일반적으로 레플리카셋을 직접 생성하지 않고 , 9장에서 배울 상위 수준의 디플로이먼트 리소스 생성시, 자동으로 생성되게 함

4.3.1. 레플리카셋과 레플리케이션 컨트로럴 비교

  • 레플리카셋은 레플리케이션 컨트롤러와 똑같이 동작한다.
  • 좀 더 풍부한 표현식을 사용하는 파드 셀렉터를 가지고 있다.
    • 특정 레이블이 없는 파드
    • 레이블 값과 상관없이 특정 레이블 키를 가지는 파드(env=*)
    • 두 파드 세트를 모두 매칭시켜 하나의 그룹 취급 가능 (env=devel, env-production)

4.3.2. 레플리카셋 정의하기

apiVersion: apps/v1beta2
kind: ReplicaSet
... 생략...

spec:
 replicas: 3
 selector:
  matchLabels:
   app: kubia
... 생략...
  • 적절한 apiVersion 지정 필요
  • 셀렉터에 차이가 있다.(selector -> selector.matchLabels)

4.3.3. 레플리카셋 생성 및 검사

  • kubectl create 명령을 사용해 yaml 파일로 레플리카셋 생성
  • kubectl get rs 로 레플리카셋 검사 가능

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

  • 레플리카셋의 주요 개선사항은 좀 더 표현적인 셀렉터를 사용할 수 있다.
selector:
 matchExpressions:
  - key : app
       operator: In
       values:
        - kubia
  • 예시
    • In : 레이블 값이 지정된 값 중 하나와 일치해야한다.
    • NotIn :레이블 값이 지정된 값과 일치하지 않아야한다
    • Exists: 파드는 지정된 키를 가진 레이블이 포함돼야한다.
    • DoesNotExist : 파드에 지정된 키를 가진 레이블이 포함되지 않아야한다.
  • 여러 표현식을 지정하는 경오, 모든 표현식이 true 여야 셀렉터가 파드와 매칭된다.
  • matchLabels 와 matchExpressions 를 모두 지정하면, 모든 레이블이 일피하고, 모든 표현식이 true 여야한다.

4.3.5. 레플리카셋 지우기

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

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

  • 레플리케이션 컨트롤러와 레플리카셋은 쿠버네티스 내의 어딘가에 지정된 수의 파드를 실행하는데 사용된다.
  • 클러스터의 모든 노드에 노드당 하나의 파드만 실행되기를 원하는 경우가 있을 수 있다.
    • 시스템 수준의 작업을 수행해야하는 인프라 관련 파드의 경우
      • 로그 수집기, 리소스 모니터, 쿠버 프록시 프로세스
  • 쿠버네티스를 사용하지 않는 환경에서는 init script , systemd 데몬을 통해 수행된다.

img

  • 데몬셋은 각 노드에서 하나의 파드 복제본만 실행하지만, 레플리카셋은 클러스터 전체에서 무작위로 파드를 분산시킨다.

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

  • 모든 클러스터 노드마다 파드를 하나만 실행하려면, demonSet 오브젝트를 생성해야한다.
  • 데몬셋에 의해 생성되는 파드는 타깃 노드가 이미 지정돼있고, 쿠버네티스 스케줄러를 건너뛰는 것을 제외하면, 레플리케이션 컨트롤러와 레플리카셋과 굉장히 유사하다.
    • 파드가 클러스터 내에 무작위로 흩어져 배포되지 않는다.
    • 레플리카셋은 클러스터에 원하는 수의 파드 복사본이 존재하는지 확인하는 반면, 데몬셋엔 우너하는 복제본 수라는 개념이 없음
      • 파드 셀렉터와 일피하는 파드 하나가 각 노드에서 실행중인지 확인
    • 노드가 다운되면, 데몬셋은 다른 곳에서 파드를 생성하지 않음
    • 새 노드가 클러스터에 추가되면, 데몬 셋은 새 파드 인스턴스를 새 노드에 배포한다.
    • 레플리카셋과 마찬가지로 데몬셋은 그 안에 구성된 파드 템플릿으로 파드를 생성한다.

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

  • 별도의 지정을 하지 않으면, 데몬셋은 클러스터의 모든 노드에 파드를 배포한다.
  • node Selector 속성을 지정하면 된다.(3장과 유사)
  • 예제
    • Node selector:
       disk=ssd
  • img
  • 노드 셀렉터를 가지는 데몬셋을 이요해 특정노드만 시스템 파드 배포하기
  • 데몬셋 YAML 정의 생성
    • luksa/ssd-monitor컨테이너 이미지를 기반으로 컨테이너를 한 개만 갖는 데몬셋을 정의
    • disk=ssd 레이블이 있는 각 노드에 생성
  • apiVersion: apps/v1beta2
    kind: DaemonSet
    metadata:
        name: ssd-monitor
    spec:
        ...생략...
       template:
            ...생략...
            spec:
                nodeSelector:
                    disk: ssd
              ...생략...
  • 데몬셋 생성
    • kubectl create -f ssd-monitor-daemonset.yaml
  • 필요한 레이블을 노드에 추가하기
    • kubectl label node nodename dist-ssd
  • 노드에 레이블 제거
    • kubectl label node nodename disk=hdd --overwrite
  • 파드 목록 조회해서 확인해보기
    • kubectl get po

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

  • 작업 완료 후, 종료되는 태스크만실행하는 경우가 있다.
  • 레플리케이션 컨트로럴, 레플리카셋, 데몬셋은 지속적인 태스크를 실행한다.

4.5.1. 잡 리소스 소개

  • 쿠버네티스는 job 리소스를 통해 해당 기능을 지원한다.
    • 4장에서 논의된 다른 리소스와 유사하지만, 파드의 컨테이너의 내부에서 실행중인 프로세스가 성공적으로 완료되면, 컨테이너를 다시 시작하지 않는다,
    • 그렇게 되면, 파드는 완료된 것으로 간주된다.
  • 장애가 발생한 경우
    • 노드 : 해당 노드에 있던 잡이 관리하는 파드는 레플리카셋 파드와 같은 방식으로 다른 노드로 다시 스케줄링 된다.
    • 프로세스 : job 에서 컨테이너를 다시 시작할 것인지 설정 가능

  • job 리소스는 작업이 제대로 완료되는 것이 중요한 임시 작업에 유용하다.
    • 예. 데이터를 어디엔가 저장하고 있고, 데이터를 변환해 어딘가 전송해야하는 경우

4.5.2. 잡 리소스 정의

apiVersion : batch/v1
kind : Job
metadata:
 name : batch-job
spec:
 template:
  metadata:
   labels:
    app: batch-job
   spec:
    restartPolicy : OnFailure
   containes:
   - name: main
    image:luksa/batch
  • luksa.batch-job 이미지를 실행할 잡 유형의 리소스를 정의
  • 파드 스펙에서는 컨테이너에서 실행중인 프로세스가 종료될 때, 쿠버네티스가 수행할 작업 지정 가능
    • 예시는 restartPolicy 로 수행되며, 잡 파드는 무한정 실행하지 않으므로 OnFailure나 Never로 명시적으로 설정해야함

4.5.3. 파드로 실행한 잡 보기

  • kubectl get jobs
  • kubectl get po -a
  • 해당 파드의 로그 검사
    • kubectl logs batch-job-28qf4

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

예. https://greencloud33.tistory.com/25

  • 잡은 두 개 이상의 파드 인스턴스를 생성해, 병렬 또는 순차적으로 실행할 수 있다
    • job spec 의 completions와 parallelism 속성 설정해야함
  • completions: 순차적으로 잡 파드 실행
    • 완료된 pod 후에 새로운 pod를 생성하여 결과적으로는 연속적으로 5개의 pod를 실행하도록 한다.
    • ...생략...
      spec:
        completions: 5
      ...생략...
  • 병렬로 Pod 실행하기
    • parallelism : 여러 job이 병렬로 실행되도록 한다.
    • completion을 5로 하여 총 5개의 pod를 완료하도록 설정했으며,
    • 한번에 두 개까지 병렬로 실행할 수 있다.
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: multi-completion-batch-job
    spec:
    completions: 5
    parallelism: 2

  • job 스케줄링
    • job 실행 도중에, parallelism 속성을 변경할 수 있다.
    • kubectl scale job multi-completion-batch-job --replicas 3

4.5.5. JOB 파드가 완료되는데 걸리는 시간 이해하기

  • pod spec 에 activeDeadlineSeconds 속성을 설정해 파드의 실행 시간을 제한 가능하다.

4.6. job 주기적으로, 또는 한 번 실행되게 스케줄링 하기

  • 많은 배치 잡들이 특정 시간, 지정된 간격으로 반복 실행해야한다.
  • 리눅스에서 cron
  • 쿠버네티스에서는 cronjob 리소스를 만들어 구상한다.

4.6.1. 크론잡 생성하기

apiVersion: batch/v1beta1
kind : CronJob
metadata:
  name: batch-job-every-fifteen-minutes
spec:
    schedule: "0,15,30,45 * * * *"
    jobTemplete:
...생략...
  • 스케줄 설정하기
    • 분 시 일 월 요일

4.6.2. 스케줄된 잡의 실행방법

  • job resource 는 대략 예정된 시각에 크론잡 리소스에서 생성된다. (그 때, 잡은 파드를 생성한다.)
  • 예정된 시간을 너무 초과해 시작하면 안되는 경우, 크론잡 스펙에 startingDeadlineSeconds 필드를 지정해 데드라인 지정이 가능하다.
반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함