[대세는쿠버네티스] 3. [기초편] 컨트롤러

Replication Controller, ReplicaSet - Template, Replicas, Selector

강의내용

컨트롤러

  • 쿠버네티스는 선언적 선언을 하면 그 선언에 클러스터 상태를 맞추고 감시하며 항상 제어함
  • 이 역할을 컨트롤러라고 부름
  • 컨트롤러의 기본 움직임
    • 클러스터의 현재 상태를 확인 - (X)
    • 클러스터가 본래 되어 있어야 할 상태를 확인 - (Y)
    • X == Y 이면? 아무것도 하지 않는다
    • X != Y 이면? 컨테이너 시작 혹은 재시작, 특정 어플리케이션 스케일링등의 task 수행
  • 예) ReplicaSet Controller의 움직임 (replicas=3)
    • pod < 3 : Manifest file의 spec필드에 정의된 pod을 새로 만들도록 API Server에게 통지
    • pod = 3 : None
    • pod > 3 : 여분의 pod을 삭제하도록 API Server에게 통지
    • 실제로 pod을 만들거나 삭제하는 것은 kubelet이 컨테이너 런타임(Docker)에게 지시를 내려 수행
    • ‘지정된 수 pod을 실행’하는 리소스가 아닌 ‘지정된 수의 pod가 실행된 상태를 유지하기’ 위한 리소스
쿠버네티스 컨트롤러 종류
  1. kube-controller-manager
  • 클러스터 안의 리소스를 감시(watch)하고 state를 본래 되어야 할 상태로 유지
  • 클러스터의 Control plain인 master에서 움직임
  • 컨트롤러는 다양한 종류가 있으나 컨트롤러끼리 서로 직접 통신하는 일은 없음
  • 종류
    • ReplicationManager
    • ReplicaSet/DaemonSet/Job controllers
    • Deployment controllers
    • StatefulSet controllers
    • Node controllers
    • Service controllers
    • Endpoint controllers
    • Namespace controllers
  1. cloud-controller-manager
  • 클라우드 프로바이더의 독자적인 컨트롤러
  • 쿠버네티스 매니지드 서비스등에서 클라우드 자체 컨트롤러를 구축하기 위한 것
    스토리지 서비스, 로드 발란서등의 기능에 이용됨
  • 보통 해당 회사의 엔지니어가 개발에 공헌
  1. 커스텀 컨트롤러도 가능
  • 쿠버네티스는 오픈 소스 프로젝트이므로 누구나 개발에 참여해서 컨트리뷰트 가능

강의내용 - 다음과 같은 기능을 제공함으로써 서비스를 관리하고 운영하는데 도움을 줌

  • 오토힐링 - 장애대응
    • ReplicaSet은 클러스터 안에서 선언을 유지하려 한다
    • 파드나 파드가 스케쥴링 되는 노드가 이상이 있는 경우 다른 곳에 다시 생성
  • 오토스케일링 - 부하대응
    • pod의 리소스가 limit가 넘어가면 컨트롤러가 상태 파악후 pod 수를 늘림
  • 버전 업
    • 여러 pod에 대한 버전 업
    • 컨트롤러를 통해 쉽게 할 수 있으며 문제가 있는 경우 롤백을 할 수 있게 제공
  • Job
    • 일시적 작업이 필요한 경우 컨트롤러가 필요한 순간에 pod를 만들어 작업 수행후 pod 삭제
    • 그 순간에만 자원 사용 후 작업 반환 - 효율적인 자원 관리

Replication Controller 은 Deprecated 되어 ReplicaSet으로 대체됨
템플릿 기능

  • Controller와 pod는 Service와 Pod처럼 Label을 이용해서 select되서 연결됨
  • Controller를 템플릿으로 pod를 생성
  • pod가 다운되면 템플릿으로 pod를 새로 만들어주게 된다.
  • 이를 이용해서 앱 업그레이드가 가능 → template만 update해주면 pod이 업데이트 된다

