12 Docker Swarm and Kubernetes

seohan·2022년 3월 18일
2
post-thumbnail

고가용성과 많은 수신 트래픽을 처리할 수 있는 능력을 제공하기 위해 Docker를 실행하는 많은 머신이 있는 프로덕션 환경에서 이러한 애플리케이션이 실행되는 방식을 다룹니다.

해당 환경에서 앱은 여전히 로컬에서 실행하는 것과 동일한 Docker 이미지를 사용하여 컨테이너에서 실행되지만 모든 머신을 조정하고 컨테이너를 실행하는 관리 계층이 있습니다. 이를 오케스트레이션이라고 하며 두 가지 주요 컨테이너 오케스트레이터는 Docker SwarmKubernetes입니다. 그들은 동일한 기능과 기능을 많이 공유하지만 Kubernetes는 자체 학습 여정이 있는 복잡한 시스템입니다. 여기서 한 달 동안 Kubernetes를 학습하는 것이 귀하의 가이드가 될 것입니다. 이 장에서는 Docker에 내장된 강력한 프로덕션급 컨테이너 오케스트레이터인 Docker Swarm을 사용한 오케스트레이션에 대해 배울 것입니다. 궁극적인 목표가 Kubernetes를 배우는 것이더라도 Swarm으로 시작하는 것이 좋습니다. Kubernetes 학습 곡선은 가파르지만 Swarm을 이미 알고 있으면 훨씬 쉽습니다.

12.1 컨테이너 오케스트레이터

Docker Compose는 단일 머신에서 컨테이너를 실행하는 데 적합하지만 프로덕션 환경에서는 작동하지 않습니다. 머신이 오프라인이 되면 모든 앱을 잃게 됩니다. 프로덕션 시스템에는 오케스트레이션이 필요한 고가용성이 필요합니다. 오케스트레이터는 기본적으로 클러스터를 형성하기 위해 함께 그룹화되는 많은 시스템입니다. 오케스트레이터는 컨테이너를 관리하고, 모든 시스템 간에 작업을 분산하고, 네트워크 트래픽의 부하를 분산하고, 비정상 상태가 되는 모든 컨테이너를 교체합니다.

각 머신에 Docker를 설치하여 클러스터를 만든 다음 오케스트레이션 플랫폼(Swarm 또는 Kubernetes)과 함께 결합합니다. 그런 다음 명령줄 도구 또는 웹 UI를 사용하여 원격으로 클러스터를 관리합니다. 그림 12.1은 이것이 인프라 관점에서 어떻게 보이는지 보여줍니다.


그림 12.1 오케스트레이터는 많은 서버를 단일 클러스터로 바꾸고 컨테이너를 관리합니다.

오케스트레이터는 컨테이너를 다음 단계로 끌어올리는 추가 기능 세트를 제공합니다. 배포하는 애플리케이션에 대한 모든 정보를 저장하는 클러스터에 분산 데이터베이스가 있습니다. 그런 다음 컨테이너를 실행할 위치를 결정하는 스케줄러와 클러스터의 모든 서버 간에 하트비트를 보내는 시스템이 있습니다. 이는 신뢰성을 위한 기본 빌딩 블록입니다.

YAML 파일을 클러스터에 전송하여 애플리케이션을 배포합니다. 해당 정보를 저장한 다음 컨테이너가 앱을 실행하도록 예약하여 사용 가능한 용량이 있는 서버에 작업을 배포합니다. 앱이 실행 중일 때 클러스터는 앱이 계속 실행되는지 확인합니다. 서버가 오프라인 상태가 되어 많은 컨테이너를 잃어버리면 클러스터는 다른 서버에서 교체 컨테이너를 시작합니다.

오케스트레이터는 컨테이너 관리의 모든 힘든 작업을 수행합니다. YAML 파일에서 원하는 상태를 정의하기만 하면 클러스터에 얼마나 많은 서버가 있는지 또는 컨테이너가 실행되는 위치를 알거나 신경 쓸 필요가 없습니다. 오케스트레이터는 네트워킹, 애플리케이션 구성 및 데이터 저장을 위한 기능도 제공합니다. 그림 12.2는 네트워크 트래픽이 클러스터 내부로 라우팅되는 방식과 컨테이너가 구성 객체와 비밀을 읽고 공유 스토리지에 쓰는 방식을 보여줍니다.


그림 12.2 는 네트워킹, 구성 및 저장과 같은 컨테이너에 대한 추가 기능을 제공합니다.

오케스트레이터는 개별 시스템, 네트워크 및 저장 장치의 세부 정보를 숨깁니다. 명령줄이 연결되는 API를 통해 명령을 보내고 쿼리를 실행하여 클러스터를 단일 단위로 사용합니다. 클러스터는 1,000개의 머신 또는 단일 머신일 수 있습니다. 동일한 방식으로 작업하고 동일한 명령과 YAML 파일을 보내 앱을 관리할 수 있습니다. 앱 사용자는 클러스터의 모든 서버에 연결할 수 있으며 오케스트레이션 계층은 트래픽을 컨테이너로 라우팅합니다.

