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가 실행된 상태를 유지하기’ 위한 리소스
- pod < 3 : Manifest file의
쿠버네티스 컨트롤러 종류
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
cloud-controller-manager
- 클라우드 프로바이더의 독자적인 컨트롤러
- 쿠버네티스 매니지드 서비스등에서 클라우드 자체 컨트롤러를 구축하기 위한 것
스토리지 서비스, 로드 발란서등의 기능에 이용됨 - 보통 해당 회사의 엔지니어가 개발에 공헌
- 커스텀 컨트롤러도 가능
- 쿠버네티스는 오픈 소스 프로젝트이므로 누구나 개발에 참여해서 컨트리뷰트 가능
강의내용 - 다음과 같은 기능을 제공함으로써 서비스를 관리하고 운영하는데 도움을 줌
- 오토힐링 - 장애대응
- 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 | apiVersion: v1 |
1 | apiVersion: apps/v1 |
pod을 삭제안하고 컨트롤러만 삭제
- 위 ReplicaSet을 삭제 하면 pod도 삭제된다
- pod을 남긴채 컨트롤러를 삭제하는 방법은 뭐가 있을까
- delete시 옵션
--cascade=false
: 대시보드에서는 불가능 - 이 옵션을 쓰면 pod을 남긴채 컨트롤러 삭제가 가능하다
- 예를들어서 이론 강의때 말했던 것처럼 Replication Controller → ReplicaSet 으로 바꿀 때 의 예시
1 | apiVersion: v1 |
1 | # pod을 남긴채 컨트롤러 삭제 |
1 | apiVersion: apps/v1 |
이렇게 하면 기존 Replica Controller에 의해 만들어졌던 pod들이
새로 만들어진 ReplicaSet에 연결된다
ReplicaSet
- 이름에서 알수 있듯이 Pod를 복제(replicate)한다
Selector 실습
- 일반적으로
matchLabels
를 사용하고matchExpressions
는 잘 사용하지 않는다- 사전에 오브젝트가 미리 만들어져 있고 그 오브젝트에 여러 레이블이 붙어 있을 때
내가 원하는 레이블을 정교하게 선택하고 싶을 떄 사용하는 기능 - 컨트롤러에는 템플릿의 pod를 이용하면 되기 떄문에 굳이 어렵게 저런 기능을 쓸 이유가 없음
- NodeScheduling 연습 때 사용할 예정
- 사전에 오브젝트가 미리 만들어져 있고 그 오브젝트에 여러 레이블이 붙어 있을 때
주의점 2가지
- selector의 내용이 template의 label에 포함이 되어야 한다
그렇지 않으면selector does not match template
에러가 발생한다 matchLabels
와matchExpressions
을 동시에 사용할 때는 이 모든 조건들 또한
역시 template에 포함이 되어야 한다. 그렇지 않으면 역시 에러가 발생한다
Deployment - Recreate, RollingUpdate
앞서서 업데이트 방법 개요 설명
업데이트 전반적인 개요 - ReCreate, Rolling Update, Blue/Green, Canary
- 디플로이먼트를 만들고 pod이 만들어졌으며 v1이미지를 사용하고 있으며 v2로 업데이트 할때
- ReCreate
- 디플로이먼트가 기존 pod들을 삭제 → 서비스 downtime 발생
- 기존 pod들이 사용하던 자원들 반환됨
- 디플로이먼트가 신규 pod들을 다시 생성
- downtime이 존재하므로 일시적인 서비스 정지가 가능한 서비스에서만 사용 가능
- Rolling Update
- 디플로이먼트가 신규 pod을 하나 생성 : pod1개만큼 추가 작원
- 디플로이먼트가 기존 pod을 하나 삭제
- 위 과정 반복
- 배포 중간에 추가적인 자원을 요구하나 요구량이 작고 zero downtime
- 중간 단계에서 v1,v2 둘다 사용자가 접속 가능-> 특정 사용자는 다른 화면이나 다른 서비스
- Blue/Green
- deployment 자체 기능 아님
- deployment를 이용해서 사용 가능하지만 보통 replicas를 관리하는 컨트롤러를 이용해서 사용
- 기존 ReplicaSet에서 서비스와 v1pod들을 사용하고 있음
- 새로운 컨트롤러가 만들어지며 v2를 가진 pod들을 생성 :자원 사용량은 기존의 2배가 된다
- 서비스에있는 selector의 레이블만 변경 : 기존v1대신 v2pod와 서비스가 연결됨
- 문제시 서비스의 selector의 레이블만 기존 것으로 바꿈 : 롤백이 매우 쉽고 빠름
- 문제가 없으면 기존 컨트롤러 삭제
- zero down time, 상당히 많이 사용하는 방식이며 안정적이지만 자원 용량을 2배를 요구한다는 것
- 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에 바인딩해 접근도 가능
- node type Service +
Job
- https://kubernetes.io/ko/docs/concepts/workloads/controllers/job
- 일반 pod처럼 항상 실행되고 있는 서비스 프로세스가 아닌
한번 실행하고 완료가 되는 일괄처리 프로세스용
노드가 장애시 팟을 만든 주체에 따라 달라지는 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는 생기게 됨
- Allow
그밖에
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 = 컴포넌트화 > 조합 > 거대 어플리케이션