본문 바로가기
2023~/쿠버네티스 인 액션

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

by 경아ㅏ 2024. 10. 10.

 
4.1 파드를 안정적으로 유지하기
 
라이브니스 프로브

1) 파드 내 컨테이너에 크래시가 발생하면 Kubelet 이 자동으로 컨테이너를 재시작
2) 크래시가 발생하여 종료된 것이 아니더라도 무한 루프, 교착 상태에 빠져있거나 OutofMemoryErrors 를 뱉어내는 등 오류가 있을 수 있기 때문에 애플리케이션 외부에서 해당 컨테이너 상태를 지속적으로 체크하는 시스템 필요 (라이브니스 프로브)
 
 
라이브니스 프로브 종류

1) HTTP GET 프로브: 특정 ip, 포트, 경로로 HTTP 요청 후 응답 결과가 실패(4xx, 5xx) 혹은 응답 없음일 경우 컨테이너 재시작
2) TCP 소켓 프로브: 컨테이너의 지정 포트에 TCP 연결 시도하여 연결 실패할 경우 컨테이너 재시작
3) Exec 프로브: 컨테이너 내에서 임의의 명령을 실행하고 실행 결과가 0이 아닐 경우 컨테이너 재시작

 
 
HTTP 기반 라이브니스 프로브 생성

 
1) 파드를 생성하는 yaml 파일에 라이브니스 프로브 명시

apiVersion: v1
kind: Pod
metadata:
  name: kubia-liveness
spec:
  containers:
  - image: luksa/kubia-unhealthy
    name: kubia
    livenessProbe:
      httpGet:
        path: /
        port: 8080

 
 
2) 파드 생성

Kubectl create -f kubia-liveness.yaml

 
 
3) pod 확인

(파드 안의 컨테이너 애플리케이션은 5번까지 요청을 정상적으로 받고 이후 부터는 실패 처리)
라이브니스 프로브 요청으로 인해 파드가 종료되고 재시작 되는 것을 확인 가능 (Restart)
 

NAME             READY   STATUS    RESTARTS       AGE
kubia-liveness   1/1     Running   7 (3m2s ago)   12m

 
 
4) describe 명령어로 파드 종료 상황, 라이브니스 프로브 정보 확인

Containers:
  kubia:
    Image:          luksa/kubia-unhealthy
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 08 Oct 2024 16:43:00 +0900
    Last State:     Terminated
      Reason:       Error
      Exit Code:    143 // 128 + 15(SIGTERM)
      Started:      Tue, 08 Oct 2024 16:41:40 +0900
      Finished:     Tue, 08 Oct 2024 16:42:58 +0900
    Ready:          True
    Restart Count:  2
    Liveness:       http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:    <none>

 
 
5) 라이브니스 프로브 동작 세부 속성 지정

  • delay: 애플리케이션 시작 후 몇초 후에 라이브니스 프로브 실행할 것인지 지정
  • timeout: 응답 제한 시간 지정
  • period: 실행 주기 지정

 

apiVersion: v1
kind: Pod
metadata:
  name: kubia-liveness
spec:
  containers:
  - image: luksa/kubia-unhealthy
    name: kubia
    livenessProbe:
      httpGet:
        path: /
        port: 8080
      initialDelaySeconds: 15 // 15초 지연 설정, delay=0 으로 두면 프로그램 실행에 필요한 모든 것들이 셋팅 되지 않았는데 라이브니스 프로브가 실행될 수 있음

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

 
 

레플리케이션컨트롤러로 관리되는 파드는 사라졌을 때 복제되어 새로 생성
(cf. 레플리케이션컨트롤러가 관여하지 않는 파드는 유실)
 

레플리케이션 컨트롤러의 세가지 요소

1) 레이블 셀렉터(레플리케이션이 관리하는 파드의 범위 설정)
2) 레플리카 수(의도된 파드 개수)
3) 파드 템플릿(새로 파드를 만들 때 사용)
 
레플리케이션컨트롤러는 레이블 셀렉터와 매치되는 파드를 선택한 후 현재 파드 수와 레플리카 수를 비교하여 부족한 만큼 파드 템플릿을 통해 새로운 파드 생성(넘치는 경우 제거)

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

yaml 파일에 레플리케이션컨트롤러 이름, 의도하는 파드 인스턴스 수, 파드 셀렉터, 파드 템플릿 등을 기술
레플리케이션컨트롤러의 파드 셀렉터 레이블은 지정하지 않는 것이 좋음(파드 템플릿에 설정된 레이블 이름을 그대로 가져와 사용하도록)
 

apiVersion: v1
kind: ReplicationController
metadata:
  name: kubia
spec:
  replicas: 3 // 레플리카 수
  selector:
    app: kubia // 파드 셀렉터 (app=kubia 라벨을 가지는 파드에 대하여 관리)
  template: // 파드 템플릿
    metadata:
      labels:
        app: kubia 
    spec:
      containers:
      - name: kubia
        image: luksa/kubia
        ports:
        - containerPort: 8080

 

kubectl create -f kubia-rc.yaml

kubectl get pods

NAME          READY   STATUS              RESTARTS   AGE
kubia-c2b4v   0/1     ContainerCreating   0          3s
kubia-fbcf8   0/1     ContainerCreating   0          3s
kubia-ltggr   1/1     Running             0          3s

 
 
파드 삭제

레플리케이션컨트롤러에 의해 새로운 파드 생성

NAME          READY   STATUS    RESTARTS   AGE
kubia-fbcf8   1/1     Running   0          38s
kubia-ltggr   1/1     Running   0          38s
kubia-pf57f   1/1     Running   0          3s

 
 