Replicas

  • 컨트롤러에서 설정하는 클러스터 안에서 가동할 Pod의 갯수 (default : 1)
  • 해당 숫자를 유지하려고 쿠버네티스는 노력한다
  • 템플릿 + replicas의 조합을 하면 컨트롤러 생성만으로 pod들이 자동으로 만들어져 연동된다

Selector

  • 템플릿, Replicas와 달리 셀렉터는 Replication Controller에 없고 ReplicaSet에만 들어있는 기능
  • Replication 의 경우 레이블로 셀렉트를 하며 레이블의 키와 밸류중 하나만 달라도 연결하지 않는다
  • 어떤 pod를 가동시킬지에 대한 셀렉터
  • pod의 template에 설정된 label과 매칭
  • ReplicaSet의 셀렉터에는 2가지 추가적 속성이 존재한다
    • matchLabels : 기존 ReplicaSet의 셀렉터와 동일한 기능
    • matchExpressions : 레이블의 키와 밸류를 집합 기반(set-based)방법으로 더 정교하게 컨트롤 가능

버전관리 기능 없음

  • ReplicaSet은 지정된 수의 pod이 항상 실행되고 있다는 것을 보증하나 버전관리 기능은 없음
  • 따라서 프로젝트에서 사용할 땐 deployment를 사용해야 한다
  • replicaSet

Replication Controller 실습

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: pod1
labels:
type: web
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0 # pod 삭제 걸리는 시간 (기본 30초) - 학습시 편하다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica1
spec:
replicas: 1 # 현재 pod가 1개
selector:
matchLabels:
type: web
template: # 위의 pod내용과 완전히 같음
metadata:
name: pod1 # 한 ns에 같은 이름 중복 X → replicas 증가시 리플리카셋이름+다른문자로 만들게 됨
labels:
type: web
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0

pod을 삭제안하고 컨트롤러만 삭제

  • 위 ReplicaSet을 삭제 하면 pod도 삭제된다
  • pod을 남긴채 컨트롤러를 삭제하는 방법은 뭐가 있을까
  • delete시 옵션 --cascade=false : 대시보드에서는 불가능
  • 이 옵션을 쓰면 pod을 남긴채 컨트롤러 삭제가 가능하다
  • 예를들어서 이론 강의때 말했던 것처럼 Replication Controller → ReplicaSet 으로 바꿀 때 의 예시
ReplicationController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: ReplicationController
metadata:
name: replication1
spec:
replicas: 2
selector:
cascade: "false"
template:
metadata:
labels:
cascade: "false"
spec:
containers:
- name: container
image: kubetm/app:v1
1
2
# pod을 남긴채 컨트롤러 삭제 
kubectl delete replicationcontrollers replication1 --cascade=false
ReplicaSet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica2
spec:
replicas: 2
selector:
matchLabels:
cascade: "false"
template:
metadata:
labels:
cascade: "false"
spec:
containers:
- name: container
image: kubetm/app:v1

이렇게 하면 기존 Replica Controller에 의해 만들어졌던 pod들이
새로 만들어진 ReplicaSet에 연결된다

ReplicaSet

  • 이름에서 알수 있듯이 Pod를 복제(replicate)한다

Selector 실습

  • 일반적으로 matchLabels를 사용하고 matchExpressions는 잘 사용하지 않는다
    • 사전에 오브젝트가 미리 만들어져 있고 그 오브젝트에 여러 레이블이 붙어 있을 때
      내가 원하는 레이블을 정교하게 선택하고 싶을 떄 사용하는 기능
    • 컨트롤러에는 템플릿의 pod를 이용하면 되기 떄문에 굳이 어렵게 저런 기능을 쓸 이유가 없음
    • NodeScheduling 연습 때 사용할 예정

주의점 2가지

  1. selector의 내용이 template의 label에 포함이 되어야 한다
    그렇지 않으면 selector does not match template 에러가 발생한다
  2. matchLabelsmatchExpressions을 동시에 사용할 때는 이 모든 조건들 또한
    역시 template에 포함이 되어야 한다. 그렇지 않으면 역시 에러가 발생한다

