Kubernetes - Controller (DaemonSet, Job, CronJob)
Devops/Kubernetes

Kubernetes - Controller (DaemonSet, Job, CronJob)

뉴비뉴 2020. 5. 27.

DeamonSet

노드들이 있고, 자원이 다르게 남아 있는 상태에서 ReplicaSet을 이용하여 팟을 생성하게 되면

노드들 중에서 자원이 여유로운 노드에 팟을 생성하게 됩니다.

자원이 별로 없다면 팟을 배치를 안할 수도 있습니다.

 

데몬셋은 자원 상태와 상관없이 모든 노드에 한 개의 팟을 생성하게 되어 있습니다.

자원이 부족한 노드에도 생성할 정도면 정말 필요한 기능을 가진 팟인가 봅니다.

 

데몬셋으로 생성하는 것들은 대표적으로

1. 성능 수집(Prometheus)

2. 로그 수집(Fluentd) 

3. Storage(GlusterFS) 

 

selector와 template가 있어서 모든 노드에 템플릿으로 팟을 만들고, 셀렉터와 라벨로 데몬셋과 연결됩니다. nodeSelector로 특정 노드의 지정한 라벨에만 생성하게도 설정해줄 수 있습니다. 

데몬셋 팟은 한 개 이상으로는 만들 수는 없지만 생성하지 않을 수는 있습니다.

특정 노드로 접근을 했을 때 특정 노드에 들어있는 팟에 접근이 되도록 사용할 수도 있습니다.

hostPort로 설정해서 직접 노드에 있는 포트가 팟에 연결되어 같은 결과를 얻을 수 있습니다.

spec:
  nodeSelector:
    os: centos
  containers:
  - name: container
    image: tmkube/app
    ports:
    - containerPort: 8080  # 해당 파드의 8080로 연결이 된다.
      hostPort: 18080  # hostPort로 요청이 들어오면

실습

DeamonSet HostPort

minikube로 실습을 진행하였기 때문에 한 개의 노드에서 테스트 했습니다.

$ kubectl describe node  # Node IP를 확인합니다.

Node IP 확인

hostPort를 이용하여 직접 노드에 있는 팟에 연결해보겠습니다.

curl 172.17.0.2:18080/hostname 으로 요청하게되면 

위와 같은 결과를 확인해볼 수 있고, kubectl get pod 을 해보면 똑같은 이름의 Pod이 보이는 걸 확인할 수 있습니다. 한가지 아쉬운 점은 DaemonSet이라는 기능 자체가 모든 노드에 한 개씩 생성된다는 점이 특징인데 minikube 에서는 한 개의 노드만 운용이 가능(?) 하기 때문에 테스트가 어려운 점이 아쉽습니다.

 

DeamonSet NodeSelector

각각의 노드에 라벨을 달아서 NodeSelector에 선택 된 노드만 생성이 되는지 확인하는 실습입니다.

 

yaml 파일을 생성해주시고,

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-2
spec:
  selector:
    matchLabels:
      type: app
  template:
    metadata:
      labels:
        type: app
    spec:
      nodeSelector:
        os: centos
      containers:
      - name: container
        image: kubetm/app
        ports:
        - containerPort: 8080

노드에 라벨을 지정해주겠습니다.

kubectl label nodes minikube os=centos

 

kubectl create -f <파일명.yaml> 

 

yaml 파일 안에 nodeSelector가 Key는 os, Values는 centos를 가리키고 있습니다.

minikube node의 라벨을 centos로 지정해줬기 때문에 Pod이 제대로 생성되는 것을 확인할 수 있었습니다.

 

반대로 ubuntu로 변경하기 위해 k delete daemonset <name> 삭제해주고,

kubectl label nodes minikube os=ubuntu --overwrite 하여 강제로 ubuntu 로 덮어씌웠습니다.

*--overwrite를 사용하지 않으면 에러가 발생합니다.

 