12.2 Docker Swarm 클러스터 설정

Docker Swarm은 Docker 엔진에 내장되어 있기 때문에 컨테이너 오케스트레이터를 배포하는 것은 매우 쉽습니다. 클러스터를 초기화하여 Swarm 모드로 전환하기만 하면 됩니다.

TRY Docker CLI에는 클러스터 작업을 관리하기 위한 일련의 명령이 있습니다. docker swarm init 명령은 Swarm 모드로 전환합니다. 일반적으로 인수 없이 실행할 수 있지만 시스템이 둘 이상의 네트워크에 연결되어 있으면 오류가 발생하고 Docker는 Swarm 통신에 사용할 IP 주소를 묻습니다.

$ docker swarm init

Swarm initialized: current node (6d57pnzhf25b9iubn2kevah9c) is now a manager.

아래의 출력은 Swarm이 초기화되고 내 시스템이 관리자임을 알려줍니다. 클러스터의 머신은 다른 역할, 매니저 또는 워커가 될 수 있습니다. swarm init 실행의 출력은 Swarm에 워커로 합류하기 위해 다른 시스템에서 실행해야 하는 명령을 보여줍니다.

To add a worker to this swarm, run the following command:

$ docker swarm join --token SWMTKN-1-40umrktqfwzyg2yxqyltxn9ndymio3pkxezewxki2ztgk6ar9f-7hxqp0593mnmla6ygjcyj7c2g 192.168.65.3:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

클러스터 데이터베이스는 관리A 매니저에 저장되고, 명령과 YAML 파일을 관리자에서 호스팅되는 API로 보내고, 일정 및 모니터링은 모두 매니저가 수행합니다. 워커는 일반적으로 매니저가 일정을 잡을 때 컨테이너를 실행하고 관리자가 워크로드를 실행하도록 할 수도 있지만 상태에 대해 다시 보고합니다.

일단 Swarm을 초기화하면 원하는 수의 시스템을 가입시킬 수 있습니다. Docker는 Swarm 노드의 시스템들을 호출합니다. 노드를 Swarm에 조인시키려면 동일한 네트워크에 있어야 하며 관리자로부터 가입 토큰이 필요합니다. 매니저에 대한 액세스 권한이 있는 경우 노드에 대한 토큰을 프린트하여 워커 또는 추가 매니저로 가입할 수 있으며 Swarm에 노드를 나열할 수 있습니다.

TRY Swarm 모드에 있으면 Docker CLI에서 더 많은 명령을 사용할 수 있습니다. 다음을 실행하여 작업자 또는 관리자 노드에 대한 조인 토큰을 찾고 Swarm의 모든 노드를 나열합니다.

워커 노드를 조인하는 명령:

 docker swarm join-token worker

워커를 추가

$ docker swarm join --token SWMTKN-1-40umrktqfwzyg2yxqyltxn9ndymio3pkxezewxki2ztgk6ar9f-7hxqp0593mnmla6ygjcyj7c2g 192.168.65.3:2377

매니저 노드를 조인

$ docker swarm join-token manager

$ docker swarm join --token SWMTKN-1-40umrktqfwzyg2yxqyltxn9ndymio3pkxezewxki2ztgk6ar9f-8r1n0k4ta9kg2emze5rhxm41d 192.168.65.3:2377

Swarm에 있는 노드 목록:

$ docker node ls
6d57pnzhf25b9iubn2kevah9c *   docker-desktop   Ready     Active Leader 20.10.12

단일 노드 Swarm은 컨테이너를 확장하는 옵션을 통해 고가용성을 얻지 못한다는 점을 제외하고 다중 노드 Swarm과 똑같은 방식으로 작동합니다. 그림 12.5는 개발 및 테스트 환경에 사용할 수 있는 단일 노드 Swarm과 프로덕션 환경에 사용할 다중 노드 클러스터의 아키텍처를 비교합니다.


Figure 12.5 테스트와 프로덕션 Swarms은 노드 개수가 다르지만 기능은 같습니다.

Kubernetes에 비해 Swarm의 가장 큰 장점 중 하나는 설정과 관리가 간단하다는 것입니다. 모든 서버에 Docker를 설치하고, docker swarm init를 한 번 실행하고, 다른 모든 노드에 대해 docker swarm join을 실행하면 수십 개의 노드로 Swarm을 구축할 수 있습니다. 프로세스는 프로덕션 및 테스트 환경에서 동일합니다.

12.3 Docker Swarm 서비스로 앱 실행

