본문 바로가기
Google Cloud Platform

GKE(Google Kubernetes Engine)로 애플리케이션 관리하기 - 2부

by Roy Lee 2020. 6. 18.

애플리케이션 확장

쿠버네티스를 이용하여 애플리케이션을 관리하면 얻을 수 있는 장점으로 확장이 쉽다는 것을 꼽을 수 있다. 트래픽이 몰리는 경우 빠르게 인프라를 키워줘야 엔드유저들이 원활하게 서비스를 이용할 수 있다.

 

특정 애플리케이션에 대한 서버 리플리카를 추가하는 방법은 다음과 같다.

kubectl scale deployment hello-world --replicas=3

여기서 리플리카의 아규먼트는 총 리플리카가 그 갯수만큼 되게 하라는 의미이다. 즉, 이미 1개의 pod에 배포되어 있었다면 2개가 더해져서 총 3개가 되도록, 이미 2개의 pod에 배포되어 있었다면 1개의 리플리카를 추가하여 총 3개가 되게 하라는 의미이다.

 

확장된 리소스는 다음 명령어로 확인 가능하다.

kubectl get deployment hello-world

 

클러스터 내 pod 현황은 앞서 언급했듯이 다음 커맨드로 확인할 수 있다.

kubectl get pods

hello-world2 애플리케이션은 스케일을 확장하지 않았기에 1개의 pod에만 배포되어 있고, 스케일을 확장한 hello-world 애플리케이션은 1개에서 3개로 늘어난 것을 확인할 수 있다.

 

만약 hello-world 애플리케이션에만 유독 트래픽이 더 몰려서 pod를 하나 더 증설하고 싶다면 어떻게 해야 할까?

앞서 리플리카 아규먼트를 3으로 줬었기 때문에 이를 4로 바꿔서 한번 더 커맨드를 실행하면 된다.

kubectl scale deployment hello-world --replicas=4

 

애플리케이션 구버전을 새버전으로 교체 배포하기

최초 버전의 애플리케이션을 배포하고 서비스를 영구히 할 수는 없다. 기능을 추가하거나 수정하는 즉 새버전의 애플리케이션을 배포해야 하는 경우가 생긴다. 이 부분은 의외로 어렵고 중요한 작업이다. 새버전의 애플리케이션으로 교체하는 과정이 얼마나 고급지냐에 따라 그 회사의 서비스 다운타임을 길거나 짧게 만든다. 물이 흐르고 있는 파이프를 얼마나 빠르게 교체할 수 있느냐에 따라 세대의 수도 중단 시간을 결정되고 세대 구성원들의 불편함을 줄일 수 있는 것으로 귀결되는 것과 마찬가지라고 할 수 있다.

GKE는 롤링 업데이트를 지원한다. 롤링 업데이트는 논리적으로 봤을 때 서비스는 중단되지 않으면서 내부적으로 부분 교체를 가능하게 하는 것이라고 생각하면 쉽다. 즉 물이 흐르고 있는 파이프를 한번에 통째로 바꾸는 것이 아니라 파이프 부분 마다 점진적으로 바꾸는 방식이라고 생각하면 된다. 쿠버네티스에서는 앞서 언급한 파이프에 해당하는 파드 단위로 새버전의 애플리케이션을 배포한다. 목표는 서비스 무중단이다. 이를 가능하게 하는 것은 스케줄링 능력이 있기 때문이다. 기본적으로는 새버전의 애플리케이션 배포가 이루어질 때 이용 불가능한 pod를 1개로 유지하는 정책이 적용되어 있는데 이 옵션을 pod 개수 또는 백분율 %로 설정할 수 있다. 이 과정 덕분에 서비스를 중단하지 않고 롤링 업데이트를 할 수 있다.

출처. https://kubernetes.io/

 

새버전의 애플리케이션 배포는 4단계를 거쳐 설명한다.

  1. 새버전의 애플리케이션 구현

  2. 새버전의 애플리케이션 이미지 빌드

  3. 컨테이너 레지스트리에 이미지 업로드

  4. 기존 애플리케이션이 배포되어 있는 클러스터에 pod별 롤링 업데이트

첫번째 단계로 새로운 버전의 애플리케이션을 준비하는 개념으로 Hello World를 출력하던 애플리케이션1과 Hellooooooooooo World를 출력하던 애플리케이션2를 각각 Roy can, Roy cannnnnnnnnn 을 출력하도록 수정하자.

 

다음 단계로, 애플리케이션이 준비되었으니 각각 다시 빌드해서 이미지를 만들어주자.

hello-world 애플리케이션과 hello-world2 애플리케이션 모두 v.0.0.1에서 v0.0.2로 버저닝을 바꿔서 빌드하겠다.

docker build -t "gcr.io/$PROJECT_ID/docker-springboot-hello-world:v0.0.2" .

docker build -t "gcr.io/$PROJECT_ID/docker-springboot-hello-world2:v0.0.2" .

 

빌드가 완료되면 docker images 커맨드로 빌드된 이미지를 살펴보자.

애플리케이션별로 버전 v0.0.1과 v0.0.2 두가지씩 총 4개가 생긴 것을 확인할 수 있다.

 

세번째 단계로 빌드한 이미지를 컨테이너 레지스트리로 업로드 하자.

docker push gcr.io/$PROJECT_ID/docker-springboot-hello-world:v0.0.2

docker push gcr.io/$PROJECT_ID/docker-springboot-hello-world2:v0.0.2

 

이제 컨테이너 레지스트리까지 이미지 업로드가 모두 되었으므로 롤링 업데이트만 수행하면 된다.

롤링 업데이트는 다음 커맨드로 수행할 수 있다.

kubectl set image deployment/hello-world docker-springboot-hello-world=gcr.io/${PROJECT_ID}/docker-springboot-hello-world:v0.0.2

kubectl set image deployment/hello-world2 docker-springboot-hello-world2=gcr.io/${PROJECT_ID}/docker-springboot-hello-world2:v0.0.2

 

그리고 external ip에 연결된 애플리케이션이 새버전으로 정상 배포되었는지 확인을 해보자.

Hello World 와 Hellooooooooooo World를 출력하던 기존 애플리케이션 2개 모두 새로운 버전의 애플리케이션으로 교체 배포가 완료된 것을 확인할 수 있다.

다음은 이전 버전의 애플리케이션을 배포해두었을 때의 실행 결과로 새버전의 실행 결과와 비교하기 위해 첨부하는 자료이다. 애플리케이션별로 접속 주소는 변하지 않았고 내용만 바뀐 것을 알 수 있다.

애플리케이션 삭제하기

더 이상 서비스하지 않길 원한다면 다음 커맨드로 삭제할 수 있다.

kubectl delete service hello-world

kubectl delete service hello-world2

또한 클러스터를 구성하는 Google Compute Engine의 VM 인스턴스, 디스크, 네트워크 등 각종 리소스까지 제거하려면 다음 커맨드를 수행하면 된다.

gcloud container clusters delete hello-cluster