Deployment - Recreate, RollingUpdate

앞서서 업데이트 방법 개요 설명

업데이트 전반적인 개요 - ReCreate, Rolling Update, Blue/Green, Canary

  • 디플로이먼트를 만들고 pod이 만들어졌으며 v1이미지를 사용하고 있으며 v2로 업데이트 할때
  1. ReCreate
  • 디플로이먼트가 기존 pod들을 삭제 → 서비스 downtime 발생
  • 기존 pod들이 사용하던 자원들 반환됨
  • 디플로이먼트가 신규 pod들을 다시 생성
  • downtime이 존재하므로 일시적인 서비스 정지가 가능한 서비스에서만 사용 가능
  1. Rolling Update
  • 디플로이먼트가 신규 pod을 하나 생성 : pod1개만큼 추가 작원
  • 디플로이먼트가 기존 pod을 하나 삭제
  • 위 과정 반복
  • 배포 중간에 추가적인 자원을 요구하나 요구량이 작고 zero downtime
  • 중간 단계에서 v1,v2 둘다 사용자가 접속 가능-> 특정 사용자는 다른 화면이나 다른 서비스
  1. Blue/Green
  • deployment 자체 기능 아님
    • deployment를 이용해서 사용 가능하지만 보통 replicas를 관리하는 컨트롤러를 이용해서 사용
  • 기존 ReplicaSet에서 서비스와 v1pod들을 사용하고 있음
  • 새로운 컨트롤러가 만들어지며 v2를 가진 pod들을 생성 :자원 사용량은 기존의 2배가 된다
  • 서비스에있는 selector의 레이블만 변경 : 기존v1대신 v2pod와 서비스가 연결됨
  • 문제시 서비스의 selector의 레이블만 기존 것으로 바꿈 : 롤백이 매우 쉽고 빠름
  • 문제가 없으면 기존 컨트롤러 삭제
  • zero down time, 상당히 많이 사용하는 방식이며 안정적이지만 자원 용량을 2배를 요구한다는 것
  1. Canary
  • 카나리아 - 1초에 17번 뛸정도로 심박수가 높고 공기에 민감, 광산의 가스 테스트로 사용
  • 카나리아같은 실험제로 위험도를 테스트하고 위험도가 없으면 정식 배포하는 방식
  • 불특정 다수 테스트
    • 기존 컨트롤러로 서비스와 v1 pod을 사용하고 있음
    • 여기서 ver:v1 레이블이 아닌 ty:app등의 버전과 무관한 레이블을 셀렉트해서 서비스 연결
    • 테스트 컨트롤러 생성 - replica:1,ty:app을 가진 pod 1개 생성
    • 기존과 같은 레이블이므로 자동으로 서비스에 연결이 되며 트래픽중 일부는 신규 pod으로 연결됨
    • 문제가 생기면 테스트 컨트롤러의 replica를 0으로 만든다
  • 특정 타겟 테스트
    • v1과 v2가 서비스도 따로 존재
    • Ingress Controller - 유입되는 트래픽을 url에 따라 서비스에 라우팅하는 컨트롤러 - 를 앞단
    • 특정 url로 접속시 v2 연결 - 특정지역등의 특정 타겟에게 테스트 서비스 제공
    • 문제가 없으면 v2 scale을 늘리고 Ingress에서 기존url을 서비스2에 연결후
      기존 v1 컨트롤러 삭제 : 컨트롤러, 팟, 서비스등 v1 오브젝트들 삭제됨
    • zero downtime, 테스트할 pod수와 성공시 늘리는 pod수에 따라 자원 소모 증가

Controller - Deployment - 어플리케이션의 업데이트에 도움을 주는 컨트롤러