Docker Swarm에서 서비스를 배포하면 Swarm이 대신 컨테이너를 실행합니다. 서비스는 개별 컨테이너에 대한 개념을 추상화한 것입니다. 도커 Swarm은 같은 이유로 Compose와 동일한 용어를 사용합니다. 서비스를 여러 컨테이너로 배포할 수 있습니다.

서비스는 컨테이너를 실행하는 데 사용하는 것과 동일한 많은 정보로 정의됩니다. 사용할 이미지, 설정할 환경 변수, 게시할 포트 및 네트워크에서 DNS 이름이 되는 서비스 이름을 지정합니다. 차이점은 서비스에는 서비스의 동일한 사양을 사용하고 Swarm의 모든 노드에서 실행할 수 있는 개별 컨테이너인 많은 복제본이 있을 수 있다는 것입니다.

TRY Docker Hub의 간단한 애플리케이션 이미지를 사용하여 하나의 컨테이너를 실행하는 서비스를 만든 다음 서비스를 나열하여 올바르게 실행되고 있는지 확인합니다.

 docker service create --name timecheck --replicas 1 diamol/ch12-timecheck:1.0
 docker service ls

서비스는 Docker Swarm의 일급 객체이지만 서비스를 사용하려면 Swarm 모드에서 실행 중이거나 Swarm 관리자에 연결되어 있어야 합니다. 내 출력은 그림 12.6에 있습니다. 여기에서 서비스가 생성되고 기본 세부 정보가 서비스 목록 명령에서 표시되는 것을 볼 수 있습니다. 이 명령은 하나의 복제본이 실행 중임을 보여줍니다.

2bn4bw39k4km   timecheck   replicated   1/1        diamol/ch12-timecheck:1.0  

서비스를 구성하는 컨테이너를 replica라고 하지만 그냥 평범한 도커 컨테이너입니다. 복제본을 실행하는 노드에 연결하고 일반적인 Docker 컨테이너 명령을 사용하여 작업할 수 있습니다. 단일 노드 Swarm에서 모든 복제본은 해당 머신에서 실행되므로 방금 생성한 서비스 컨테이너로 작업할 수 있습니다.

TRY 서비스 복제본이 컴퓨터에서 실행 중이지만 Swarm에서 관리하고 있습니다. 컨테이너를 삭제할 수 있지만 Swarm은 서비스가 원하는 복제본 수 미만으로 실행되고 있음을 확인하고 교체를 생성합니다.

서비스 복제 목록:

docker service ps timecheck
 2bn4bw39k4km   timecheck   replicated   1/1        diamol/ch12-timecheck:1.0   

컨테이너 목록:

 docker container ls
 00ca378bc4f4   diamol/ch12-timecheck:1.0   "dotnet TimeCheck.dll"   6 minutes ago   Up 6 minutes                                             timecheck.1.xnfiavhnjl78qtb7ys8lnea86

가장 최근의 컨테이너를 제거

 docker container rm -f $( docker container ls --last 1 -q)
 00ca378bc4f4

복제된 서비스를 확인:

docker service ps timecheck

gvp793jk1rr3   timecheck.1       diamol/ch12-timecheck:1.0   docker-desktop   Running         Running 21 seconds ago                                 
xnfiavhnjl78    \_ timecheck.1   diamol/ch12-timecheck:1.0   docker-desktop   Shutdown        Failed 26 seconds ago    "task: non-zero exit (137)" 

서비스에 대한 복제본을 실행하는 컨테이너가 하나 있었는데 수동으로 제거했습니다. 그러나 서비스는 여전히 Swarm에 존재하며 복제본 수준이 1이어야 합니다. 컨테이너를 제거했을 때 Swarm은 실행 중인 복제본이 충분하지 않다는 것을 확인하고 교체를 시작했습니다. Swarm은 컨테이너가 중지된 이유를 모르기 때문에 최종 복제본 목록에서 원본 컨테이너가 실패한 것으로 표시됩니다. 실행 중인 복제본은 10초 동안만 가동된 새 컨테이너입니다.

Swarm 모드에서 실행할 때 앱을 서비스로 관리하고 Swarm이 개별 컨테이너를 관리하도록 합니다. Swarm의 각 노드에 연결하고 서비스에 대한 복제본을 실행 중인지 확인하고 상태를 확인하거나 로그를 인쇄하고 싶다면 컨테이너로 직접 작업해야 합니다. Docker는 Swarm 리소스에서 작동하는 명령을 제공하여 지원합니다. docker service 명령을 사용하여 모든 복제본에서 로그 항목을 인쇄하고 해당 사양을 읽기 위해 서비스를 검사할 수 있습니다.

TRY docker service 명령은 Swarm 모드에서 앱으로 작업하는 방법입니다. 모든 로그 항목과 같은 복제본에서 정보와 서비스 전체에 대한 정보를 얻을 수 있습니다.

 docker service logs --since 10s timecheck

