본문으로 바로가기

쿠버네티스 정리2

category 나의 주니어 개발 일기/쿠버네티스 2026. 3. 23. 09:58
728x90
반응형
SMALL

Controller

Auto Healing, Software Update, Auto Scaling, Job 의 기능들을 제공한다.(- 표시는 추후 중급과정에서)


Controller 옵션


Template

  • Controller와 Pod는 Service와 Pod 처럼 label과 selector로 연결된다.
  • selector를 선언하고 template에 label을 선언한다. 버전 변경시에는 기존 pod만 죽이면 controller는 다시 되살리려는 특성을 갖고있기 때문에 그 특성을 이용해서 새로운 버전을 올리기 용이하다.

Replicas

  • replicas 숫자만큼 pod의 개수가 관리된다. replicas가 3개이면 pod도 3개로 scale out하여 만들어준다
  • pod에 대한 내용이 없으면 replicas가 동작하지 않게된다. pod와 controller를 따로 만들지 않고 한번에 만들 수 있는데 templete에 선언된 pod의 내용을 기반으로 연결되어 사용된다.

Selector

  • replication의 selector는 같은 정보를 갖고 있는 pod의 label을 보고 pod와 연결해주고 정보가 하나라도 일치하지 않으면 연결되지 않는다.
  • 반면 replicaSet에는 selector에 matchLabels 속성을 사용하여 같은 정보(key와 value값이 같아야한다)를 갖고 있는 pod들과 연결되며, matchExpressions 속성을 사용하여 value는 다르지만 key값이 같은 정보들을 갖고 있는 pod들을 연결할 수도 있다.
    • matchExpressions 의 value를 담당하는 operator 값에는 4가지가 있다.
    • Exists: 키값이 같은 pod만 연결
    • DoesNotExist:: 키값이 다른 pod만 연결
    • In: 키값이 같고 value가 하나라도 포함된 pod와 연결
    • NotIn: 키값이 같고 value가 하나라도 포함되지 않은 pod와 연결

예제

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replica2
spec:
  replicas: 1
  selector:
    matchLabels:
      type: web
      ver: v1
    matchExpressions:
    - {key: type, operator: In, values: [web]}
    - {key: ver, operator: Exists}
  template:
    metadata:
      labels:
        type: web
        ver: v1
        location: dev
    spec:
      containers:
      - name: container
        image: kubetm/app:v1
      terminationGracePeriodSeconds: 0


Deployment


ReCreate

  • Recreate로 Deployment 배포시 먼저 기존 버전들이 다운되고 새로운 버전이 생성된다.
  • 다운 되는 순간 Downtime이 발생하기 때문에 일시적인 서비스 정지가 가능한 서비스에만 사용해야한다.

예제

deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-1
spec:
  selector:
    matchLabels:
      type: app
  replicas: 2
  strategy:
    type: Recreate
  revisionHistoryLimit: 1
  template:
    metadata:
      labels:
        type: app
    spec:
      containers:
      - name: container
        image: kubetm/app:v1
      terminationGracePeriodSeconds: 10

service

apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  selector:
    type: app
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080

신규버전(v2)으로 업그레이드시

# kubectl set image deployment <deployment-name> <container-name>=<image>
$ kubectl set image deployment deployment-1 container=kubetm/app:v2

이전 버전으로 롤백시

# 특정 버전으로 롤백하기
$ kubectl rollout undo deployment deployment-1 --to-revision=1
# 롤백 버전 리스트 확인
$ kubectl rollout history deployment deployment-1

버전 업그레이드 확인해보기

$ while true; do curl <service-ip>:8080/version; sleep 1; done

Rolling Update

  • rolling update로 배포시 먼저 신규 버전이 1개씩 생성되며 그에 따른 추가적인 자원사용량이 발생한다.
  • 신규 버전이 다 생성되었으면 자동으로 기존 버전들을 삭제한다.
  • 배포 과정에서 기존버전과 신규버전이 공존하는 시간이 있는데 그사이에 사용자들이 서로 다르게 버전을 사용하게 될 수도 있다.
  • 추가적인 자원 사용량이 발생하지만 Downtime이 없다는게 장점이다

예제

deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-2
spec:
  selector:
    matchLabels:
      type: app
  replicas: 2
  strategy:
    type: RollingUpdate
  minReadySeconds: 10
  template:
    metadata:
      labels:
        type: app
    spec:
      containers:
      - name: container
        image: kubetm/app:v1
      terminationGracePeriodSeconds: 0

