ReplicaSet / Deployment / Deployment Strategy
ReplicaSet
- 래플리카셋은
클러스터 안에서 움직이는 파드의 수
를유지
하는 장치. - 클러스터의 파드의 실행을 항상 안정적으로 유지하는 것을 목표로
명시된 파드 개수에 대한 가용성을 보증
하는 데 사용됨. - 만약 애플리케이션 오류나 노드 장애 등으로 파드가 정지된 경우 래플리카셋이 자동으로 새로운 파드를 시작함.
사진첨부
- 레플리카셋은 labelSelector의 조건에 따라 파드를 검색하여 가동 중인 파드의 수가 매니페스트 파일의 replicas의 수와 일치하는지 아닌지를 확인함.
- 만약
가동 중인 파드의 수가 부족한 경우 새로 파드를 추가하고, 파드의 수가 많을 때는 여분의 파드를 정지 시킨다.
- 따라서 가동 중인 애플리케이션의 파드 수를 변경하고 싶을 때는 레플리카셋의 replicas의 값을 수정하기만 하면 된다.
사진첨부
방법
- 1) 기본 항목
apliVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
필드 | 데이터형 | 설명 | 예시 |
---|---|---|---|
apiVersion | 문자열 | API 버전, 존재하지 않는 값을 설정하면 오류가 발생 | apps/v1 |
kind | 문자열 | 쿠버네티스 리소스의 종류 | ReplicaSet |
metadata | Object | 레플리카셋의 이름이나 Label과 같은 메타데이터 | name: photoview-rs |
spec | PodSpec | 레플리카셋의 상세 정보를 설정 | - |
- 2) ReplicaSet 스펙
spec:
replicas: 3 # Pod의 수
selector:
matchLabels:
app: nginx-replicaset
필드 | 데이터형 | 설명 |
---|---|---|
replicas | 정수 | 클러스터 안에서 가동시킬 파드의 수 , 기본값은 1 |
selector | LabelSelector | 어떤 파드를 가동시킬지에 대한 셀렉터, 파드의 Template에 설정된 라벨과 일치해야 함 |
template | PodTemplateSpec | 실제로 클러스터 안에서 움직이는 파드의 수가 replicas에 설정된 파드의 수를 만족시키지 않을 때 새로 작성되는 파드의 템플릿 |
- 3) Pod 템플릿
template:
metadata:
labels:
app: nginx-replicaset
env: prod
필드 | 데이터형 | 설명 |
---|---|---|
metadata | Object | 템플릿의 이름이나 Label과 같은 데이터 |
spec | PodSpec | 파드의 상세 정보를 설정 |
- 4) Pod 스펙
spec:
containers:
- image: nginx
name: nginx-replicaset
ports:
- containerPort: 80
- spec.template 하위의 [spec] 필드에는 Pod의 상세 정보를 설정함.
- 특히 .spec.template.spec.containers[] 필드의 하위에 .name, .image, .ports[], .containerport 필드를 이용해 컨테이너의 구체적인 명세를 설정함.
# watch kubectl get all -o wide
# kubectl apply -f ex06.yaml
사진첨부
Deployment
- 디플로이먼트(Deployment) : 쿠버네티스에서 상태가 없는(stateless) 앱을 배포할 때 사용하는 가장 기본적인 컨트롤러
쿠버네티스가 처음 등장했을 때는 Replication Controller에서 앱을 배포했는데 최근에는 디플로이먼트를 기본적인 앱 배포에서 사용함.
Stateless Application
: 클라이언트와 서버의 연결 구조에서 불필요한 상태의 반영을 위한 데이터나 리소스가 사용되지 않는 형태의 서비스 구조파드와 레플리카셋은 ‘이력’이라는 개념이 없기 때문이 릴리스 후에 변경이 없는 애플리케이션을 관리하는 데 적합함.
- 디플로이먼트는 이름처럼 배포 기능을 세분화한 것으로 파드와 레플리카셋에
버전 관리 기능을 추가
한 것 이라고 생각. - 단순히 실행시켜야 할 파드 개수를 유지하는 것 뿐만 아니라 앱을 배포할 때 롤링 업데이트 하거나, 앰 배포 도중 잠시 멈췄다가 다시 배포할 수 있다.
- 또한 앱 배포 후 이전 버전으로 롤백도 가능함.
레플리카셋과 완전히 다른 기능이라고 보기는 어렵고,
디플로이먼트가 레플리카셋을 관리하며 앱 배포를 더 세밀하게 관리하는 것
- 디플로이먼트는 컨테이너 이미지 버전 업 등 업데이트가 있을 때 새로운 사양의 레플리카셋을 작성하고 순서대로 새로운 파드로 대체하여 롤아웃을 수행함.
- 디플로이먼트는 레플리카셋과 달리 이력을 관리하기 때문에 1세대 이전으로 되돌리는 롤백을 할 수 있음.
사진첨부
- 1) 기본 항목
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
- 2) Deployment 스펙
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment
- 3) Pod 템플릿
template:
metadata:
labels:
app: nginx-deployment
- 4) Pod 스펙
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
# watch kubectl get all -o wide
# kubectl apply -f ex07.yaml
# kubectl scale deployment.apps/nginx-deployment --replicas=2
# kubectl scale deployment.apps/nginx-deployment --replicas=4
# kubectl scale deployment.apps/nginx-deployment --replicas=1
or
# kubectl edit deployment.apps/nginx-deployment
"1을 6으로 수정하기"
# kubectl edit deployment.apps/nginx-deployment
"6을 1로 수정하기"
or
# vi ex07.yaml
"1을 6으로 수정하기"
# kubectl apply -f ex07.yaml
# vi ex07.yaml
"6을 1로 수정하기"
# kubectl apply -f ex07.yaml
-------------------------------
# kubectl delete deployment.apps/nginx-deployment
사진첨부
Deployment 수정
- 이 상태에서 nginx-deployment의 컨테이너 이미지 설정 정보를 업데이트 해 보자.
- 업데이트 하는 방법
kubectl set
명령으로 직접 컨테이너 이미지를 지정kubectl edit
명령으로 현재 파드의 설정 정보를 연 다음 컨테이너 이미지 정보를 수정처음 적용했던 템플릿의 컨테이너 이미지 정보를 수정
한 다음kubectl apply
명령을 실행해서 변경
- 1번 방식을 사용하여 실행 중인 디플로이먼트에서 image 필드를
nginx:1.9.1
버전으로 변경해보기.
# kubectl set image deployment/nginx-deployment nginx-deployment=nginx:1.9.1
Deployment 롤백
- 컨테이너 이미지를 변경한 내역을 보기 위하여 다음과 같이 명령어를 입력함.
# kubectl rollout history deploy nginx-deployment
- 위에서 이미지를 한 번 변경하였기 때문에 두 개의 리비전이 보이며, 현재 리비전은 2이다.
- 특정 리비전의 상세 내용을 확인하려면
--revision=리비전번호
옵션을 사용함.
# kubectl rollout history deploy nginx-deployment --revision=2
- 이 상태에서 컨테이너 이미지를 수정하기 전인
리비전 #1로 롤백
하기
# kubectl rollout undo deploy nginx-deployment --to-revison=1
리비전#2
의 레플리카셋인 7b779c9598에 있던 파드들이 삭제되고 다시리비전#1
의 레플리카셋인 69cfdf4bc 파드들이 생성된 것을 확인할 수 있음.
# kubectl rollout history deploy nginx-deployment
Deployment Strategy
- 서비스 배포 전략 기법에는 Recreate, Rolling Update, Blube/Green, Canary 배포 전략이 있다.
Recreate
- 가장 단순한 배포 전략, 기존 버전의 서버를 모두 삭제한 다음 새로운 버전의 서버를 생성하는 방법
서비스에 대한 일시적인 DownTime(중단 시간)이 존재한다. (무중단 배포 X)
- 방법)
사진첨부
사진첨부
사진첨부
- Deployment를 만들면 v1 파드들이 만들어짐
- 파드 하나당 자원 하나 사용한다고 가정
- 먼저 파드 삭제 후, Downtime 동안 자원을 사용하지 않음
- 그 다음 파드 v2를 만들고 다시 자원 할당
- 단점은 Downtime이 발생해서 일시적으로 중단 가능한 서비스에만 쓰임.
# watch kubectl get all -o wide
# kubectl get pods --show-labels
# kubectl get pods -l type // -l (label) 옵션 사용하기
# kubectl get pods -l type=app // -l (label) 옵션 사용하기
# kubectl describe pod/deployment-1-7fb6d9dc-2np2t
Controlled By: ReplicaSet/deployment-1-7fb6d9dc
# kubectl describe replicaset.apps/deployment-1-7fb6d9dc
Controlled By: Deployment/deployment-1
- master에서 Cluster IP에 반복해서 접근하기
root@mster.~3 while true; do curl 10.96.251.8:8080/version; sleep 1; done
- Deployment 편집으로 image를 v1에서 v2로 변경하고 마스터 노드 쉘 보기
# kubectl edit deployment.apps/deployment-1
- ReplicaSet 확인 : 기존 파드 v1은 2->0이 되고, v2는 2개가 생성됨
# watch kubectl get all -o side
# kubectl describe pod/deployment-1-6d995d446d-2dn6q
Image: kubetm/app:v2
- Deployment에서 image v3으로 변경하고 ReplicaSet 확인
- ReplicaSet v1은 삭제되고 v2, v3만 남음
- revisionHistoryLimit: 1이기 때문
# kubectl edit deployment.apps/deployment-1
- Deployment에서 image를 v3->v2로 변경하여 롤백 시행해도 되지만 명령어로 롤백 시행
- deployment-1 : 롤백할 대상
- –to-revision=2: 2번째로 배포한 대상으로 롤백하겠다
- revison 확인 방법 : 대시보드, 명령어
# kubectl rollout undo deployment deployment-1 --to-revision=2
Roiing Update
- 기존 버전의 서버를 하나씩 죽이고, 새로운 버전의 서버를 하나씩 띄우면서 순차적으로 교체하는 방법
- 즉, 서버를 하나하나씩 버전을 업그레이드하는 방식
- 배포 중 추가 자어ㅜㄴ을 요구하지만, 서비스 DownTime 시간이 없음.
하지만, 이전의 버전과 새로운 버전의 공존하는 시간이 발생하는 단점이 있음.
- 방법)
사진첨부
- master에서 Cluser IP에 반복해서 접근하기
# while true; do curl 10.96.251.8.8080/version; sleep 1;done
- Deployment 편집으로 image를 v1에서 v2로 변경하고 마스터 노드 쉘 보기
# kubectl edit deployment.apps/deployment-2
- Downtime 없이 v1, v2 번갈아가면서 접속되다가 v2로 변경됨.
사진첨부
- ReCreate과 달리 v1을 삭제하지 않고 v2를 생성
- 자원은 3개가 되고, 접속하는 사람은 v1이나 v2에 접속하게 됨.
- v1을 삭제하고, v2 생성
- 마지막으로 남은 v1을 삭제하여 v2로 업데이트 완료
- 단점 : 자원을 추가로 요구, 장점 : DownTime이 없음.
Blue/Green
- 구 버전과 새로운 버전의 2가지를 서버에 마련하고, 이를 한꺼번에 교체하는 방법
- 이전 버전을 블루, 신버전을 그린이라고 함.
- 서비스 DownTime이 존재하지 않고, 롤백이 쉬움.
- 이전 버전과 새로운 버전의 공존하는 시간이 존재하는 Rolling Updatd의 문제를 해결할 수 있다.
- 운영 환경에 영향을 주지 않고 실제 서비스 환경으로 새 버전 테스트가 가능
배포 시 시스템 자원의 2배를 사용하는 단점이 있음.
- 방법)
사진첨부
사진첨부
사진첨부
사진첨부
- Deployment에서 제공되는 기능이 아님
- Replicas를 관리하는 컨트롤러 이용함
- Controller를 만들고 Pod v1 생성하고 Service 에 연결
- 컨트롤러를 추가로 만들고 v2 버전 파드 생성
- 이때 자원 사용량은 2배가 됨.
- 서비스의 셀렉터를 v2로 변경하여 v2 버전의 파드와 연결 -> 순간적으로 변경
- v2에 문제가 발생하면 서비스의 라벨을 v1으로 변경하여 문제 시 롤백 가능
- 문제가 없으면 기존 버전 파드 삭제
- 상당히 많이 사용하고 안정적인 배포 방식이지만 자원이 2배로 필요
$ watch kubectl get all -o wide
# kubectl edit service/svc-3
$ kubectl delete service/svc-1
$ kubectl delete replicaset.apps/replica1
- ReplicaSet 생성
- 서비스 생성
- 서비스의 cluster ip를 복사하여 다음 명령어 실행
# while true; do curl 10.104.8.101:8080/version;sleep 1;done
- ReplicaSet2 생성
- 서비스의 selector에서 ver: v1-> ver:v2로 변경
- 다운 타임 없이 바로 v2를 호출함.
- 다운 타임 없이 바로 v2를 호출함.
- 기존 ReplicaSet은 삭제를 해도 되고, replicas를 0으로 만들면 됨.