timecheck.1.gvp793jk1rr3@docker-desktop    | App version: 1.0; time check: 03:41.46
timecheck.1.gvp793jk1rr3@docker-desktop    | App version: 1.0; time check: 03:41.51

서비스의 이미지 정보를 확인

 # get the service details, showing just the image:
 docker service inspect timecheck -f '{{.Spec.TaskTemplate.ContainerSpec.Image}}'

서비스의 전체 정보는 클러스터에 저장되며 동일한 docker service inspect 명령을 실행하지만 형식 매개변수 없이 볼 수 있습니다. 모든 관리자 노드에 복제되는 클러스터의 데이터베이스에 안전하게 저장된 많은 정보가 있습니다. 이것은 애플리케이션 정의를 위한 데이터 저장소가 없는 Docker Swarm과 Docker Compose 간의 큰 차이점 중 하나입니다.

앱 정의의 소스이기 때문에 Compose 파일이 있는 경우에만 Docker Compose로 앱을 관리할 수 있습니다. Swarm 모드에서는 앱 정의가 클러스터에 저장되므로 YAML 파일 없이 앱을 관리할 수 있습니다.

실행 중인 서비스를 업데이트하여 시도해 볼 수 있습니다. 새 이미지 버전을 지정할 수 있지만 서비스 사양의 다른 정보를 반복할 필요는 없습니다. 이것이 클러스터에서 애플리케이션 업데이트를 배포하는 방법입니다. 서비스 정의를 업데이트하면 Swarm이 변경 사항을 롤아웃하고 이전 컨테이너를 제거하고 새 컨테이너를 시작하여 복제본을 교체합니다.

TRY 새 이미지 버전을 사용하려면 timestamp 서비스를 업데이트하세요. 몇 초마다 timestamp를 작성하는 간단한 앱이지만 업데이트 버전은 로그에 새 버전을 인쇄합니다.

docker service update --image diamol/ch12-timecheck:2.0 timecheck

복제된 서비스 목록:

docker service ps timecheck

rksi8xy7flmf timecheck.1 diamol/ch12-timecheck:2.0 docker-desktop   Running Running 15 seconds ago
gvp793jk1rr3 \_ timecheck.1 diamol/ch12-timecheck:1.0 docker-desktop   Shutdown Shutdown 19 seconds ago    

로그 확인

docker service logs --since 20s timecheck

timecheck.1.rksi8xy7flmf@docker-desktop | App version: 2.0; time check: 03:53.43
timecheck.1.rksi8xy7flmf@docker-desktop | App version: 2.0; time check: 03:53.48
timecheck.1.rksi8xy7flmf@docker-desktop | App version: 2.0; time check: 03:53.53
timecheck.1.rksi8xy7flmf@docker-desktop | App version: 2.0; time check: 03:53.58

service ps가 있는 복제본을 나열하면 이미지 태그 1.0에서 실행되는 이전 복제본과 이미지 태그 2.0에서 실행되는 대체품의 두 가지 인스턴스가 있음을 알 수 있습니다. 서비스 로그에는 로그 항목을 생성하는 복제본을 볼 수 있도록 ID가 포함됩니다.

모든 컨테이너 오케스트레이터는 앱 업데이트를 위한 단계적 출시 접근 방식을 사용하여 업그레이드 중에 앱을 온라인 상태로 유지합니다. Swarm은 한 번에 하나씩 복제본을 교체하여 이를 구현하므로 앱을 호스팅하는 여러 복제본이 있는 경우 들어오는 요청을 처리하기 위해 항상 실행 중인 컨테이너가 있습니다. 롤링 업그레이드의 실제 동작은 개별 서비스에 대해 구성할 수 있습니다. 웹 앱을 제공하는 복제본이 10개 있을 수 있으며 업그레이드를 롤아웃할 때 Docker가 한 번에 2개의 복제본을 교체하도록 할 수 있으며 10개가 모두 교체될 때까지 다음 2개의 복제본을 교체하기 전에 새 컨테이너가 정상인지 확인합니다.

그림 12.10은 배포 중일 때 롤링 업그레이드가 어떻게 보이는지 보여줍니다. 일부 복제본은 애플리케이션 이미지의 이전 버전을 실행하고 일부는 새 버전을 실행합니다. 롤아웃하는 동안 앱의 두 버전이 모두 라이브 상태이며 사용자는 둘 중 하나에 도달할 수 있습니다. 업데이트의 사용자 경험 측면을 직접 관리해야 합니다.


그림 12.10 서비스 업데이트는 Docker Swarm 및 Kubernetes에서 증분입니다.