관리 되는 파드의 레이블을 변경
 
특정 파드의 label 을 레플리케이션컨트롤러 파드 셀렉터와 다른 값으로 변경하면 해당 파드는 관리 대상에서 제외되고 새로운 파드 생성
 

kubectl label pods kubia-pf57f app=foo --overwrite

 

kubectl get pods --show-labels

 

NAME          READY   STATUS    RESTARTS   AGE   LABELS
kubia-fbcf8   1/1     Running   0          18m   app=kubia
kubia-ltggr   1/1     Running   0          18m   app=kubia
kubia-pf57f   1/1     Running   0          17m   app=foo // foo 가 된 파드는 관리 대상에서 제외
kubia-vpjwr   1/1     Running   0          21s   app=kubia // 새로 생긴 파드

 
 
레플리케이션의 파드 셀렉터 변경
 
이전 셀렉터를 가진 파드들은 관리에서 벗어나고 부족한 만큼 새로운 파드를 생성
(근데 이거는 생각해보면 좀 이상한거 같다... 어짜피 템플릿의 라벨과 라벨 셀렉터는 같아야 하고 - 관례적으로, 파드 셀렉터 값만 바꾸는 것은 이상하니까 템플릿의 라벨도 같아야 하고...? 그러면 사실 해당 레플리케이션 컨트롤러를 삭제하고 다른 레플리케이션 컨트롤러를 만들면 되는거 아닌가...)

 
파드 템플릿 변경
 
파드 템플릿이 변경되어도 이전 파드들에는 영향이 없고 기존 파드를 삭제했을 때 새로운 파드 템플릿으로 파드 생성
 
 

 

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

 

레플리카셋 = 차세대 레플리케이션컨트롤러

레플리카셋은 레플리케이션컨트롤러에 비해 파드 셀렉터 표현식을 정교하게 사용 가능
(레플리케이션 컨트롤러에서는 특정 라벨 키=값을 갖는 파드만 셀렉 가능하지만, 레플리카셋에서는 특정 라벨 자체를 가지는/가지지 않는, 라벨 키에 대한 복수의 값 중에서 하나를 갖는/갖지 않는 셀렉터를 만들어 사용할 수 있다)

 

apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
  name: kubia
spec:
  replicas: 3
  selector:
    matchExpressions: // app=kubia 라벨 셀렉터
      - key: app
        operator: In
        values:
         - kubia
  template:
    metadata:
      labels:
        app: kubia
    spec:
      containers:
      - name: kubia
        image: luksa/kubia

 


matchExpression operator

 

  • In: 레이블 값이 지정된 값 중 하나와 일치해야
  • NotIn: 레이블 값이 지정된 값과 일치하지 않아야 
  • Exists: 지정된 키를 가진 레이블을 포함해야 (값 지정 X)
  • DoesNotExist: 지정된 키를 가진 레이블이 포함되지 않아야 (값 지정 X)

 

 

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

 

데몬셋을 이용하면 특정 라벨이 붙어있는(혹은 모든 노드)에 각각 하나의 파드만 실행 가능
(e.g 로그 수집기, 모니터 애플리케이션, kube-proxy 등의 파드는 하나의 노드에 하나만 실행되어야 함)

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ssd-monitor
spec:
  selector:
    matchLabels:
      app: ssd-monitor // 근데 matchLabels 정보는 왜 필요한 거지?? nodeSelector 만 있으면 되는거 아닌가??
  template:
    metadata:
      labels:
        app: ssd-monitor
    spec:
      nodeSelector: // 어떤 라벨이 붙은 노드에 파드를 배포할 것인지 기술
        disk: ssd
      containers:
      - name: main
        image: luksa/ssd-monitor

 

 

노드에 label 지정시 데몬셋이 파드 배포(노드에서 label 제거시 파드는 자동 종료됨)

 

kubectl label node minikube disk=ssd

 

NAME                READY   STATUS    RESTARTS   AGE
kubia-fbcf8         1/1     Running   0          39h
kubia-ltggr         1/1     Running   0          39h
kubia-pf57f         1/1     Running   0          39h
kubia-vpjwr         1/1     Running   0          39h
ssd-monitor-fjgw5   1/1     Running   0          5m27s

 

 

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

잡은 실행 완료된 파드를 종료하는 리소스
일반적으로 레플리카셋은 지속적으로 파드를 실행하지만 잡은 실행 완료된 잡은 종료시킴(로그를 봐야 하므로 삭제 시키진 않는다)

apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure // 재시작 옵션 - OnFailure(실패할 때), Never(재시작 하지 않음)
      containers:
      - name: main
        image: luksa/batch-job

 

 

잡을 실행하면 파드가 만들어져 실행하고 실행 완료되면 Completed 처리 되는 것을 확인

 

// 파드 확인
NAME                READY   STATUS      RESTARTS   AGE
batch-job-2t4lz     0/1     Completed   0          3m30s

// 잡 확인
NAME        STATUS     COMPLETIONS   DURATION   AGE
batch-job   Complete   1/1           2m7s       8m18s

 

 

잡 파드를 순차적으로/병렬로 여러번 실행하기

apiVersion: batch/v1
kind: Job
metadata:
  name: multi-completion-batch-job
spec:
  completions: 5 // 몇 개의 파드를 실행할 것인지 설정
  parallelism: 2 // parallelism 을 설정하면 병렬 실행, 해당 옵션 없으면 순차 실행
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job

 

 

크론잡 생성하기

cron 식을 기술하여 특정 시간(시각) 마다 파드를 생성/실행

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



댓글