Cloud Architect 꿈꾸기

Cloud Computing 35

Docker Swarm Volume

Docker를 사용할 때 컨테이너에 쓰여진 데이터는 기본적으로 컨테이너가 삭제될 때 함께 삭제된다. 그러나 Docker에서 돌아가는 서비스들은 컨테이너의 생명주기와 관계없이 데이터를 존속해야하는 경우가 있다. 이 때 Docker에서 제공하는 옵션으로 Volume과 Bind mounts, tmpfs 를 지원하는데 Volume의 경우 Docker가 관리하는 Host File System에 데이터가 저장되기 때문에 데이터를 존속시킬 수 있는 안전한 방법으로 쓰인다. 기본 도커 데몬의 경우, -v 옵션을 사용할 때 호스트와 디렉토리를 공유하는 경우와 볼륨을 사용하는 경우에 대한 구분이 없다. Swarm Mode에서는 서비스를 생성할 때 이를 명확하게 명시해줄 수 있다. volume 타입의 volume을 생성해준..

Docker Swarm Network

도커 스웜 네트워크는 세 종류로 나눌 수 있다. 1) Ingress Network 2) Overlay Network 3) docker_gwbridge Network 이번 포스팅에서는 각각 네트워크의 종류에 대해서 알아보겠다. 1. Ingress Network Ingress Network의 경우 스웜 클러스터를 생성하면 자동으로 등록되는 네트워크이다. 해당 네트워크는 스웜 모드를 사용할 때만 유요하며 스웜 클러스터에 등록된 모든 노드에 Ingress Network가 생성된다. Ingress Network는 어떤 스웜 노드에 접근하더라도, 서비스 내의 컨테이너에 접근 가능한 Routing을 구성해주며, 컨테이너 접근을 Round-Robin 방식으로 Load Balancing 해준다. 간단한 예제를 통해 In..

Swarm mode의 서비스 장애 복구

Replicated mode로 생성된 서비스는 컨테이너가 중단되거나 특정 노드가 다운되면 스웜 매니저에서 새로운 컨테이너를 생성해 자동으로 복구해준다. 매니저 노드에서 실행중인 컨테이너를 삭제하자마자 새로운 Task가 생성된 것을 볼 수 있다. 만약 특정 노드가 다운되면 해당 노드의 컨테이너가 종료되고 다른 노드에 컨테이너가 생성되게 된다. 먼저 swarm-worker1 을 다운시킨다. 이제 실행중인 서비스의 상태를 확인해보면 swarm-worker1이 중지되었으므로 각 Task가 다른 노드로 옮겨갔음을 확인할 수 있다. 이번엔 다운되었던 노드를 재시작해보기로 한다. 비록 중단되었던 노드가 다시 실행되었더라도 rebalancing은 일어나지 않는다. 즉 한 번 이동한 Task는 이동한 노드에 그대로 유지..

Swarm mode

Docker 명령어의 제어 단위가 Container 라면 Swarm mode의 제어 단위는 Service이다. Service 서비스는 같은 이미지에서 생성된 컨테이너의 집합으로, 서비스를 제어하면 해당 서비스 내의 모든 컨테이너에 같은 명령이 실행된다. 서비스 내에 컨테이너는 한 개 이상 할당 될 수 있으며, 컨테이너들은 각 워커 노드와 매니저 노드에 할당된다. 각 노드에 할당된 컨테이너들을 Task 라고 부른다. 이제 서비스를 생성해보자. docker service create ubuntu:18.04 bin/sh -c "while true; do echo hello world; sleep 1; done" 서비스를 자세히 조회해보면, docker service ps unruffled_shannon 컨테이..

Docker Swarm 구성

본격적으로 Docker Swarm을 구성하기 위해 세 개의 가상머신을 생성하겠다. 가상머신 생성은 Vagrant를 이용할 것이며, 매니저 노드 하나와 워커 노드 두 개를 생성하려한다. # -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "ubuntu/bionic64" config.vm.hostname = "swarm-manager" config.vm.network "private_network", ip: "192.168.111.100" config.vm.synced_folder ".", "/vagrant_data", disabled: true end 먼저 매니저 노드를 생성하기 위한 Vagra..