자동 롤링 업데이트는 수동 애플리케이션 릴리스에서 커다란 개선 사항이며 자가 치유 애플리케이션을 지원하는 기능입니다. 업데이트 프로세스는 새 컨테이너를 롤아웃할 때 정상 상태인지 확인합니다. 새 버전에 문제가 있고 컨테이너에 오류가 있는 경우 전체 응용 프로그램이 중단되는 것을 방지하기 위해 업데이트가 자동으로 일시 중지될 수 있습니다. Swarm은 또한 서비스의 이전 사양을 데이터베이스에 저장하므로 이전 버전으로 수동으로 롤백해야 하는 경우 단일 명령으로 이를 수행할 수 있습니다.

TRY 일반적으로 YAML 파일을 사용하여 앱 배포를 관리하지만 배포가 잘못되면 이전 상태로 롤백하는 것이 매우 유용합니다. Docker Swarm은 서비스의 현재 및 이전 상태를 데이터베이스에 저장하기 때문에 이를 수행할 수 있습니다.

이전 업데이트를 롤백합니다.

docker service update --rollback timecheck

timecheck
rollback: manually requested rollback 
overall progress: rolling back update: 1 out of 1 tasks 
1/1: running   [>          ] 
verify: Service converged 

서비스 목록:

docker service ps timecheck

로그 확인:

docker service logs --since 25s timecheck

롤백 프로세스는 단계적 롤아웃을 통해 업데이트 프로세스와 동일한 방식으로 작동하지만 가장 최근 업데이트 이전의 서비스 사양을 사용하므로 이미지 태그를 제공할 필요가 없습니다. 업데이트로 인해 Docker가 인식하지 못하는 방식으로 애플리케이션이 중단되는 경우 매우 유용합니다. 이는 상태 확인이 없거나 확인이 충분히 상세하지 않은 경우 발생할 수 있습니다. 이 경우 앱이 고장난 것을 발견했을 때 롤백 명령을 실행하기만 하면 이전 서비스 사양의 세부 정보를 찾으려고 미친 듯이 시도할 필요가 없습니다.

서비스는 컨테이너가 아니라 Swarm 모드에 있을 때 관리하는 리소스입니다. 관리할 수 있는 몇 가지 새로운 유형의 리소스도 있지만 일부 주요 Docker 리소스는 동일한 방식으로 작동합니다. 컨테이너가 Swarm 모드에서 통신해야 하는 경우 Docker 네트워크를 통해 이를 수행하고 외부 트래픽이 애플리케이션으로 들어갈 수 있도록 포트를 게시합니다.

12.4 클러스터에서 네트워크 트래픽 관리

Swarm 모드의 네트워킹은 컨테이너 내부의 앱에 관한 한 표준 TCP/IP입니다. 구성 요소는 DNS 이름으로 찾고 Docker의 DNS 서버는 IP 주소를 반환하고 컨테이너는 네트워크 트래픽을 해당 IP 주소로 보냅니다. 궁극적으로 트래픽은 컨테이너에 전달되고 응답합니다. Swarm 모드에서 요청을 보내는 컨테이너와 응답을 보내는 컨테이너는 서로 다른 노드에서 실행될 수 있지만 이는 컨테이너와 내부 앱에 모두 투명합니다.

클러스터 간 통신을 원활하게 만들기 위해 배후에서 발생하는 여러가지 영리한 네트워킹 로직이 있지만 All Just Works 때문에 굳이 파헤칠 필요가 없습니다. Swarm 모드는 오버레이 네트워크라는 새로운 유형의 Docker 네트워크를 제공합니다. 클러스터의 모든 노드에 걸쳐 있는 가상 네트워크이며 오버레이 네트워크에 서비스가 연결되면 서비스 이름을 DNS 이름으로 사용하여 서로 통신할 수 있습니다.

그림 12.12는 각 앱이 여러 노드의 여러 서비스에서 실행되는 서로 다른 앱을 지원하는 두 개의 오버레이 네트워크에서 작동하는 방식을 보여줍니다. 오버레이 네트워크를 사용하면 서비스가 동일한 앱의 일부를 형성할 때 통신할 수 있지만 네트워크가 격리되어 서로 다른 네트워크의 서비스가 서로 액세스할 수 없습니다.


그림 12.12 Swarm의 네트워크는 전체 클러스터에 걸쳐 있으며 여전히 앱 간에 격리를 제공합니다.

일반 Docker 네트워크의 컨테이너와 비교할 때 오버레이 네트워크의 서비스에는 또 다른 차이점이 있습니다. 7장에서 Docker Compose를 사용하여 단일 Compose 서비스에 대해 컨테이너의 여러 인스턴스를 확장하고 실행할 수 있음을 보았습니다. 해당 Compose 서비스에 대한 Docker에 대한 DNS 쿼리는 모든 컨테이너의 IP 주소를 반환하고 소비자가 트래픽을 보낼 주소를 선택하는 데 의존합니다. Swarm 서비스에 수백 개의 복제본이 있는 경우 확장성이 좋지 않으므로 오버레이 네트워크는 다른 접근 방식을 사용하고 서비스에 대한 단일 가상 IP 주소를 반환합니다.

