디플로이먼트의 주된 역할은 파드의 개수를 관리하는 것이다.
기존 레거시에서는 서버를 미리 구매해 놓고, 이벤트시 서버에 어플리케이션을 미리 기동시켜 놓고 트래픽을 받는 등의 방식으로 운영했다.
하지만 클라우드 환경이 발전하면서 각종 퍼블릭클라우드사에서 VM스케일 인아웃을 간편하게 만들었고, 더 나아가 k8s에서는 이런 어플리케이션 서버 역할을 하는 pod를 자유롭게 스케일 인아웃하여 이전보다 굉장히 유동적으로 서버 자원을 늘리고 줄일 수 있으며 비용,공간,자원 등 많은 부분에서 유리하다.
k8s에서는 디플로이먼트를 이용하며 pod의 수를 조정할 수 있다. 디플로이먼트와 pod의 관계는 아래 그림을 참고하자

디플로이먼튼 혼자 작동하는 것이 아니라 레플리카셋과 함께 작동한다.
간단한 yaml을 보면 아래와 같다.

metadata의 name은 디플로이먼트의 이름이며, replicas 는 기동되는 pod의 수이며, template는 생성될 pod에 대한 정보들이다. 위를 create해보면 아래와 같이 3개의 pod가 생성이 된다.

이때 pod의 수를 변경하고 싶을 수 있는데 크게 2가지 방법이 있다. yaml을 변경하거나 scale 명령어를 사용한다.
아래와 같이 replicas를 3-> 5로 생성한후 apply -f 를 하면 pod가 2개 더 기동된 것을 볼 수 있다.


이번에는 scale명령어를 통해 5->8개로 늘려보겠다.


이런식으로 변경이 가능하다. 개인적으로는 협업이나 장애시 추적을 위해 yaml를 버저닝하며, 변경시마다 로컬디렉토리든 github이든 저장을 하는것을 추천한다.
롤아웃 기능
이번에는 롤아웃이라는 기능을 보자. 위에서 실습한 deployment yaml를 하나 copy한 후 이미지에서 nginx 버전을 변경한 후 저장한다. 아래와 같이 새로운 yaml을 만들었고 이전 nginx 1.14버전과는 다르게 1.16으로 지정했다.

diff <yaml_name> <yaml_name> 과 같이 입력하면 아래와 같이 다른 부분을 보여준다.

테스트를 하기전에 pod가 어떻게 교체가 되는지를 보기 위해 현재 배포되어 있는 deployment를 describe 해보자.
아래와 같이 StrategyType등 정보가 나와있다.

최대 25%에 해당되는 pod의 수만큼 정지시킬수 있으며, 만드는것도 최대 25%에 해당하는 pod의 수만큼 만들 수 있다는 의미이다. 이역시 yaml에서 지정할 수 있다.
이후 아까 만든 1.16버전의 yaml을 apply하면 해당 디플로이먼트의 이름이 배포되어 있으니 롤링아웃이 적용되어 pod가 삭제되고 기동된다. 아래와 같이 삭제와 생성이 동시에 진행된다.

이후 최종적으로 pod가 새로운 nginx버전으로 전환되게 된다.

이때 만약 새로운 버전의 pod에서 어플리케이션 장애가 있어 롤백을 해야하는 경우 어떻게 할까
rollout이란 기능을 통해 다시 되돌릴 수 있다. 아래와 같이 입력해보자.

그럼 아래와 같이 위에서 했던 과정을 반복하며 pod를 교체한다.

pod는 이렇게 생성되고 삭제될 때마다 ip가 변경이 된다. 하지만 ip변경 없이 pod가 지속되는 경우도 있는데, restart하는 경우에는 pod 자체를 없애버리는것이 아니기 때문에 ip는 그대로 유지된다.
여기서 디플로이먼트의 기능중 하나인 Auto Healing을 해보자. 위 pod중 한개를 죽여보면 어떻게 작동하는지 알 수 있다.