Job

특정 노드에서 팟이 돌아가고 있는 상태에서 노드가 죽게 되었다고 가정하겠습니다.

컨트롤러에 의해서 만들어진 팟들은 다른 노드에 재성성되지만, 그렇지 않은 팟은 다운되어 서비스를 할 수 없습니다.

레플리카셋에서 만들어진 팟은 일을 하지 않는다면 Restart하기 때문에 팟에 대한 서비스는 무슨 일이 있어도 서비스가 유지되는 목적으로 사용해야 한다.

 

template과 selector가 있습니다.

template에는 특정 작업만 하고 종료가 되는 팟을 담게 됩니다.

selector는 직접 만들지 않아도 Job이 알아서 만들어줍니다.

 

template를 가지고 한 개의 팟을 생성하고, 임무가 종료되면 삭제가 됩니다.

추가로 completions: 6을 주면 6개의 파드를 하나씩 순차적으로 실행하여 모두 종료되여 잡이 종료된다.

parallelism: 2 로 동시에 수행할 수 있고, activateDeadlineSeconds: 30을 주면 해당 Job을 30초 뒤에 기능이 종료된다.

실행되고 있던 모든 팟과 실행되려고 대기하고 있던 팟들도 실행이 안됩니다.

 

completions, parallelism, activateDeadlineSeconds는 spec에 명시할 수 있습니다.

추가로 template에 restartPolicy를 설정해주어야 됩니다.

해당 yaml 파일은 실습할 때 상세히 적도록 하겠습니다.

 

 

 

ReplicaSet Pod

Recreate는 팟을 다시 만들어주기 때문에 팟의 이름이나 IP들이 변경되고,

Restart는 팟은 그대로 있고, 안에 컨테이너만 재생성 시켜준다.

 

Job Pod

프로세서가 일을 하지 않으면 팟을 종료된다. (삭제된다는 의미가아닌 자원을 사용하지 않는 상태로 중지)

팟 안에서 로그를 확인할 수 있고, 삭제를 해줄 수도 있다.

 

실습

 

 

CronJob

Job들을 주기적인 시간에 따라서 생성하는 역할을 합니다.

Job을 하나 단위로 사용하지 않고, 보통 CronJob으로 사용합니다.

 

ex) 매일 새벽마다 정기적으로 DB 백업을 하고, 주기적인 업데이트 확인, 예약 메일 SMS 메시지 전송 작업

 

CronJob은 Job 템플릿이 있어서 Job을 만들어주고, 스케쥴이 있어서 시간을 주기로 Job을 생성합니다.

schedule: */1 * * * * 이렇게 설정하면 1분 간격으로 Job이 생성되고, Job은 Pod을 생성시키게 됩니다.

옵션으로는 concurencyPolicy라는 옵션이 있는데 Default는 Allow로 되어있고, Forbid와 Replace가 추가 옵션으로 존재합니다. 

 

concurencyPolicy

Allow는 1분 마다 하나씩 Job과 Pod을 생성합니다.

Forbid는 1분에 하나를 생성하고, 생성 된 Job과 Pod이 아직 존재한다면 2분에 생성해야 될 동작을 스킵하게 됩니다.

그리고 Pod가 종료되는 즉시 다음 스케쥴 타임에 있는 Job이 생성됩니다.

Replace는 1분에 Job이 만들어지고, 1분에 만들었던 Pod이 작업중이라면 해당 잡으로 2분에 Pod를 생성하여 연결해줍니다. 만약 2분에 만든 파드가 자신의 스케쥴 타임에 종료하게 된다면 다음 스케쥴 때 Job과 Pod이 생성하게 됩니다.

 

그 밖에 실행중인 Job을 일시중지하는 옵션인 Suspend도 있고, Manual Trigger 매뉴얼별로 트리거도 할 수 있습니다.

 

 

 

댓글

💲 추천 글