TRY 이전 연습에서 간단한 앱을 제거하고 이전 장에서 사용한 NASA 이미지 애플리케이션을 위한 API 서비스와 네트워크를 생성해 보겠습니다.

원래의 앱을 삭제합니다.

 docker service rm timecheck

오버레이 네트워크를 생성:

 docker network create --driver overlay iotd-net

API 서비스를 만들어 네트워크에 연결:

docker service create --detach --replicas 3 --network iotd-net --name iotd diamol/ch09-image-of-the-day

access-log API를 만들어 네트워크에 연결:

docker service create --detach --replicas 2 --network iotd-net --name accesslog diamol/ch09-access-log

서비스를 확인:

docker service ls
accesslog   replicated 0/2 diamol/ch09-access-log:latest         
iotd        replicated 3/3 diamol/ch09-image-of-the-day:latest   

이제 NASA 이미지 API를 실행하는 서비스가 있고 서비스가 오버레이 네트워크에 연결됩니다. 그림 12.13의 내 출력에서 볼 수 있듯이 이미지 API 서비스를 실행하는 3개의 복제본과 액세스 로그 서비스를 실행하는 2개가 있습니다. 이것은 Docker Desktop을 사용하여 단일 노드 Swarm에서 여전히 실행 중이지만 500개 노드가 있는 Swarm에서 동일한 명령 세트를 실행할 수 있으며 출력은 동일합니다. 단, 복제본이 다른 노드에서 실행된다는 점만 제외합니다.

가상 IP 주소를 확인하는 가장 쉬운 방법은 컨테이너 복제본의 터미널 세션에 연결하는 것입니다. nslookup 명령으로 서비스 이름에 대한 DNS 쿼리를 수행하고 반환된 IP 주소를 확인할 수 있습니다.

TRY 가장 최근의 컨테이너에서 대화형 터미널 세션을 실행하고 API 서비스에 대한 DNS 조회를 실행하십시오.

터미널 세션을 엽니다.

 # OR on Linux containers:
 docker container exec -it $(docker container ls --last 1 -q) sh

DNS 룩업을 실행합니다.

/app # nslookup iotd

Name:      iotd
Address 1: 10.0.1.2

/app # nslookup accesslog

Name:      accesslog
Address 1: 10.0.1.7

가상 네트워킹은 트래픽을 로드 밸런싱하는 훨씬 더 효율적인 방법입니다. DNS 조회에는 단일 IP 주소가 있으며 서비스가 확장 또는 축소되는 경우에도 일정하게 유지됩니다. 클라이언트는 해당 IP 주소로 트래픽을 보내고 호스트의 네트워킹 계층은 해당 주소에 대해 실제로 여러 대상이 있음을 발견하고 사용할 대상을 결정합니다.

Docker Swarm은 서비스 간에 VIP 네트워킹을 사용하여 서비스에 대한 안정적이고 로드 밸런싱된 액세스를 제공합니다. 통신 문제를 디버그하려는 경우에 유용하기 때문에 이 사실만 알면 됩니다. 그렇지 않으면 많은 복제본이 있는 서비스에 대해 DNS 조회를 실행하고 단일 IP 주소가 반환되는 것을 보고 놀랄 수 있습니다. Swarm 서비스로 실행되는 앱은 일반적인 DNS 이름을 사용하므로 오버레이 네트워크의 복잡성이 완전히 숨겨집니다.

Swarm 모드는 클러스터로 들어오는 트래픽을 처리하기 위해 복잡한 네트워크 패턴을 단순화하는 동일한 방식을 사용합니다. 클러스터와 앱의 규모를 생각하면 이것은 훨씬 더 복잡한 문제입니다. 10개의 복제본으로 실행되는 웹 앱이 있을 수 있습니다. 클러스터에 20개의 노드가 있는 경우 일부 노드는 웹 컨테이너를 실행하지 않으며 Swarm은 컨테이너를 실행하는 노드에 요청을 전달해야 합니다. 클러스터에 5개의 노드만 있는 경우 각 노드는 여러 복제본을 실행하고 Swarm은 노드의 컨테이너 간에 로드 밸런싱을 수행해야 합니다. Swarm은 수신 네트워킹을 사용하여 이 문제를 처리합니다. 그림 12.15의 다이어그램은 모든 노드가 외부적으로 동일한 포트에서 수신 대기하고 Docker가 내부적으로 클러스터 내에서 트래픽을 지시하는 수신 작동 방식을 보여줍니다.