한개가 죽고, 한개가 생성되어 running 상태가 되는 것을 볼 수 있다. 이렇게 디플로이먼트의 replicas에 적혀있는 숫자를 맞추기 위해 살아난다.
이제는 배포에 대해서 생각해보자.
위에는 이론적인 부분이였따. 롤링아웃이 디폴트여서 모든 서비스에 롤링아웃만 적용한다고 생각할 수 있지만 서비스에 따라 다르게 가지고 가야한다.
배포방법에는 대표적으로 3가지 정도를 알아보자.
1. 롤링 아웃
2. 블루/그린
3. 카나리
1번인 롤링 아웃은 말 그대로 특정 수만큼 갈아치우면서 배포하는 방식이다. 만약 JVM환경의 pod가 기동된다면, 기동되는데 수분의 시간이 소요될 수 있다. 우리의 이커머스 서비스가 MSA환경으로 분리되어 있고 상품 전시에 해당하는 pod가 총 40개정도 기동되고 있다고 해보자. 롤링 아웃으로 배포시 최종적으로 신규 pod 40개가 배포되어야 하는데, 1개씩 롤링 아웃된다고 생각해보면 굉장히 오랜 시간이 걸릴 것이다. 사용자 입장에서는 새로 접속하거나 새로고침 할 때마다 신규 버전과 이전버전을 번갈아 접속할 확률이 높아진다. 이는 사용자 경험상에도 안좋은 영향을 줄 수 있으며, 가장 심각할 수 있는 상황은 신규버전이 테스트가 제대로 되지않아 운영환경에서 장애를 맞이하고 있는 상황이다. 롤링아웃은 취소가 안되기에 장애가 있는 신규 pod가 끝까지 배포될 것이다. 이후 이전 버전을 배포하는 것도 똑같은 시간이 걸리기에 장애가 극대화 된다. 단점만 말한것 같지만, 장점으로는 다른 배포방식보다 인프라 자원은 조금 덜 사용될 수 있다.
2번 블루/그린은 현재 기동중인 블루환경과 새로 배포할 그린 환경을 한순간에 트래픽을 역전시키는 것이다. 블루 디플로이먼트 40개가 기동중인 상황에서 그린 디플로이먼트 40개를 배포한다, 서비스는 아직 이전 블루를 보고 있기에 트래픽은 블루로 들어간다. 이후 특정 시간에 서비스를 apply하여 그린으로 트래픽을 보내는 방식이다. 이미 블루쪽 pod에 들어간 트래픽들은 마저 하던일을 하고 사라지게 된다. 어플리케이션에는 그레이스풀하게 작동하도록 개발이 되어있어야 한다.
그린 버전에 대해 장애가 관측되었을 경우 롤백을 해야하는데, 롤링아웃과 달리 다시 서비스만 이전 블루를 보게 변경후 apply한다면 장애시간을 최소화 하여 대처할 수 있다. 단점은 배포시 인프라가 2배가 사용된다는 것이다.
3번 카나리는 비율을 정해서 먼저 배포해 보는 것이다. 10% 비율로 다음 버전을 배포한다고 하면, 10% pod만 배포를 한 후 장애가 없는지 나머지 90%를 배포해도 되는지 조금 모니터링 한 후 괜찮으면 나머지를 배포하는 방식이다. 장점은 인프라도 적절하게 사용하고, 운영에서 장애환경을 가장 최소화 할 수 있다는 것이다. 단점은 역시 모니터링이다. 모니터링이 위 2방법보다 조금 까다롭다. 또한 istio와 같은 서비스 메쉬를 사용해야 할 수도 있으며, l7 로드밸러서 단에서 작업을 하여 트래픽을 새로운 10% pod로 갈 수 있도록 구조적인 변경을 하는등 아키텍처상에 조금 까다로울 수 있는 부분이 있다.
3가지중에 어느것이 가장 좋다고 말할수는 없고, 자신의 서비스에 맞게 진행하면 된다. 아래 글을 좀 더 참고해보자.
https://www.haproxy.com/blog/rolling-updates-and-blue-green-deployments-with-kubernetes-and-haproxy/
Rolling Updates and Blue-Green Deployments with Kubernetes and HAProxy - HAProxy Technologies
Learn how the HAProxy Kubernetes Ingress Controller supports rolling updates and blue-green deployments for updating your Kubernetes applications
www.haproxy.com
https://blog.container-solutions.com/kubernetes-deployment-strategies