deployment 의 ReCreate

  • Deployment에는 ReplicaSet처럼 selector, replicas, template들이 들어있음
  • 직접 deployment가 pod을 만드는 것이 아니라 ReplicaSet을 생성후 사용할 용도임
  • Deployment의 template을 v1에서 v2로 바꿈(Template Update)
    • Deployment는 기존 ReplicaSet의 replicas를 0으로 변경
    • 그러면 ReplicaSet은 기존 pod들을 제거함 - downtime 발생
    • Deployment는 새로운 ReplicaSet 생성 - 새로운 v2 pod 생성 - 서비스 자동 연결됨
    • 기존 ReplicaSet을 삭제를 하지는 않음
    • 기본값으로 10개의 컨트롤러를 남기게 되며 옵션에 따라 남기는 개수를 정할 수 있음
      1
      2
      3
      4
       # 기존 컨트롤러 1개만 남기기
      strategy:
      type: Recreate
      revisionHistoryLimit: 1

deployment의 Rolling Update(default)

  • Recreate처럼 Template update
  • 새로운 ReplicaSet(replicas:1) 생성 → v2 pod 1개 생성되어 서비스 연결됨
  • v1 replicas를 하나씩 줄이고 삭제가 완료되면 v2 replicas를 하나 늘린다 - 반복
  • minReadySeconds
    • 해당 옵션이 없으면 위의 과정이 순식간에 진행됨
    • 시간을 텀을 줄 수 있음 그러면 진행상황을 눈으로 보거나 학습하기가 편함
    • 중급편의 ReadinessProbe에 영향이 있으며 그때 다시 배울 예정

Deployment - 실습

DaemonSet, Job, CronJob

DaemonSet

  • 모든 노드에 동일한 pod를 실행시키고자 할 떄 사용하는 리소스
  • 일반적인 ReplicaSet등 스케쥴러에 의존하는 컨트롤러의 경우
    배포시 node의 남은 자원에 따라 배치하는 갯수가 다르거나 배포를 안할 수 도 있다
  • DaemonSet은 노드의 자원의 양에 상관없이 모든 노드에 pod이 1개씩 생긴다.
    만약 총 노드의 수가 10개라면, 각 노드마다 한개씩 총 10개의 pod이 생기게 된다
  • 노드마다 설치해서 사용해야하는 서비스에 사용된다
    • 성능 수집
      • 각각의 노드에서 성능 수집을 위한 에이전트등이 깔려 있어야 한다
      • 프로메테우스 등
    • 로그 수집
      • 특정 노드에 장애가 발생할 경우 문제 파악을 위해 로그를 살펴봐야 한다
      • fluentd 등
    • 스토리지 활용
      • 각 노드의 자원을 네트워크 스토리지 시스템으로 구축할 수 있다
      • GlusterFS 등
    • etc
      • 쿠버네티스 자체도 네트워킹 관리를 위해 각각의 노드에 데몬셋으로
        프록시 역할을 하는 pod을 생성한다 → kube-proxy
  • nodeselector등을 이용해 조건에 맞지 않는 노드는 필터링이 가능
  • 위의 서비스를 위해서 특정 노드를 접속시 해당 pod에 접근 가능하게 해야 유용함
    • node type Service + externalTrafficPolicy: Local으로 사용 가능
    • hostPort를 이용해 직접 노드의 포트를 Pod에 바인딩해 접근도 가능

Job