그림 12.15 Docker Swarm은 수신 네트워킹을 사용하여 노드의 컨테이너로 트래픽을 라우팅합니다.

ingress 네트워킹은 서비스에 대한 포트를 게시할 때 Swarm 모드의 기본값이므로 사용하기 매우 쉬운 오버레이 네트워킹과 동일합니다. 서비스를 생성할 때 포트를 게시할 수 있으며 수신 네트워크를 사용하기 위해 수행해야 하는 모든 작업입니다.

TRY 이미지 갤러리 앱의 마지막 구성 요소는 웹 사이트 자체입니다. Swarm 서비스로 실행하고 포트를 게시하면 수신 네트워크를 사용합니다.

image-gallery 앱의 프론트엔드를 생성합니다.

docker service create --detach --name image-gallery --network iotd-net --publish 8010:80 --replicas 2 diamol/ch09-image-gallery
# list all services:
 docker service ls

이제 단일 포트에서 수신 대기하는 여러 복제본이 있는 서비스가 있습니다. 여러 컨테이너가 모두 동일한 포트에서 수신 대기할 수 없기 때문에 Docker Compose에서는 이 작업을 수행할 수 없지만, 수신 네트워크를 사용하여 포트에서 수신 대기하는 서비스이기 때문에 Docker Swarm에서는 가능합니다. 클러스터에 요청이 들어오면 수신 네트워크는 요청을 수신한 노드 또는 클러스터의 다른 노드에서 실행 중인 서비스 복제본 중 하나로 이를 보냅니다. 그림 12.16은 두 개의 복제본과 게시된 포트로 실행되는 서비스를 보여줍니다.

포트를 탐색할 수 있으며 Windows 컨테이너를 실행하지 않는 한 4장에서 NASA 이미지 앱을 볼 수 있습니다. 나는 지금까지 명령의 이상한 차이점을 제외하고 Windows 및 Linux 리더의 큰 차이점을 피했지만 이 문제를 해결할 방법이 없습니다. Linux 머신이나 Mac 또는 Windows 10의 Linux 컨테이너 모드에서 Linux 컨테이너를 실행하는 경우 바로 이동하여 http://localhost:8010으로 이동하여 앱을 볼 수 있습니다. Windows Server 또는 Windows 10의 Windows 컨테이너 모드에서 Windows 컨테이너를 실행하는 경우 로컬 호스트를 사용하여 Swarm 서비스에 액세스할 수 없기 때문에 그렇게 할 수 없습니다.

이것은 Windows 컨테이너가 Linux 컨테이너와 동일한 방식으로 작동하지 않는 몇 안 되는 상황 중 하나이며 Windows 네트워킹 스택의 제한 사항입니다. 실제로는 Swarm 클러스터가 테스트 또는 프로덕션 환경에서 원격 서버가 되고 원격 시스템에 액세스할 때 수신 네트워킹이 작동하기 때문에 일반적으로 문제가 되지 않습니다. 그러나 로컬 단일 노드 Windows Swarm에서는 다른 시스템에서 검색해야만 서비스에 액세스할 수 있습니다. 좋지 않다는 것을 압니다. 하지만 "Windows에서는 이런 일이 잘 안 되는" 순간이 오기 전에 적어도 12개의 챕터가 있고 더 이상 나오지 않을 것 같습니다.

이 챕터에서 Linux 컨테이너로 전환했으며 그림 12.17에서 오늘 앱의 이미지를 볼 수 있습니다. 내 네트워크 요청이 웹 서비스에 대한 2개의 복제본 중 하나로 라우팅되고 있으며, 웹 서비스는 API 서비스에 대한 3개의 복제본 중 하나에서 데이터를 가져옵니다.


그림 12.17 서비스에 게시된 포트는 수신 네트워크를 사용하고 Swarm은 요청을 복제본으로 라우팅합니다.

앱을 배포하고 관리하는 한 클러스터의 크기는 중요하지 않습니다. 클라우드에서 50개 노드로 실행되는 클러스터에서 정확히 동일한 명령을 실행할 수 있으며 결과는 동일합니다. 즉, 모든 노드에서 액세스할 수 있는 웹 서비스의 2개 복제본, 웹 컨테이너는 모든 노드에서 액세스할 수 있습니다.

12.5 Docker Swarm과 Kubernetes 간의 선택

Docker Swarm은 간단한 컨테이너 오케스트레이터로 설계되었습니다. 이미 엄청난 인기를 누리고 있는 Docker Compose에서 네트워크와 서비스의 개념을 가져와 Docker 엔진의 일부가 된 오케스트레이터에 구축했습니다. 이제 선택은 Docker Swarm 및 Kubernetes로 귀결됩니다.

