서비스와 컨테이너 * 도커 스웜 환경에서는 서비스를 배포하면 스웜이 대신 컨테이너를 실행해 준다. * 서비스는 컨테이너를 추상화한 개념으로 컨테이너와 같은 정보로 정의된다. * 사용되는 이미지 * 환경 변수 * 공개되는 포트 등 * 여기에 서비스의 이름이 도커 네트워크상에서 그대로 도메인으로 사용된다는 점도 컨테이너와 같다. * 차이점이라면, 서비스는 여러 개의 레플리카(서비스와 똑같이 설정되지만 스웜상의 여러 노드에 흩어져 배치될 수 있다)를 가질 수 있다 는 점이다.
실습 도커 허브에 있는 이미지로 컨테이너 하나를 실행하는 서비스를 만들어라. 그리고 서비스 목록을 확인해 새로 실행한 서비스가 제대로 실행 중인지 확인해 보자.
- 서비스는 도커 스웜의 일급 객체이지만, 서비스를 다루려면 도커 엔진이 스웜 모드이거나 스웜 매니저에 연결된 상태여야 한다.
001) ➜ docker service create --name timecheck --replicas 1 diamol/ch12-timecheck:1.0
002) verify: Service converged
003)
004) ➜ docker service ls
005) ID NAME MODE REPLICAS IMAGE PORTS
006) uair352b8mg3 timecheck replicated 1/1 diamol/ch12-timecheck:1.0
- 001: 단일 컨테이너로 실행되는 서비스 timecheck를 스웜상에 생성한다.
- 004~006: 서비스 목록에는 실행 중인 레플리카 수, 도커 이미지 등 서비스에 대한 기본적인 정보가 함께 출력된다.
레플리카(replica) * 서비스를 구성하는 컨테이너를 레플리카라고 부른다. * 레플리카를 실행 중인 노드에 접속하면, 지금까지 컨테이너를 다룰 때와 마찬가지로 docker container 명령을 사용할 수 있다. * 노드가 하나뿐인 스웜에서는 모든 레플리카가 같은 서버에서 실행되므로 지금 만든 서비스 컨테이너를 바로 다룰 수 있다. * 컨테이너 관리를 스웜이 대신해 주니 컨테이너를 직접 다룰 일이 많지는 않겠지만, 그럴 필요가 있다면 직접 다룰 수 있다.
실습 서비스 레플리카가 현재 실행 중이지만, 스웜이 레플리카의 관리를 맏고 있다. 직접 컨테이너를 삭제해 보면 스웜이 레플리카 수가 부족해졌다고 판단하고 새로운 컨테이너를 실행한다.
001) # 이 서비스의 레플리카 목록을 확인한다.
002) ➜ docker service ps timecheck
003) ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
004) ympow8yhkugp timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop Running Running 6 minutes ago
005)
006) # 현재 컴퓨터에서 실행 중인 컨테이너를 확인한다.
007) ➜ docker container ls
008) CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
009) 88e2fd5d910e diamol/ch12-timecheck:1.0 "dotnet TimeCheck.dll" 6 minutes ago Up 6 minutes timecheck.1.ympow8yhkugpyyf57cmxkc6q4
010)
011) # 가장 최근에 생성한 컨테이너(레플리카)를 삭제한다.
012) ➜ docker container ls --last 1 -q
013) 88e2fd5d910e
014)
015) # 가장 최근에 생성한 컨테이너(레플리카)를 삭제한다.
016) ➜ docker container rm -f $(docker container ls --last 1 -q)
017) 88e2fd5d910e
018)
019) # 레플리카 목록을 다시 확인한다.
020) ➜ docker service ps timecheck
021) ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
022) uiko76xirpn4 timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop Running Running 5 seconds ago
023) ympow8yhkugp \_ timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop Shutdown Failed 10 seconds ago "task: non-zero exit (137)"
- 002: service ps 명령은 해당 서비스의 레플리카 목록을 출력한다.
- 009: 컨테이너 이름은 서비스 이름, 레플리카 번호, 레플리카 식별자를 붙여 짓는다.
- 022~023: 레플리카 컨테이너를 직접 삭제하면, 스웜은 서비스의 레플리카가 부족하다고 판단하고 새 레플리카를 실행한다.
실습 스웜 모드에서는 docker service 명령을 사용해 애플리케이션을 관리한다. 이 명령으로 레플리카의 로그 같은 각 레플리카의 정보나 서비스에 대한 전반적인 정보 를 확인할 수 있다.
- docker service 명령을 사용해 레플리카의 로그를 확인하거나 서비스의 구성을 확인할 수 있다.
001) # 최근 10초간의 로그를 출력
002) ➜ docker service logs --since 10s timecheck
003) timecheck.1.uiko76xirpn4@docker-desktop | App version: 1.0; time check: 00:38.39
004) timecheck.1.uiko76xirpn4@docker-desktop | App version: 1.0; time check: 00:38.44
005)
006) # 서비스의 정보 중 이미지 정보를 출력한다.
007) ➜ docker service inspect timecheck -f '{{.Spec.TaskTemplate.ContainerSpec.Image}}'
008) diamol/ch12-timecheck:1.0@sha256:9d3010a572344c988da8e28444ed345c63662a5c211886e670a8ef3c84689b4e
- 002: 서비스에 속한 모든 레플리카의 ~ 컨테이너 로그를 출력한다. 파라미터 since를 사용해 출력 범위를 최근 10초로 제한했다.
-
003~004: 로그 엔트리는 레플리카 식별자와 함께 출력되므로 로그를 생성한 컨테이너를 추적할 수 있다.
-
서비스 전체의 구성 정보는 클러스터에 저장돼 있으므로, service inspect 명령을 입력하면 확인할 수 있다.
- 클러스터 데이터베이스에는 상당히 많은 정보가 들어 있는데, 이들 정보는 안전하게 암호화돼 모든 매니저 노드마다 복제본이 위치한다.
- 도커 컴포즈가 도커 스웜과 가장 크게 다른 점은 애플리케이션 정의를 저장할 공간을 갖지 않는다는 것이다.
실습 timecheck 서비스의 이미지 버전을 변경하라. 새 버전은 이전 버전과 마찬가지로 몇 초에 한 번씩 타임스탬프 값을 출력하지만, 로그에 애플리케이션 버전이 삽입된다.
001) # 서비스에 사용된 이미지 버전을 수행한다.
002) ➜ docker service update --image diamol/ch12-timecheck:2.0 timecheck
003) timecheck
004) overall progress: 1 out of 1 tasks
005) 1/1: running [==================================================>]
006) verify: Service converged
007)
008) # 서비스의 레플리카 목록을 확인한다.
009) ➜ docker service ps timecheck
010) ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
011) o8hb0zg18qjv timecheck.1 diamol/ch12-timecheck:2.0 docker-desktop Running Running 13 seconds ago
012) uiko76xirpn4 \_ timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop Shutdown Shutdown 15 seconds ago
013) ympow8yhkugp \_ timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop Shutdown Failed 17 minutes ago "task: non-zero exit (137)"
014)
015) # 레플리카 로그도 확인한다.
016) ➜ docker service logs --since 20s timecheck
017) timecheck.1.o8hb0zg18qjv@docker-desktop | App version: 2.0; time check: 00:47.49
018) timecheck.1.o8hb0zg18qjv@docker-desktop | App version: 2.0; time check: 00:47.54
019) timecheck.1.o8hb0zg18qjv@docker-desktop | App version: 2.0; time check: 00:47.59
020) timecheck.1.o8hb0zg18qjv@docker-desktop | App version: 2.0; time check: 00:48.04
- 009~013: 태그가 1.0인 이미지로 실행된 컨테이너는 내려갔고, 새로 실행된 컨테이너는 태그가 2.0인 이미지로 실행된 것이다.
- 016~020: 각 로그에는 레플리카의 식별자가 달려 있어 어느 레플리카에서 출력한 것인지 알 수 있다. 로그는 애플리케이션에서 컨테이너에 남긴 것으로, 스웜이 이를 다시 수집하고 레플리카 식별자를 달아 보여 주는 것이다
롤링 업데이트 * 모든 컨테이너 오케스트레이션 도구는 애플리케이션을 업데이트할 때 애플리케이션을 중단시키지 않고 점진적으로 컨테이너를 교체해 나가는 롤링 업데이트 방식을 사용한다. * 스웜에서는 한 번에 한 레플리카씩 교체하는 방식을 사용하는데, 이는 두 개씩 교체해 나가도록 설정할 수도 있고 새로 투입된 컨테이너의 상태가 정상인지 확인한 후 다음 교체를 시작하도록 할 수도 있다. * 롤링 업데이트 중에는 두 버전이 모두 실행되고 있으므로 사용자도 두 버전 중 한 가지를 마주하게 된다. 이러한 이유로 롤링 업데이트 중의 사용자 경험은 직접 관리해야 한다. * 자동화된 롤링 업데이트는 수동 배포에 비하면 천지 차이라 할 만큼 크게 발전한 방식으로, 자기 수복(self-healing)형 애플리케이션의 또 다른 기능적 축을 담당한다. * 업데이트 과정에서 신규 투입된 컨테이너의 상태를 확인하게 되는데, 새로 투입된 신 버전 컨테이너에서 문제가 발생하면 업데이트가 자동으로 중단돼 전체 애플리케이션으로 문제가 번지지 않도록 막는다. * 스웜의 데이터베이스는 이전 버전의 서비스 정의 내용이 남아 있으므로 명령 한 번으로 이전 버전으로 롤백할 수 있다.
실습 배포 작업 중 이상이 발생하면 이전 상태로 롤백하는 경우가 많다. 도커 스웜도 애플리케이션의 이전 상태를 저장하고 있기 때문에 애플리케이션 롤백 기능을 제공한다.
001) # 이전 버전으로 롤백
002) ➜ docker service update --rollback timecheck
003) timecheck
004) rollback: manually requested rollback
005) overall progress: rolling back update: 1 out of 1 tasks
006) 1/1: running [==================================================>]
007) verify: Service converged
008)
009) # 레플리카의 목록 확인
010) ➜ docker service ps timecheck
011) ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
012) 7haak0lncd4u timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop Running Running 22 seconds ago
013) zcrpc052jsa2 \_ timecheck.1 diamol/ch12-timecheck:2.0 docker-desktop Shutdown Shutdown 25 seconds ago
014) o8hb0zg18qjv \_ timecheck.1 diamol/ch12-timecheck:2.0 docker-desktop Shutdown Failed 8 hours ago "task: non-zero exit (255)"
015) ympow8yhkugp \_ timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop Shutdown Failed 11 hours ago "task: non-zero exit (137)"
016)
017) # 최근 25초 동안 모든 레플리카의 로그 출력
018) ➜ docker service logs --since 25s timecheck
019) timecheck.1.7haak0lncd4u@docker-desktop | App version: 1.0; time check: 11:44.58
020) timecheck.1.7haak0lncd4u@docker-desktop | App version: 1.0; time check: 11:45.03
021) timecheck.1.7haak0lncd4u@docker-desktop | App version: 1.0; time check: 11:45.08
022) timecheck.1.7haak0lncd4u@docker-desktop | App version: 1.0; time check: 11:45.13
023) timecheck.1.7haak0lncd4u@docker-desktop | App version: 1.0; time check: 11:45.18
- 002: 롤백은 특수한 업데이트의 일종이다. 스웜의 데이터베이스에 남아 있는 이전 버전의 정의대로 애플리케이션을 되돌린다.
-
012: 2.0에서 1.0으로 롤백되었다.
-
롤백 과정도 업데이트와 같이 롤링을 거친다. 하지만 저장 중인 이전 상태로 돌아가는 것이므로 이미지 태그를 새로이 지정할 필요는 없다.
- 업데이트 중 헬스 체크에서 확인할 수 없는 사항 등의 이유로 애플리케이션에 도커에서 파악할 수 없는 이상이 발생했다면 롤백으로 즉시 정상 상태로 회복할 수 있다.