노드가 장애시 팟을 만든 주체에 따라 달라지는 pod의 모습

  • pod을 직접 만들었을 때는 해당 pod도 장애가 난 상태 → 서비스 유지 불가능
  • 컨트롤러(ReplicaSet, Job)로 만들어진 Pod는 다른 정상 노드에 Recreate된다 → 서비스 유지
  • Replicaset의 pod은 일을 하지 않으면 Restart된다 → 무슨 일이 있어도 유지되어야 하는 서비스에 사용
  • recreate vs restart
    • Recrate 는 팟이 재생성 됨 - 팟의 이름, ip등이 변경됨
    • Restart는 팟은 그대로이며 팟 내부의 컨테이너만 재기동
  • Job으로 만든 Pod은 일을 하지않으면 종료(Finish)시킨다
    • 팟이 삭제 되는 것이 아니라 자원을 사용하지 않은 상태로 멈춤
    • 해당 팟에 들어가서 로그등을 확인 가능
  • 계속적으로 서비스 유지가 아닌 실행된 후에 종료해야하는 성격의 작업을 실행할때 사용하는 컨트롤러
  • 잡패턴
    • 요약 내용 : https://skasha.tistory.com/93
    • 잡에서 파드를 병렬로 실행하였을때 파드들이 서로 통신하면서 동작하지 않는다.
      각 파드는 독립적으로 동작하는 것을 전제로 둔다.
    • 여러 개의 잡을 생성하기보다 여러 작업을 수행하는 잡 하나를 사용하는게 좋다.
      잡을 생성하는 오버헤드는 크기 때문에 작업이 많아질수록 하나의 잡에서 여러개의 작업을 처리하는게 좋다.
    • 여러 개의 파드를 생성하기보다 여러 작업을 수행하는 파드 하나를 사용하는게 좋다.
      위와 동일하게 파드를 생성하는 오버헤드는 크기 때문에 하나의 파드에서 여러개의 작업을 처리하는게 좋다.
    • Work queue를 사용한다면 카프카나 RabbitMQ 같은 큐 서비스를 워크 큐로 구현하도록
      기존 프로그램이나 컨테이너를 수정해야한다.
      워크 큐를 사용하지 않으면 그냥 기본 설정 그대로 컨테이너를 사용하므로 비효율적이다
  • activeDeadlineSeconds
    • 해당 시간이 지나면 생성된 pod들을 전부 삭제한다

CronJob

  • 잡을 시간 기준으로 관리하도록 하며,
    지정한 시간에 잡을 실행하거나 주기적으로 잡을 반복 실행할 수 있다
  • 일반 서비스에서 crontab에 해당하는 위치
  • DB 일일 백업, 커머스 일일 정산처리, 주기적인 업데이트 확인, 일일 sms 발송
  • jobtemplate을 이용해서 job 생성
  • schedule은 흔히 사용하는 cron 포맷으로 지정 가능
  • concurencyPolicy - 동시성 정책
    • Allow
      • 기존 실행된 작업의 실행/종료에 상관없이 새로운 job 생성
    • Forbid
      • 기존 pod의 수행이 끝나지 않았으면 해당 시점을 skip
    • Replace
      • 기존 pod이 계속 러닝중이라면 새 pod을 만들고 기존 job의 연결을 새 pod로 연결
      • 새로운 job은 생기지 않지만 새로운 pod는 생기게 됨

그밖에

StatefulSet

StatefulSet

  • Stateful한 pod를 생성해야 하는 경우 사용

  • Deployment, ReplicaSet과 다르게 복제된 pod이 완벽하게 동일(identical)하지 않음

  • 순서에 따라 고유의 역할을 가짐

    • 각 pod의 순서와 고유성을 보장
    • 즉 pod이 삭제되면 Deployment처럼 다른 pod으로 대체가 불가능을 의미함
  • 동일한 이미지를 이용해서 pod을 생성하나 실행시, 각기 다른 역할을 가지며
    서로의 역할을 교체하지 못할 때 사용

  • 프로세스간 서로 치환 될 수 없는 클러스터를 구축할 때 많이 사용

    • 동일한 프로세스가 실행 순서에 따라 master-worker가 결정되는 경우(pod끼리 순서에 민감한 어플리케이션)
    • 고유의 pod 식별자가 필요한 경우
    • 명시적으로 pod마다 저장소가 지정되어야 하는 경우: 1번디스크는 pod1, 2번디스크는 pod2
    • 어플리케이션이 순서대로 업데이트 되어야 하는 경우
  • 좋은 사용 예시 : MySQL DB 클러스터 구축 예제

컨트롤러 정리

  • 쿠버네티스는 모든 것을 리소스로 표현
  • 블럭 처럼 작은 단위의 리소스를 조합해서 점점 더 큰 리소스로 만듬
  • 컨테이너 > pod > ReplicaSet > Deployment + Service = 컴포넌트화 > 조합 > 거대 어플리케이션

Related POST

공유하기