7.3.3 [실습] 디플로이먼트를 이용한 애플리케이션 배포, 업데이트, 롤백

지금까지 디플로이먼트의 필요성과 다양한 기능, 그리고 명세 파일의 주요 필드들에 대해 이론적으로 깊이 있게 살펴보았습니다. 이제는 직접 손으로 디플로이먼트를 다루어보면서 그 강력함을 체감해 볼 시간입니다! 이 실습을 통해 우리는 간단한 웹 애플리케이션을 디플로이먼트를 사용하여 배포하고, 이미지 버전을 변경하여 롤링 업데이트를 수행하며, 배포 기록을 확인하고, 마지막으로 문제가 발생했을 경우를 가정하여 이전 버전으로 안전하게 롤백하는 전체 과정을 경험하게 될 것입니다.

본 실습 역시 앞선 레플리카셋 실습과 마찬가지로, 쿠버네티스 클러스터와 kubectl 명령어가 준비되어 있어야 합니다. Minikube, kind, Docker Desktop의 쿠버네티스 기능 또는 클라우드 제공업체의 관리형 서비스를 사용하시면 됩니다. 자, 그럼 클라우드 네이티브 애플리케이션 배포의 표준, 디플로이먼트의 세계로 직접 뛰어들어 볼까요?

7.3.3.1 디플로이먼트 생성

가장 먼저 할 일은 디플로이먼트를 정의하는 YAML 파일을 작성하고, 이를 클러스터에 적용하여 디플로이먼트와 그에 따른 파드들을 생성하는 것입니다. 이번 실습에서는 간단한 “Hello World” 웹 서버 컨테이너(예: nginxdemos/hello 또는 직접 만드신 간단한 웹 서버 컨테이너)를 사용하는 디플로이먼트를 만들어 보겠습니다. 처음에는 3개의 복제본으로 시작하고, 롤링 업데이트 전략의 기본값을 사용할 것입니다.

아래 내용을 my-deployment.yaml 이라는 이름의 파일로 저장해 주세요.

클립보드에 복사

이 YAML 파일은 앞서 배운 디플로이먼트 명세의 기본 구조를 따르고 있습니다. replicas: 3으로 설정하여 3개의 파드를 유지하도록 하고, selector와 template.metadata.labels에 app: hello-app을 동일하게 지정하여 디플로이먼트가 관리할 파드를 정확히 식별하도록 했습니다. template.spec.containers에는 nginxdemos/hello:0.2 이미지를 사용하는 hello-container를 정의했습니다.

이제 터미널에서 이 YAML 파일이 저장된 디렉토리로 이동한 후, 다음 명령어를 실행하여 디플로이먼트를 생성합니다.

클립보드에 복사

명령이 성공하면 “deployment.apps/hello-deployment created” 와 같은 메시지가 출력됩니다. 디플로이먼트가 잘 생성되었는지 확인해 보겠습니다.

클립보드에 복사

hello-deployment라는 이름의 디플로이먼트가 보이고, READY, UP-TO-DATE, AVAILABLE 등의 상태 정보가 표시될 것입니다. READY는 현재 replicas 수만큼의 파드가 준비되었음을, UP-TO-DATE는 현재 template과 일치하는 파드 수를, AVAILABLE은 사용 가능한 파드 수를 나타냅니다. 처음에는 이 값들이 3/3, 3, 3으로 표시될 것입니다.

디플로이먼트는 내부적으로 레플리카셋을 생성한다고 말씀드렸죠? 어떤 레플리카셋이 생성되었는지 확인해 봅시다.

클립보드에 복사

hello-deployment-xxxxxxxxxx 와 같이 디플로이먼트 이름에 랜덤한 해시값이 붙은 레플리카셋이 하나 생성되어 있고, 이 레플리카셋이 3개의 파드를 관리하고 있는 것을 볼 수 있습니다.

마지막으로, 실제로 파드들이 잘 생성되었는지 확인합니다.

클립보드에 복사

hello-deployment-xxxxxxxxxx-yyyyy 형태의 이름을 가진 3개의 파드가 Running 상태로 표시될 것입니다. 이로써 우리는 디플로이먼트를 사용하여 애플리케이션의 첫 번째 버전을 성공적으로 배포했습니다!

7.3.3.2 이미지 업데이트 (kubectl set image) 및 롤링 업데이트 확인

이제 디플로이먼트의 핵심 기능 중 하나인 롤링 업데이트를 직접 경험해 볼 차례입니다. 애플리케이션의 컨테이너 이미지를 새로운 버전으로 변경하여 디플로이먼트가 어떻게 무중단으로 업데이트를 수행하는지 관찰해 보겠습니다.

