- 애플리케이션 배포는 서비스 중단 시간의 주요 원인
- 롤링 업데이트 설정을 미리 관리해서 새로 투입한 레플리카가 모니터링 중 오류를 일으켰을 때 롤백을 자동화 시키면 좋다.
실습 무작위 숫자 애플리케이션의 버전 v5를 실행하라(v4는 앞서 11장에서 지속적 통합을 체험하기 위해 사용했던 버전이다. 하지만 코드는 버전 v3와 같았다). 이번 배포는 버전 v5에서 꼭 필요한 설정이 컴포즈 파일에서 누락됐기 때문에 실패할 것이다.
001) # 코어 컴포즈 파일과 여러 개의 오버라이드 파일을 병합
002) ➜ docker-compose -f ./numbers/docker-compose.yml -f ./numbers/prod.yml -f ./numbers/prod-healthcheck.yml -f ./numbers/prod-update-config.yml -f ./numbers/v5-bad.yml config > stack.yml
003)
004) # 업데이트 배포
005) ➜ docker stack deploy -c stack.yml numbers
006) Updating service numbers_numbers-web (id: u578u3isd06h7p9id9ofbtdeb)
007) Updating service numbers_numbers-api (id: 4bz8ag3u3jy3ucwobhmnpwyfz)
008)
009) # 1분간 기다린 후 서비스 상태를 확인
010) ➜ docker service inspect --pretty numbers_numbers-api
011)
012) ID: 4bz8ag3u3jy3ucwobhmnpwyfz
013) Name: numbers_numbers-api
014) Labels:
015) com.docker.stack.image=diamol/ch08-numbers-api:v3
016) com.docker.stack.namespace=numbers
017) Service Mode: Replicated
018) Replicas: 6
019) UpdateStatus:
020) State: rollback_completed
021) Started: 2 minutes ago
022) Message: rollback completed
023) # ...
- 002: 이 정도로 여러 개의 컴포즈 파일을 병합하면 안정성이 떨어진다. 하지만 여기서는 기능별로 오버라이드 파일을 분리한 것이라 일반적으로 파일 개수가 이렇게 많아지지는 않는다.
- 015: v5 버전 배포가 실패하였기 때문에 v3 버전으로 롤백되어 컨테이너가 실행 중이다.
-
019~022: v5 버전을 배포하는 업데이트가 실패하여 롤백되었다.
-
이 상황은 전형적인 배포 실패 사례다.
- 새 버전의 API 레플리카가 정상적으로 생성되고 시작됐지만, 헬스 체크 과정에서 오류를 일으켰다.
- 배포 실패가 좋은 일은 아니지만, 적어도 이렇게 자동으로 롤백이 된다면 애플리케이션이 장애를 일으키지는 않을 것이다.
- 롤링 업데이트는 아래 두 가지 방식이 있다.
start-first
방식- 레플리카 컨테이너를 실행한 후 기존 컨테이너를 정지
stop-first
방식- 기존 컨테이너를 삭제 후 레플리카 컨테이너를 실행
- 레플리카 컨테이너가 헬스 체크에서 이상을 일으켜 롤백되어 다시 기존 버전의 컨테이너를 실행할 때까지 처리 능력이 저하됨
예제 14-3 업데이트 실패 시 최대한 빨리 이전 버전으로 돌아가는 롤백 설정
numbers-api:
deploy:
rollback_config:
parallelism: 6
monitor: 0s
failure_action: continue
order: start-first
- 동시 교체 레플리카 수를 6으로 지정해 이상 상태에 있는 레플리카를 한 번에 교체
- 교체 전략은 start-first를 적용해 기존 레플리카(새 버전) 종료를 신경 쓰지 않고 먼저 새 레플리카(구 버전)를 실행하도록 한다.
- 롤백이 실패하더라도 다음 레플리카를 교체할 것이므로 모니터링 시간도 불필요하다.
실습 버전 v5 업데이트를 다시 시도해 보자. 이번에는 롤백 설정을 변경한 상태로 시도한다. 롤링 업데이트는 이번에도 실패하지만, 롤백이 좀 더 빠르게 일어나며 v3 버전 API의 처리 용량이 빠르게 회복된다.
001) # 병합할 컴포즈 파일이 더 늘어났다
002) ➜ docker-compose -f ./numbers/docker-compose.yml -f ./numbers/prod.yml -f ./numbers/prod-healthcheck.yml -f ./numbers/prod-update-config.yml -f ./numbers/prod-rollback-config.yml -f ./numbers/v5-bad.yml config > stack.yml
003)
004) # 롤백 설정을 바꿔 업데이트를 재시도한다.
005) ➜ docker stack deploy -c stack.yml numbers
006) Updating service numbers_numbers-api (id: 4bz8ag3u3jy3ucwobhmnpwyfz)
007) Updating service numbers_numbers-web (id: u578u3isd06h7p9id9ofbtdeb)
008)
009) # 롤백이 끝날 때까지 기다린 후 서비스 상태를 확인한다.
010) ➜ docker service inspect --pretty numbers_numbers-api
011)
012) ID: 4bz8ag3u3jy3ucwobhmnpwyfz
013) Name: numbers_numbers-api
014) Labels:
015) com.docker.stack.image=diamol/ch08-numbers-api:v3
016) com.docker.stack.namespace=numbers
017) Service Mode: Replicated
018) Replicas: 6
019) UpdateStatus:
020) State: rollback_completed
021) Started: About a minute ago
022) Message: rollback completed
023) # ...
-
002: 앞서 실패한 업데이트와 같은 설정이므로 이번에도 업데이트는 실패한다. 하지만 롤백 설정이 변경됐기 때문에 이전 버전으로 돌아가는 시간이 줄어든다.
-
단일 노드 환경에서는 API 서비스의 레플리카 수가 그리 많지 않기 때문에 차이가 미미하지만, 큰 규모의 서비스에서는 이 차이를 무시할 수 없다.
- 예를 들어 20개 노드에 걸쳐 100개 레플리카로 실행 중인 서비스를 롤백하는데, 한 번에 컨테이너 하나씩 교체해 나간다면 그만큼 서비스 처리 용량이 저하된 상태가 길어진다.
실습 버전 v5 업데이트가 실패하고 이전 버전으로 롤백됐다. 개발 팀을 소집해 확인해 보니 중요한 설정 하나가 누락돼 있었다. 오버라이드 파일 vS.yml에 누락된 설정을 추가하고 prod-full.yml 파일에 운영 환경 관련 설정을 모두 모았다. 이제 버전 vS를 제대로 배포할 준비가 끝났다.
- 이전까지 컴포즈 파일을 여러 파일로 분할한 이유는 롤백 설정과 업데이트 설정을 나눠 설명하기 위함
- 대개의 경우 코어 컴포즈 파일 하나 와 환경별 오버라이드 파일 하나, 버전을 정의하는 파일 정도가 일반적
001) # 일반적인 방식 - 운영 환경용 설정을 모두 prod-full.yml 한 파일에 모음
002) ➜ docker-compose -f ./numbers/docker-compose.yml -f ./numbers/prod-full.yml -f ./numbers/v5.yml config > stack.yml
003)
004) # 오류가 수정된 버전 v5 배포
005) ➜ docker stack deploy -c stack.yml numbers
006) Updating service numbers_numbers-api (id: 4bz8ag3u3jy3ucwobhmnpwyfz)
007) Updating service numbers_numbers-web (id: u578u3isd06h7p9id9ofbtdeb)
008) ➜ docker service inspect --pretty numbers_numbers-api
009)
010) ID: 4bz8ag3u3jy3ucwobhmnpwyfz
011) Name: numbers_numbers-api
012) Labels:
013) com.docker.stack.image=diamol/ch14-numbers-api:v5
014) com.docker.stack.namespace=numbers
015) Service Mode: Replicated
016) Replicas: 6
017) UpdateStatus:
018) State: completed
019) Started: About a minute ago
020) Completed: 45 seconds ago
021) Message: update completed
022) # ...
023) ➜ docker stack services numbers
024) ID NAME MODE REPLICAS IMAGE PORTS
025) 4bz8ag3u3jy3 numbers_numbers-api replicated 6/6 diamol/ch14-numbers-api:v5
026) u578u3isd06h numbers_numbers-web global 1/1 diamol/ch14-numbers-web:v5
- 002: 이전 업데이트에서 누락됐던 설정을 V5.ym! 파일에 추가했으므로 AP 서비스 레플리카가 정상적으로 동작해 업데이트가 성공할 것이다.
-
013: v5 버전의 이미지를 사용하고 있다.
-
간단한 데모용 애플리케이션이지만 롤백을 배우는 우리 입장에서는 일종의 도착점이라고 할 수 있다.
- 애플리케이션은 잘 동작하고 헬스 체크도 적용됐으니 AP를 여러 번 호출해 버그를 일으킨다 해도 API 레플리카가 새 레플리카로 교체되며 애플리케이션을 그대로 사용할 수 있을 것이다.
- 이전 버전으로 돌아가는 롤백은 업데이트 설정에 지정된 모니터링 시간 이내에 발생한 헬스 체크 실패에만 적용된다.
- 그 이후에는 헬스 체크 실패가 발생해도 해당 레플리카가 교체될 뿐이다.
- 만약 버전 v5를 배포하고 나서 모니터링 시간 60초 이내에 API에 버그를 일으켰다면 이전 버전으로 롤백될 것이다.