Docker Swarm Cluster를 구성하기에 앞서

이번에는 도커 스웜 클러스터를 통해 Container Orchestration 환경을 구성해보기로 한다. 들어가기에 앞서 도커 스웜에 대해 간단하게 알아보자면, 여러대의 서버에 애플리케이션을 설치하여 사용하다보면, 서버가 부하에 걸리지 않도록 분산 관리 해줄 필요성이 있다. Scheduling, Clustering, Logging, Monitoring 등의 서버 관리는 서버가 온전하게 기능을 수행할 수 있도록 도와주는 역할을 수행하는데 이들을 통칭 Server Orchestration 이라고 부른다. 도커 스웜은 서버를 운영하기 위해 사용되는 컨테이너를 자동화, 관리 즉 Orchestration 해주기 위한 서비스가 되겠다. 도커 스웜 모드의 구조는 다음과 같다. - 매니저(manager) 노드와 워커(..

Docker Compose 이용하기

설치 참조 https://docs.docker.com/compose/install/ Install Docker Compose docs.docker.com Windows의 경우 Docker를 설치할 때 Docker Compose도 함께 설치된다. 도커 컴포즈를 통해 컨테이너를 실행하기 위해 yml 파일을 생성해주자. version: "3" # 문법 버전 services: echo: # 컨테이너 이름 image: boolks/dockertest # 컨테이너 생성에 사용할 도커 이미지 ports: - 9000:8080 # 포트 포워딩 ⇒ 호스트:컨테이너 docker-compose up명령어를 통해 실행시키면 정상적으로 컨테이너가 실행된다. 도커 컴포즈는 down 명령어를 통해 중지시킬 수 있는데 down의 경..

Container 내부에 명령어를 전달하기

실행중인 컨테이너를 조작하기 위해 내부에 명령어를 주거나 내부 쉘을 이용하는 방법에 대해 알아본다. 1. exec 이용 도커를 실행시킨 후. docker container exec 명령어를 통해 컨테이너 내부에 명령어를 실행시켰다. 2. 컨테이너 내부 쉘 이용 docker container exec -it echo /bin/sh 위와 같은 명령어를 통해 shell에 접속하여 커맨드를 입력할 수 있다. 참고로 옵션의 경우 -i : 상호작용 (interactive)을 함 (표준 입출력 사용) -t : 터미널 (terminal)을 사용함 으로 정리할 수 있다. 호스트 파일을 컨테이너 내부로 복사 호스트의 파일 또는 디렉토리를 컨테이너 내부로 복사하는 방법 또한 알아보자. 먼저, 간단하게 테스트용 파일을 만든다..

Docker Image를 검색하고 받아오기

Docker Image를 검색하는 방법에 대해서는 search 명령어를 통해 조회하는 것과 HTTP API를 이용하는 방법이 있다. 1. Docker search search의 경우 STARS가 높은 순으로 출력되며, --limit를 주게되면 상위 몇 개의 이미지를 조회할 수 있다. 외부 레포지터리에서 이미지를 가져올 때 다음과 같은 순서에 해당하는 이미지를 사용할 것을 권장한다. 1) 공식 배포 이미지 2) Dockerfile이 공개된 이미지 3) STARS를 받은 이미지 2. HTTP API 이용 https://docs.docker.com/registry/spec/api/ Docker에서 지원하는 Docker Registry HTTP API V2를 통해 Docker Hub에 등록된 이미지를 쉽게 가져..

Docker Image 직접 만들기

Hello Docker!!를 메세지를 응답처리하는 Image를 직접 만들어보겠다. 먼저 테스트를 위해 실제 코드가 들어갈 go 파일을 작성했다. package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { log.Println("received request") fmt.Fprintf(w, "Hello Docker!!") }) log.Println("start server") server := &http.Server{ Addr: ":8080" } if err := server.ListenAndServe(); err != nil { log...