물론 YAML 파일의 template.spec.containers[0].image 값을 직접 수정하고 kubectl apply -f my-deployment.yaml을 다시 실행하여 업데이트할 수도 있습니다. 하지만 kubectl은 보다 간편하게 이미지 업데이트를 수행할 수 있는 명령형 명령어인 kubectl set image를 제공합니다.

우선, 현재 hello-deployment는 nginxdemos/hello:0.2 이미지를 사용하고 있습니다. 이를 nginxdemos/hello:0.3 (또는 여러분이 준비한 다른 버전의 이미지)으로 업데이트해 보겠습니다.

클립보드에 복사

명령어 형식은 kubectl set image <오브젝트타입>/<오브젝트이름> <컨테이너이름>=<새로운이미지이름:태그> 입니다. 여기서 <컨테이너이름>은 디플로이먼트 YAML 파일의 template.spec.containers[].name에 정의된 이름 (우리 예제에서는 hello-container)을 사용해야 합니다. –record 옵션은 이 변경 사항에 대한 설명을 배포 기록(revision history)에 남기도록 하여 나중에 롤백 시 유용하게 활용할 수 있게 합니다. (최신 쿠버네티스 버전에서는 –record가 deprecated 되고, kubectl annotate를 사용하는 방식으로 변경될 수 있으니, 사용하시는 버전에 따라 문서를 확인하시는 것이 좋습니다. 여기서는 개념 설명을 위해 포함합니다.)

위 명령을 실행하면 “deployment.apps/hello-deployment image updated” 와 같은 메시지가 출력됩니다. 이제 디플로이먼트가 롤링 업데이트를 시작합니다! 이 과정을 실시간으로 관찰하기 위해 다른 터미널 창을 열고 다음 명령어를 실행하여 디플로이먼트의 상태 변화를 지켜볼 수 있습니다.

클립보드에 복사

이 명령어는 디플로이먼트의 롤링 업데이트 진행 상황을 실시간으로 보여줍니다. “Waiting for deployment “hello-deployment” rollout to finish: 1 out of 3 new replicas have been updated…” 와 같은 메시지들이 나타나며, 새로운 버전의 파드가 생성되고 기존 버전의 파드가 종료되는 과정을 단계별로 확인할 수 있습니다.

동시에, 원래 터미널에서 파드들의 상태를 주기적으로 확인해 보면 더욱 흥미로운 관찰이 가능합니다.

클립보드에 복사

새로운 버전의 이미지(nginxdemos/hello:0.3)를 사용하는 파드들이 하나씩 생성되고 Running 상태가 되는 것을 볼 수 있습니다. 동시에, 기존 버전의 이미지(nginxdemos/hello:0.2)를 사용하던 파드들은 Terminating 상태가 되었다가 사라지는 것을 확인할 수 있습니다. 이 모든 과정은 디플로이먼트의 strategy 필드에 정의된 RollingUpdate 전략(기본값 maxSurge: 25%, maxUnavailable: 25%)에 따라 진행됩니다. replicas: 3이므로, 기본적으로 최대 1개의 파드가 초과 생성될 수 있고(3 * 0.25 = 0.75, 올림하여 1), 최대 1개의 파드가 사용 불가능할 수 있습니다. 즉, 업데이트 중에도 최소 2개의 파드는 항상 서비스를 제공하며, 일시적으로 최대 4개의 파드(3개 + 1개 surge)가 존재할 수 있습니다.

kubectl rollout status 명령이 “deployment “hello-deployment” successfully rolled out” 메시지를 출력하면 롤링 업데이트가 완료된 것입니다. 이때 다시 레플리카셋 목록을 확인해 보세요.

클립보드에 복사

이제 두 개의 레플리카셋이 보일 것입니다. 하나는 이전에 nginxdemos/hello:0.2 이미지를 사용하던 레플리카셋(DESIRED, CURRENT, READY가 모두 0)이고, 다른 하나는 새로 생성된 nginxdemos/hello:0.3 이미지를 사용하는 레플리카셋(DESIRED, CURRENT, READY가 모두 3)입니다. 디플로이먼트는 새로운 버전의 레플리카셋을 만들고, 이전 레플리카셋의 파드 수를 0으로 줄인 것입니다. 이전 레플리카셋은 롤백을 위해 revisionHistoryLimit 설정에 따라 일정 기간 유지됩니다.

이처럼 kubectl set image 명령 한 줄로 우리는 안전하게 애플리케이션 버전을 업데이트할 수 있었습니다. 이것이 바로 디플로이먼트가 제공하는 롤링 업데이트의 마법입니다!

7.3.3.3 배포 기록 확인 (kubectl rollout history)

디플로이먼트는 업데이트가 발생할 때마다 ‘리비전(revision)’이라는 형태로 변경 이력을 저장한다고 했습니다. 이 배포 기록은 나중에 문제가 발생했을 때 특정 버전으로 롤백하는 데 매우 중요하게 사용됩니다. kubectl rollout history 명령어를 사용하면 이 기록을 확인할 수 있습니다.