Kubernetes는 모든 주요 클라우드에서 관리형 서비스로 제공되기 때문에 더 인기 있는 옵션입니다. Microsoft Azure, AWS 또는 Google Cloud에서 CLI의 단일 명령 또는 웹 포털에서 몇 번의 클릭으로 다중 노드 Kubernetes 클러스터를 가동할 수 있습니다. 그들은 클러스터 초기화와 노드인 가상 머신 관리를 처리합니다. Kubernetes는 쉽게 확장할 수 있으므로 클라우드 제공업체는 로드 밸런서 및 스토리지와 같은 다른 제품과 통합할 수 있으므로 모든 기능을 갖춘 애플리케이션을 쉽게 배포할 수 있습니다.

Docker Swarm은 클라우드 제공업체의 관리형 서비스로 존재하지 않습니다. 부분적으로 움직이는 부품이 적어 다른 서비스와 통합하기 더 어렵기 때문입니다. 클라우드에서 Docker Swarm 클러스터를 실행하려면 VM을 프로비저닝하고 Swarm을 직접 초기화해야 합니다. 모두 자동화할 수 있지만 관리형 서비스를 사용하는 것만큼 간단하지 않습니다. 그림 12.18은 Azure에서 Docker Swarm 클러스터를 실행하려는 경우 스스로 프로비저닝하고 관리해야 하는 주요 클라우드 리소스를 보여줍니다.


그림 12.18 프로덕션 등급 Swarm을 위해 관리해야 하는 일부 클라우드 리소스

앱을 배포하는 것보다 클러스터를 배포하는 빈도가 낮고 지속적인 작업의 경우 Docker Swarm이 훨씬 간단합니다. Kubernetes의 모든 기능이 있는 것은 아니지만 대부분의 조직에 필요한 모든 것이 있습니다. Swarm 클러스터에 보내는 YAML은 간결하고 논리적인 Docker Compose 구문의 확장입니다. Kubernetes YAML 사양은 부분적으로 Kubernetes가 지원하는 추가 리소스로 인해 훨씬 더 복잡하고 장황합니다. 두 오케스트레이터 모두 궁극적으로 Docker 컨테이너를 실행하는 작업을 수행하며 동일한 Docker 이미지를 사용하지만 앱 정의의 Kubernetes 버전은 5~10배 많은 YAML을 포함할 수 있습니다.

오케스트레이션을 처음 접하는 팀에 대한 조언은 Docker Swarm으로 시작하여 Swarm에 없는 기능이 필요한 경우 Kubernetes로 이동하는 것입니다. 앱을 Docker로 이동하려면 앱에 약간의 투자를 해야 합니다. Kubernetes로 이동하면 해당 투자가 낭비되지 않습니다. 동일한 이미지에서 컨테이너를 실행하게 됩니다. 하지만 항상 간단한 결정은 아니며 몇 가지 요소를 추가해야 합니다.

  • 클라우드에 배포하는 경우 Kubernetes가 더 간단하지만 데이터 센터에 있는 경우 Swarm이 훨씬 더 쉽게 관리할 수 있습니다.

  • Swarm으로 이전하는 것은 간단합니다. Kubernetes는 배워야 할 완전히 새로운 집합이며 팀의 모든 사람이 그런 투자를 하는 것은 아닙니다.

  • Kubernetes의 복잡성은 대규모 구성이 가능하다는 점의 결과입니다. 블루/그린 배포, 자동 서비스 확장 및 역할 기반 액세스 제어와 같이 Swarm에서 쉽게 수행할 수 없는 작업을 Kubernetes를 사용하여 수행할 수 있습니다.

  • Kubernetes는 변경 사항과 새로운 기능이 계속 제공되는 반면 Swarm은 한동안 큰 새 기능 없이 안정적인 제품이었습니다.

궁극적으로 로드맵은 Learn Kubernetes in a Month of Lunches을 통해 Kubernetes로 이동할 수 있지만 거기에 도달하기 위해 서두를 필요는 없습니다. Swarm은 프로덕션 환경에서 컨테이너 오케스트레이션을 소개하고 작업 부하가 아무리 크더라도 쉽게 실행할 수 있는 훌륭한 제품입니다. Visa는 Docker의 컨퍼런스에서 Swarm 클러스터를 사용하여 블랙 프라이데이에 엄청난 급증을 포함하여 시스템을 통해 모든 지불을 지원하는 것에 대해 이야기했습니다.

12.6 Lab

이번에는 Docker Swarm 서비스로 실행되는 애플리케이션 작업 경험을 향상시키기 위한 매우 간단한 실습입니다. Swarm 클러스터에서 8장의 난수 앱을 실행했으면 합니다. 이를 연결하려면 두 개의 서비스와 네트워크가 필요하며 서비스는 다음 Docker 이미지를 사용해야 합니다.

  • diamol/ch08-numbers-api:v3
  • diamol/ch08-numbers-web:v3
profile
코드코드

0개의 댓글