service

apiVersion: v1
kind: Service
metadata:
  name: svc-2
spec:
  selector:
    type: app
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080

업데이트시 기존 deployment의 내부 이미지 버전 수정(kubetm/app:v1 -> kubetm/app:v2)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-2
spec:
  selector:
    matchLabels:
      type: app
  replicas: 2
  strategy:
    type: RollingUpdate
  minReadySeconds: 10
  template:
    metadata:
      labels:
        type: app
    spec:
      containers:
      - name: container
        image: kubetm/app:v2
      terminationGracePeriodSeconds: 0

Blue/Green

  • Deployment 자체기능으로도 있지만 Controller 를 사용하여 이번편을 설명한다.
  • 배포하는 Pod의 라벨을 분리하여 배포한다. Service에는 타겟 라벨만 변경해주면 된다.
  • 순간적으로 변경이 되기 때문에 Downtime이 없다.
  • 신규버전 배포시에 문제가 있다면 Service의 라벨만 이전버전으로 변경해주면 되기 때문에 문제시 롤백이 쉽다는 장점이 있다.
  • 최종 배포후에 문제가 없을때만 이전 버전의 Pod를 삭제해주면 된다. 다만 그전까지 이전버전,신규버전의 자원 사용량이 발생하기 때문에 이 부분만 단점이다.
  • 실무에서 자주 사용하는 방식이다.

예제

ReplicaSet

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replica1
spec:
  replicas: 2
  selector:
    matchLabels:
      ver: v1
  template:
    metadata:
      labels:
        ver: v1
    spec:
      containers:
      - name: container
        image: kubetm/app:v1
      terminationGracePeriodSeconds: 0

Service

apiVersion: v1
kind: Service
metadata:
  name: svc-3
spec:
  selector:
    ver: v1
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080

Update할 새 ReplicaSet(replica2) 생성 후 Service(svc-3)의 Selector를 변경하여 트래픽 변경

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replica2
spec:
  replicas: 2
  selector:
    matchLabels:
      ver: v2
  template:
    metadata:
      labels:
        ver: v2
    spec:
      containers:
      - name: container
        image: kubetm/app:v2
      terminationGracePeriodSeconds: 0

Service의 Selector 수정

apiVersion: v1
kind: Service
metadata:
  name: svc-3
spec:
  selector:
    ver: v2
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080

Canary

  • 카나리아는 1초에 17번 숨을 쉬는 새다. 공기중 유해한 물질이 있으면 빨리죽는다. 그래서 광산안에 일산화탄소를 감지하는 역할로 많이 사용했다고 한다. 위험을 감지하는 느낌쓰
  • 방법1. Pod의 type,version으로 배포를 관리한다. 신규 버전 배포 문제가 될시 v2(신규버전) controller에 replicas만 0으로 만들면 된다. 배포를 해두면 누군가는 v1로 누군가는 v2로 서비스를 이용하게된다. 해당 방식은 불특정 다수를 테스트할때 사용하는 방식이다.

  • 방법2. 기존버전과 신규버전 각각 Service를 만들고, Ingress Controller에서 url로 패킷을 분리하여 전달해준다
  • 이렇게 특정 타겟을 위하여 테스트및 배포가 가능하게 된다.(ex) 해외 사용자/국내 사용자 접속시 다른 서비스로 대응)

  • Blue/Green 방식과 마찬가지로 Downtime은 없지만 자원 사용량이 2배가 될 수 있다.



Controller - DaemonSet, Job ,CronJob


목적

DaemonSet

  • 노드의 자원 여부와 상관 없이 모든 노드에 pod가 1개씩 생성되는 특징이 있다. 만약 노드가 10개면 각 노드에 pod1개씩 총 pod 10개가 생성되는 것이다.
  • 성능 수집 에이전트(prometheus), 로그 수집(fluentd), 스토리지(GlusterFS) 에 주로 사용된다.

