컨트롤러
- 컨트롤러는 다양한 조작방법을 지원한다.
- Pod이 죽었을때 빠르게 새로운 Pod을 만들어 동작할 수 있도록 Auto Healing 기능 지원.
- Pod의 리소스가 거의 다 사용되어갈때, 새로운 Pod을 만들어 부하를 분산하는 Auto Scaling 기능 지원.
- v1인 Pod들을 모두 v2로 쉽게 버전 업데이트를 위한 Software Update 기능. → 문제가 생기면 롤백도 가능한 기능.
- 필요한 순간에만 동작하고 삭제하는 Job 기능.
Replication Controller, ReplicaSet
- 레플리카란 특정 수의 Pod가 실행되도록 보장하는 컨트롤러이다.
- 레플리케이션 컨트롤러는 더이상 사용되지않고, 그에 대한 대체로 레플리카셋을 사용한다. → 물론아직 레플리케이션 컨트롤러는 사용은 되고있다. 점점 레플리카셋으로 업데이트하는 추세.
Template
- selector는 web이라는 라벨을 가진 Pod을 다루겠다는 것이다
- 셀럭터와 라벨이 일치하여야한다.
- pod이 죽었을때 template의 내용을 바탕으로 다시 재생성한다.
- v2라는 pod이 업데이트 될 땐, 템플릿의 새로운 버전의 컨테이너 이미지로 업데이트 한다.
Replicas
- replicas의 기능중에 pod의 갯수를 지정할 수 있다. → pod의 갯수가 모자라면 해당 갯수만큼 만들고, 넘어서지 않는다.
- 레플리키와 템플릿의 기능을 이용해서 pod을 짜지않고 컨트롤러만 사용하여 pod을 생성 할 수 있다.
Selector
- 위에서 배운 기능들은 레플리케이션 컨트롤러, 레플리카셋 모두 있지만, 셀렉터는 레플리카셋 에만 있다.
- 셀럭터는 레플리카셋이 원하는 pod을 고를떄 쓸수 있다.
- 컨트롤러에선 키와 밸류 모두가 일치해야 선택했지만 셀렉터는 조금더 디테일하게 사용 가능하다.
- Exists : 해당 키를 가지고 있는 pod을 모두 선택
- DoesNotExists : 해당키가 아닌 pod을 선택.
- In : 여러개를 선택할 수있고, 해당 키와 밸류를 가지고있는 pod 모두 선택.
- NotIn : 키는 는 일치하고 Value는 일치하지 않는 pod을 선택.

컨트롤러 실습
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica1
spec:
replicas: 1
selector:
matchLabels:
type: web
template:
metadata:
name: pod1
labels:
type: web
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0
- 다음과 같이 레플리카셋을 생성.
- replicas의 설정으로 1개의 pod을 유지.
- type이 web인 pod를 다루고 Template의 내용을 기반으로 Pod 생성
- pod이름이 pod1으로 설정했는데 동일한 네임스페이스에 같은 pod이름이 생성 못하는데? -> 동일한 Pod이름은 자동으로 다르게 네이밍 됨.
- 컨트롤러를 삭제하면 관련된 Pod도 모두 삭제
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica1
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
- 해당 코드에서 matchLabels를 사용해서 원하는 라벨을 선택 matchExpressions는 잘 사용하진 않는다.
- 정말 세밀하게 만져야할때 matchExpressions를 사용한다.
- matchLabels에 있는 ver이 template의 ver에 없다면 동작하지 않는다. template에 지정된 ver이여야한다
- matchLabels에 정의된 모든 라벨은 template에도 포함되어야한다.
Deployment - Recreate, RollingUpdate
- 서비스가 운영중일때, 배포를 해야하는 상황에서 유용하게 사용되는 기능
- 대표적으로 사용되는 배포방식에 대해서 알아보자
배포방식
- ReCreate
- Recreate방식으로 디플로이먼트를 짜게되면 버전 업데이트할때 모든 pod을 삭제한다.
- 그리고 업데이트한 pod을 생성하여서 모든 pod을 업데이트한다.
- 장점 : 빠르게 더 필요한 리소스없이 업데이트가 가능하다.
- 단점 : 다운타임 시간이 필요하다. 모든 서비스를 껏다 킬수 있다.
- 일시적으로 모두 정지가 가능한 서비스를 업데이트할때 사용할 수 잇다.
- Rolling Update
- 롤링 업데이트를 디플로이먼트로 짜게되면 v1을 삭제하기 전에 v2를 생성한다.
- 그리고 v2와 v1을 섞여서 사용자들이 사용하게되고. 전에쓰던 v1하나를 삭제한다.
- 그리고 또 v2만들고 v1을 삭제하고 이렇게 하나씩 생성과 삭제를 반복한다.
- 장점 : 다운타임이 없어서 사용자가 끊임없이 버전업데이트가 가능하다.
- 단점 : 여분의 리소스가 필요하다. 삭제하기전 pod을 생성만 했다면 리소스가 굉장히 늘어난다. 그리고 v1, v2가 같이 사용자가 쓸수있기때문에 모두 동시간대 같은 버전의 서비스를 받지 못할 수 있다.
- Blue/Green
- 디플로이먼트에서 지원하는건 아니지만 해당 방법은 서비스를 사용하여 구현할 수 있다.
- v1이라는 라벨을 가진 service를 사용하다 운영하다가. v2 pod을 미리 만들어놓고 서비스의 라벨만 v2로 바꿔 한꺼번에 버전업된 pod으로 이동한다.
- 블루/ 그린은 안정적이기 때문에 많은 기업에서 사용된다.
- 장점 : 한꺼번에 이동하기때문에 모두가 같은 버전을 사용하고, 다운타임 거의 없다, 그리고 만약 v2에 문제가 발생한다면 v1으로 라벨만 바꿔서 롤백이 굉장히 쉽다.
- 단점 : 리소스 사용량이 거의 딱 2배가 된다. v1을 삭제하던 롤링 업데이트와 달리 일단 모두 옮기고 보기 떄문에 리소스 사용량이 엄청나다.
- Canary
- 일 부분의 사용자만 업데이트된 버전을 사용하다가 문제가 없으면 모두 업데이트하는 방식.
- 서비스에 ty:app을 모두 쓰다가 ty:app을 가지고있는 pod중에 일부분만 v2로 업그레이드하여 사용.
- 만약 문제가 발생하지않는다면 모두 v2로 업그레이드. 문제가 발생한다면 v2 컨트롤러의 레플리카를 0으로 만들어서 pod을 모두 지우는 방식.
- 장점 : 다운타임이 없다, v2에 문제가 발생한다면 바로 가볍게 롤백이 가능하다. 원하는데로 자원을 조절할수있다. 블루그린과 롤링 업데이트는 어느정도 리소스 자원이 확보 되어야하지만 canary는 v2자원을 적게쓰고싶거나 많이 쓰고싶을때 조절이가능!
- 단점 : 설계에있어서 설정이 조금 필요하다.