클립보드에 복사

위 명령을 실행하면 다음과 유사한 출력을 볼 수 있습니다 (리비전 번호는 다를 수 있습니다).

클립보드에 복사

REVISION은 각 배포의 고유 번호이고, CHANGE-CAUSE는 해당 리비전이 생성된 원인이나 설명을 보여줍니다. 만약 kubectl apply 시 –record 옵션을 사용했거나, kubectl set image 시 –record 옵션을 사용했다면 (또는 kubectl annotate로 주석을 남겼다면) 여기에 해당 내용이 표시되어 어떤 변경이었는지 쉽게 파악할 수 있습니다. 만약 아무런 기록 옵션을 사용하지 않았다면 <none>으로 표시될 수 있습니다.

특정 리비전의 상세 정보를 보고 싶다면 –revision=<번호> 옵션을 추가합니다. 예를 들어, 리비전 1의 상세 정보를 보려면 다음과 같이 실행합니다.

클립보드에 복사

이를 통해 각 리비전이 어떤 파드 템플릿(특히 어떤 이미지)을 사용했는지 등의 상세 정보를 확인할 수 있습니다. 이 배포 기록은 마치 우리 애플리케이션의 타임캡슐과 같아서, 언제든지 과거의 특정 시점으로 돌아갈 수 있는 열쇠가 됩니다.

7.3.3.4 이전 버전으로 롤백 (kubectl rollout undo)

이제 마지막으로, 만약 새롭게 배포한 버전에 심각한 버그가 있어서 긴급하게 이전 버전으로 되돌려야 하는 상황을 가정해 봅시다. 디플로이먼트의 롤백 기능을 사용하면 이 작업을 매우 간단하게 수행할 수 있습니다. kubectl rollout undo 명령어가 바로 그 주인공입니다.

현재 우리 hello-deployment는 리비전 2 (nginxdemos/hello:0.3)가 최신 상태입니다. 이전 버전인 리비전 1 (nginxdemos/hello:0.2)로 롤백해 보겠습니다.

클립보드에 복사

이 명령을 실행하면 “deployment.apps/hello-deployment rolled back” 과 같은 메시지가 출력됩니다. 이 명령어는 기본적으로 가장 최근의 리비전에서 바로 이전 리비전으로 롤백합니다.

롤백 과정도 롤링 업데이트와 마찬가지로 점진적으로 진행됩니다. kubectl rollout status deployment/hello-deployment 명령으로 롤백 진행 상황을 확인할 수 있으며, kubectl get pods -l app=hello-app –watch 명령으로 파드들이 다시 이전 버전 이미지(nginxdemos/hello:0.2)로 교체되는 것을 실시간으로 볼 수 있습니다.

롤백이 완료된 후 다시 배포 기록을 확인해 보겠습니다.

클립보드에 복사

출력 결과가 조금 흥미로울 것입니다. 이전의 리비전 2는 그대로 있고, 리비전 1의 내용(파드 템플릿)을 가진 새로운 리비전 번호 (예: 3)가 생성되어 현재 활성 상태가 된 것을 볼 수 있습니다. 즉, 롤백은 단순히 과거의 리비전을 재활성화하는 것이 아니라, 해당 과거 리비전의 템플릿을 사용하여 새로운 리비전을 만드는 방식으로 동작합니다. 이는 모든 배포 행위(최초 배포, 업데이트, 롤백)가 새로운 리비전을 생성하도록 하여 변경 이력을 일관되게 관리하기 위함입니다.

만약 특정 리비전으로 직접 롤백하고 싶다면 –to-revision=<번호> 옵션을 사용합니다. 예를 들어, 다시 리비전 2 (원래 nginxdemos/hello:0.3을 가졌던 리비전, 현재는 비활성 상태)로 돌아가고 싶다면 (비록 롤백 후 생성된 새 리비전이 있지만, 개념 설명을 위해 원래 리비전 번호를 사용합니다)

클립보드에 복사

이처럼 kubectl rollout undo 명령어는 애플리케이션에 문제가 발생했을 때 신속하고 안전하게 이전 상태로 복구할 수 있는 강력한 도구입니다.

이번 실습을 통해 우리는 디플로이먼트를 생성하고, kubectl set image로 이미지를 업데이트하여 롤링 업데이트를 관찰했으며, kubectl rollout history로 배포 기록을 확인하고, 마지막으로 kubectl rollout undo를 통해 이전 버전으로 롤백하는 전 과정을 직접 경험했습니다. 이러한 디플로이먼트의 기능들은 클라우드 네이티브 환경에서 애플리케이션을 안정적으로 운영하고 지속적으로 개선해 나가는 데 있어 핵심적인 역할을 합니다.