Job, CronJob

  • Pod들이 Node1에서 돌아갈때 Node1이 down되었을때 controller에 의해서 만들어진 pod들은 장애를 감지하여 Node2에 pod를 재생성하는 등으로 장애 대응이 가능하게 된다.(ReplicaSet, Job)
  • ReplicaSet 에서 Recreate: pod를 다시 만들어주기때문에 pod의 ip나 이름이 변경된다, Restart: pod는 그대로 있고 pod 안에 컨테이너만 재기동 시켜준다
  • 반면 Job으로 만들어진 pod는 프로세스가 일을 하지 않으면 pod가 종료(자원을 사용하지 않는 상태로 멈춤, 없어지는것은 아님)
  • CronJob들은 이런 Job들을 주기적으로 생성하는 역할을 한다.(특정 시간에 반복적으로 사용할 목적으로 사용, db백업, 주기적 업데이트, 메일/sms 메시지 발송)

특징


DaemonSet

  • selector와 template으로 모든 node에 Pod를 만든다.
  • nodeSelector를 통해 os를 지정하여 특정 os에서 돌아가는 pod만 연결할 수도 있다. 지정하지 않으면 모든 node에 생긴다
  • 아래와 같이 NodePort 타입의 Service를 만들때 extarnalTrafficPolicy: Local 옵션을 설정하면 특정 노드의 nodePort를 외부에서 접근했을때 Service로 연결이 된다. 이와 같이 DaemonSet에서도 hostPort 옵션을 사용하면 외부에서 hostPort로 접근하면 containerPort 를 통해서 각 노드의 pod로 연결해준다.

예제1(hostPort)

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-1
spec:
  selector:
    matchLabels:
      type: app
  template:
    metadata:
      labels:
        type: app
    spec:
      containers:
      - name: container
        image: kubetm/app
        ports:
        - containerPort: 8080
          hostPort: 18080

예제2(NodeSelector)

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:v1
        ports:
        - containerPort: 8080

Job

  • template에는 특정 작업만 하고 종료하는 pod들만 담아둔다. selector는 직접 만들지 않아도 Job이 만들어준다.
  • completions 옵션을 사용하면 pod를 completions 개수 만들고 모두 작업을 완료해야 Job이 종료된다.
  • parallelism 옵션을 사용하면 pod가 생성시 동시에 parallelism 개수만큼 생성된다.
  • activeDeadlineSeconds 옵션을 사용하면 설정 시간 후에 모든 Job은 종료된다. 특정 작업에 행이 걸릴꺼 같을때 자원을 릴리즈 하기위해 사용한다.
  • template에서 pod를 만들때 restartPolicy 옵션을 필수값이다.(Never / onFailure) 해당 옵션은 추후 Pod 파트에서 자세히 설명

예제1

apiVersion: batch/v1
kind: Job
metadata:
  name: job-1
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: container
        image: kubetm/init
        command: ["sh", "-c", "echo 'job start';sleep 20; echo 'job end'"]
      terminationGracePeriodSeconds: 0

예제2

apiVersion: batch/v1
kind: Job
metadata:
  name: job-2
spec:
  completions: 6
  parallelism: 2
  activeDeadlineSeconds: 40
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: container
        image: kubetm/init
        command: ["sh", "-c", "echo 'job start';sleep 20; echo 'job end'"]
      terminationGracePeriodSeconds: 0

CronJob

  • jobTemplate을 통해 job을 만들어준다. schedule 통해 주기적으로 job을 생성한다.
  • concurrencyPolicy 라는 옵션이 있는데 설정하지 않으면 Allow값이 default로 적용된다.
  • Allow: schedule 주기마다 pod가 생성된다 , Forbid: schedule 주기마다 pod가 생성되지만 기존 Job이 안끝났으면 생성을 skip하고, 기존 Job이 종료되었으면 생성한다, Replace: 기존 Pod를 삭제하고 새로운 Job과 Pod가 주기적으로 생성된다.

예제

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cron-job
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: container
            image: kubetm/init
            command: ["sh", "-c", "echo 'job start';sleep 20; echo 'job end'"]
          terminationGracePeriodSeconds: 0

예제2(concurrencyPolicy 옵션)

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cron-job-2
spec:
  schedule: "20,21,22 * * * *"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: container
            image: kubetm/init
            command: ["sh", "-c", "echo 'job start';sleep 140; echo 'job end'"]
          terminationGracePeriodSeconds: 0

demonset, job, cronjob, node 삭제 명령어들

$ kubectl delete ds daemonset-1 daemonset-2
$ kubectl delete job job-1 job-2
$ kubectl delete cronjob cron-job cron-job-2 cron-job-3

// Node에 라벨 삭제
$ kubectl label nodes k8s-worker1 os-
$ kubectl label nodes k8s-worker2 os-
728x90
반응형
LIST