Recreate 배포방법
- Deployment로 2개의 레플리카셋을 생성하고, 각각의 레플리카셋은 v1과 v2로 연결되었다.

- Deployment에 들어가있는 값들은 pod을 직접 조작하기 위해 들어있는 값이 아닌
- 레플리카셋을 만들고 지정하기 위한 용도이다.
- 그렇게 만들어진 레플리카셋이 pod을 만들고 조작한다.
- 그리고 service를 만들면 레플리카셋에서 만들어진 pod에 연결되서 조작한다.
- ReCreate방식은 v1의 방식인 레플리카셋을 0으로 만들고 v2인 레플리카 셋을 동작시켜서 v2로 모두 배포를 진행한다.
Rolling Update 배포방법
- 마찬가지로 Deployment가 레플리카셋을 2개를 만들어서 진행한다.
- 처음엔 v1에 레플리카가 여러개있고 v2는 0개로 진행된다.
- v2가 늘어나는만큼 v1을 줄여서 진행.
- 롤백을 대비하여 레플리카셋을 지우지는 않고 v1관련 레플리카셋의 레플리카는 0개로 마무리한다.
- 그런데 v2의 레플리카셋의 pod과 v1의 레플리카셋의 pod이 같은 라벨을 가지고있는데 문제가 발생하지않을까?
- 라벨을 디플로이먼트 차원에서 더 추가한다. → 실습 정리에 조금더 자세히 적어놓겠다
Deployment 실습
Recreate
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
- 디플로이먼트를 이렇게 설정하면. 레플리카셋을 하나 만들어서 pod을 2개 만들도록 자동화.
- 여기서 v1을 v2로 바꾸게되면 잠시 다운타임을 가지면서 v2로 pod을 바뀌게 된다.
- revisionHistoryLimit: 1을 1로 해놓으면 pod이 0이된 레플리카셋은 1개만 남게된다.
- 만약 지정하지 않는다면 10개까지 저장을 해놓는다. → 롤백의 기능으로 남겨놓기도 한다.
- 만약 롤백을 하고 싶다면
kubectl rollout undo deployment deployment-1 --to-revision=2 해당 명령어로 2번째 히스토리로 남아있는 레플리카셋 설정으로 넘어가게되고
- 어떤 히스토리가 있는지 확인하고 싶다면
kubectl rollout history deployment deployment-1 으로 어떤 히스토리가 있는지 확인할 수 있다.
Rolling Update
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-2
spec:
selector:
matchLabels:
type: app2
replicas: 2
strategy:
type: RollingUpdate
minReadySeconds: 10
template:
metadata:
labels:
type: app2
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0
- 위와다른점은 minReadySecond를 추가하고 type만 RollingUpdate로 적어주었다.
- 마찬가지로 생성시. 디플로이먼트, 레플리카셋, pod이 생성
- 배포 진행사항 확인방법
- 서비스를 생성히여 해당 pod들을 연결
- 해당 서비스의 ip를 계속 curl로 버전을 확인하다가 디플로이먼트에 버전을 v2로 변경하는순간
- 천천히 v1이 나오던 curl이 v2로 점점 바뀌다가 모두 버전이 변경됨
Blue/Green 배포
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica1
spec:
replicas: 2
selector:
matchLabels:
ver: v1
template:
metadata:
name: pod1
labels:
ver: v1
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0
apiVersion: v1
kind: Service
metadata:
name: svc-3
spec:
selector:
ver: v1
ports:
- port: 8080
protocol: TCP
targetPort: 8080
- 레플리카셋을 버전1을 만들고, 레플리카셋 버전2로 2개를 만든다.
- 그리고 Service로 v1을 연결하도록 생성한다.
- v1을 생성하던 Service를 ver을 v2로 바꿔주면서 다운타임없이 순식간에 바뀌게 된다.
- 미리 pod이 만들어져있기떄문에 다운타임이 거의 없다.