컨테이너를 단독으로 실행해보는 예제. 모든 명령어는 docker hub 내용을 기반으로 작성했으며 사용 환경과 업무에 따라 설정을 변경해야 한다. 해당 예시의 가상머신 서버의 ip는 192.168.1.61이며, 가상머신은 virtualbox를 사용했고, 네트워크는 "어댑터에 브릿지" 를 설정했다.

 

 

1. httpd

- httpd는 대표적인 웹서버 프로그램이다. html파일들을 올려서 홈페이지를 호스팅할 수 있다.

- 참조 : https://hub.docker.com/_/httpd

 

httpd - Docker Hub

Supported tags and respective Dockerfile links Quick reference Where to get help:the Docker Community Forums, the Docker Community Slack, or Stack Overflow Where to file issues:https://github.com/docker-library/httpd/issues Maintained by:the Docker Communi

hub.docker.com

$ docker run -dit --name my-apache-app -p 8080:80 -v /apache:/usr/local/apache2/htdocs/ httpd:2.4

이 폼은 위에 공식 도커허브에 나오는 폼의 변형이며, 호스트 서버의 /apache 경로에 html 파일을 저장하면 된다. httpd는 /usr/local/apache2/htdocs에 html파일들을 저장하기 때문. 결과는 다음과 같다. 여기에 홈페이지 통파일을 올리면 된다.

 

 

2. mariadb

- mariadb는 오픈소스 DB 중 대표적인 관계형 데이터베이스이다.

- 참조 : https://hub.docker.com/_/mariadb

 

mariadb - Docker Hub

Supported tags and respective Dockerfile links 10.4.11-bionic, 10.4-bionic, 10-bionic, bionic, 10.4.11, 10.4, 10, latest 10.3.21-bionic, 10.3-bionic, 10.3.21, 10.3 10.2.30-bionic, 10.2-bionic, 10.2.30, 10.2 10.1.43-bionic, 10.1-bionic, 10.1.43, 10.1 Quick

hub.docker.com

docker run --name some-mariadb -e MYSQL_ROOT_PASSWORD=루트비번 -itd mariadb:latest

이 폼은 위 공식 도커허브에 나오는 폼의 변형이다. mariadb에 접속할 루트 비밀번호는 직접 설정해야 한다. 또한 외부에서 연결하는 것은 고려하지 않았으므로 딱히 포트를 오픈하지는 않는다. 컨테이너가 생성되었으면, 다음과 같이 해당 컨테이너에 접속해본다.

 

docker container exec -it some-mariadb /bin/bash

접속하면 해당 컨테이너의 프롬프트로 전환되며, 여기서 database에 접속할 수 있다. 비밀번호는 컨테이너를 생성할 때 명시한 루트 비밀번호를 넣자.

 

mysql -u root -p

 

이제 아는대로 명령어를 입력해보자.

# 현재 데이터베이스 확인
show databases;

# 데이터베이스 생성
create database phones;

# 생성한 데이터베이스 사용
use phones;

# 생성한 데이터베이스 안에 테이블 있는지 확인
show tables;

# 생성한 데이터베이스 안에 테이블 생성
CREATE TABLE products ( 
           id INT(11) NOT NULL AUTO_INCREMENT, 
           name VARCHAR(100) NOT NULL, 
           comment TEXT NULL, 
           created DATETIME NOT NULL, 
           ceo VARCHAR(50) NOT NULL, 
           PRIMARY KEY(id) 
);

# 생성한 테이블의 정보 확인
DESC products;

# 테이블에 데이터 삽입하기
INSERT INTO products (name,comment,created,ceo) VALUES ('iPhone','iPhone12 Pro Max',NOW(),'tim cook');
INSERT INTO products (name,comment,created,ceo) VALUES ('Galaxy','Galaxy 20',NOW(),'lee jaeyong');

# 삽입한 데이터 확인
SELECT * FROM products;

 

3. jupyter notebook

 - 주피터 노트북은 웹브라우저에서 파이썬을 코딩하고 실행할 수 있는 프로그램이다. 사용하는 개발 라이브러리에 따라 여러가지 종류의 이미지를 다운받을 수 있다.

- 참조 : https://hub.docker.com/r/jupyter/datascience-notebook

 

Docker Hub

 

hub.docker.com

 - 해당 도커허브에서는 설치관련하여 특별한 정보는 없고, 아래 사이트에서 확인할 수 있다.

https://jupyter-docker-stacks.readthedocs.io/en/latest/index.html

 

Jupyter Docker Stacks — docker-stacks latest documentation

 

jupyter-docker-stacks.readthedocs.io

docker run -p 8888:8888 jupyter/scipy-notebook:17aba6048f44

 

이 폼은, 위 공식 사이트의 기본 예시 중 하나이다. 실행해보자. 용량이 엄청 크므로 오래 걸릴 수 있다. 해당 명령을 실행하면 아래와 같이 경로를 알려준다.

http://192.168.1.61:8888/?token=13fa3cfcfefec360f0e057b92c4c04ba893b3bfffc1a4031

IP를 192.168.1.61로 한 이유는 외부에서 접속하기 때문이며, 도커를 설치한 가상머신 자체에서 실행한다면 위에 나온대로 IP를 127.0.0.1로 하면 된다. 아래와 같은 화면이 나온다.

new 버튼을 누르고 Python3를 선택한다.

이제 다음과 같이 파이썬 코딩을 할 수 있다.

Docker Swarm Network : ingress 

 

Ingress 네트워크는 서비스의 노드들 간에 로드 밸런싱을 수행하는 Overlay 네트워크이다.  Ingress 네트워크는 도커스웜을 init 하거나 join 할 때 자동으로 생성된다. Docker Swarm에서는 서비스를 외부에 쉽게 노출하기 위해 모든 노드가 ingress라는 가상 네트워크에 속해있다. Docker swarm의 모든 노드가 노출된 포트로 클라이언트에서 요청을 하면, 해당 요청을 IPVS라는 모듈로 전달한다. IPVS는 해당 서비스에 참여하는 모든 IP주소를 추적하고 그 중 하나를 선택한 뒤, 요청을 해당 경로로 라우팅한다. 

 

포트를 노출할 때는 docker service create 명령에서 노출할 포트를 설정할 수 있다. 포트를 따로 지정하지 않는다면 매니저 노드는 30000~32767 범위 내에서 포트를 자동으로 할당한다. 

 

즉, 다시 정리하면 "서비스에서 포트를 오픈하면, 모든 노드에서 포트가 오픈되고 어떤 노드에 요청을 보내도 실행 중인 컨테이너에 자동으로 전달한다."  노드1에 컨테이너가 있는데, 노드2 IP주소:포트 로 접속하면 노드1에 있는 컨테이너에 접속이 가능하다는 것이다. 이렇게 Ingress 네트워크를 통해 load balancing이 수행된다.

 

 

위 예시에서 보면 whoami 서비스로 4567포트를 오픈한다면 3 노드 모두 4567 포트가 오픈된다. 외부에서 해당 서비스에 접속할 때, 어떤 노드를 통해서 접속하든 5개의 컨테이너 중 하나로 분산처리된다. 

 

실제 운영레벨에서는 외부에 nginx 또는 haproxy같은 로드밸런서를 둬서 하나의 IP로 전체 스웜 노드를 가리킬 수 있다.

참고 : https://docs.docker.com/engine/swarm/ingress/#/configure-an-external-load-balancer

 

* Ingress 네트워크 테스트

아래 명령을 통해 정말 어떤 아이피로 접속하든 랜덤하케 건테이너에 접속되는지 확인을 해볼 수 있다.

docker service create --name loadbalance_test --replicas 4 -p 80:80 utyk/swarm_loadbalance_check:1.0 

아래와 같이 브라우저에서 각 노드에 대한 아이피와 포트번호 80으로 접속한 후, 새로고침을 여러번 누르면 랜덤하게 컨테이너 ID가 바뀌는 것을 확인할 수 있다. 계속 F5를 연타해보자.

 

 

Docker Swarm Network : Overlay 

만약 예를들어 2개의 컨테이너가 있는데, 컨테이너1이 DB컨테이너와 접속해야 한다면, 둘다 ingress 네트워크에 배치해 외부에 노출된 상태로 통신한다면 이것은 좋은 방법이 아니다. 컨테이너간 통신을 위한 네트워크를 만들면 된다. 외부에서 접근하지 못하는 내부 컨테이너간의 네트워크에 컨테이너를 배치하여 편리함과 보안을 모두 잡을 수 있다.

# 참고 : docker_gwbridge

오버레이 네트워크(Ingress 네트워크 포함)를 개별 Docker daemon의 물리적 네트워크에 연결하는 브릿지 네트워크이다. 기본적으로, service가 실행 중인 각각의 컨테이너는 로컬 Docker daemon host의 docker_gwbridge network에 연결된다. 이 docker_gwbridge 네트워크는 docker swarm을 init 하거나 join 할 때 생성된다.

 

 

오버레이 네트워크는 Docker Swarm에 참여하는 Docker Daemon 간의 통신을 관리한다. 독립 실행 컨테이너의 네트워크를 생성하는 방법과 동일한 방식으로 생성할 수 있다. 또한 생성한 오버레이 네트워크에 Swarm service를 연결시켜 service 간에 통신을 활성화 할 수 있다. 이러한 오버레이 네트워크는 Overlay Network Driver를 사용한다.

 

버레이 네트워크를 사용하면 컨테이너는 외부에 포트를 오픈하지 않아도 되고 연결되는 다른 컨테이너와(예를들어 웹과 디비) 다른 노드에 있어도 같은 서버에 있는 것처럼 통신할 수 있다. 

# 오버레이 네트워크 생성하기
docker network create --attachable --driver overlay 이름(testbackend)

# 해당 오버레이 네트워크를 적용하여 서비스 생성하기
docker service create --name loadbalance_test2 --network=testbackend --replicas 4 -p 99:80 utyk/swarm_loadbalance_check:1.0

위와 같이 네트워크를 testbackend로 설정하면, 해당 서비스는 overlay 네트워크에 연결되며, 다른 컨테이너도 해당 testbackend에 연결했다면 서로 통신할 수 있게 된다. 아래의 inspect 명령으로 네트워크를 확인할 수 있다.

 

docker compose로 여러 컨테이너를 생성하는 경우에는 자동으로 overlay 네트워크를 생성한다. 자동으로 생성되는 overlay 네트워크의 이름을 따로 정해준다면, 아래의 예시대로 수행할 수 있다. 아래 예시는 wordpress와 db를 docker-compose로 만든 예시이다.

version: '3.1'

services:

  wordpress:
    image: wordpress
    ports:
      - 8888:80
    networks:
      - swarm_overlay_internal
    deploy:
      mode: replicated
      replicas: 3
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: wpdb

  db:
    image: mysql:5.7
    networks:
      - swarm_overlay_internal
    deploy:
      mode: replicated
      replicas: 3
    environment:
      MYSQL_DATABASE: wpdb
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'

networks:
  swarm_overlay_internal:

 

# 참고 : docker stack 명령

Docker swarm에서는 docker-compose를 실행하려면 docker stack 명령을 사용한다. stack 은 service 의 묶음인 최상위 단위이다. 즉 동일한 컨테이너의 묶음이 service, 이러한 service를 여러개 묶은것이 stack 이다. docker stack ls, docker stack rm 등의 명령어로 관리할 수 있다. 더 이상 자세한 설명은 생략한다.

 

Docker Swarm 명령어

docker service create  이미지명:태그

- 도커 서비스 생성

 

* 옵션

--mode global : 클러스터 내의 모든 노드에 컨테이너를 반드시 하나씩 생성함. 따로 --replica가 필요 없다.

                                보통 global 모드는 warm cluster를 모니터링 하기 위한 agent container 등을 생성할 때 유용하다.

--replica 숫자 : 생성할 컨테이너의 개수 명시

--name 이름 : 서비스의 이름 명시

-p 외부포트:내부포트 : 포트 설정. 도커와 동일

-network=이름 : 어떤 네트워크에 속할지 정의

--update-delay 시간s : 이 서비스에 대해 업데이트를 진행할 때, 각 task에 대한 업데이트 시 일정한 시간 간격을 두도록 설정

 

그외에도 --update-failure-action, --update-max-failure-ratio, --update-monitor, --update-order, --update-parallelism 등의 옵션을 줄 수가 있다. 

 

 


docker service ls
- 현재 서비스 확인

 

docker-machine ls

각 노드 설정정보 (네트워크 등) 확인


docker service ps 서비스명
- 현재 서비스의 컨테이너들과 상세정보 확인

docker service logs 서비스명
- 현재 서비스의 로그 확인

docker service rm
- 서비스 제거

docker service scale 서비스명=숫자
- 해당 숫자만큼 전체 노드에 걸쳐 replica를 만든다. 만약 노드가 3개고 scale=3 이라면, 모든 노드에 각각 들어간다.
- 만약 scale=5라면, 두 노드는 2개, 한 노드는 1개 총 5개의 replica가 들어간다.
- 만약 sacle=5 에서 2로 줄이면, 그만큼 replica가 줄어든다.

- 서비스의 업무부하가 커지면, 이 명령을 사용하여 컨테이너 복제를 늘려 규모를 키울 수 있다.

  이미 실행 중에 있는 서비스에서도 가능하다.

 

docker service inspect --pretty 서비스명

- 서비스의 상세정보 확인

- 옵션 --pretty 는 JSON형식의 Data를 사람이 읽기 쉽운 형태로 변환한다.

 

docker service update 이미지:태그

- 명시한 이미지로 서비스를 업데이트한다.

 

docker swarm update 

도커 스웜의 설정을 변경할 때 사용한다.

 

 

예시 : nginx 웹서버 서비스 만들고 컨트롤하기

 

1. 생성하기

서비스의 이름은 myweb이고, replica를 2개 만들고, 포트는 80으로, 이미지는 nginx 의 latest를 사용

(주의 : 서비스 내의 컨테이너는 -d(detached) mode 로 동작하는 이미지를 사용해야 함)

docker service create --name myweb --replicas 2 -p 80:80 nginx:latest

생성하면, 아래와 같이 2개의 myweb이라는 서비스의 컨테이너 2개가 여러 노드에 걸쳐 생성된다.

각각 노드의 "IP:포트" 로 접속해서 확인할 수 있다.

2. Replica 늘리기

docker service sacle myweb=3

아래와 같이 3개로 늘어난 것을 확인할 수 있다.

 

3. Replica 더 많이 늘리기

docker service sacle myweb=6

 

 

Docker Swarm 에서 Rolling Update  수행하기

Rolling update란, 클러스터된 서비스에서, 서비스의 downtime을 가지지 않고 클러스터 노드를 하나하나 업데이트 하는 것을 말한다. Docker Swarm에서는 Rolling update를 자체 지원하여 간단하게 사용할 수 있다. 자세한 정보를 확인하려면 아래 링크를 참고한

https://docs.docker.com/engine/swarm/services/#configure-a-services-update-behavior

 

Deploy services to a swarm

Swarm services use a declarative model, which means that you define the desired state of the service, and rely upon Docker to maintain this state. The state includes information such...

docs.docker.com

 

1. Swarm service 생성

docker service create --name myweb --replicas 4 --update-delay 20s -p 8888:80 nginx:1.18

다음과 같이 현재 상태를 확인할 수 있다.

 

2. 업데이트 수행

docker service update --image nginx:1.19 myweb

이렇게 명령을 수행하면서 watch docker service ps myweb 명령으로 2초간격으로 새로고침하여 지켜볼 수 있다.

지켜보면, 맨 먼저 4개중 한개의 컨테이너(nginx1.18)가 종료되고, 그다음 종료된 노드에서 새로운 nginx1.19가 시작된다. 그 후 위에서 설정한 update-delay 20초가 지난 후에, 또 다른 하나의 컨테이너가 종료되고 새로운 컨테이너가 시작되는 과정이 반복된다. 최종적으로 아래와 같이 업데이트가 완료된다.

 

 

즉 전체 slot에 대해 “한 노드에서 기존 컨테이너를 죽인 후 새로운 높은 버전의 컨테이너를 생성하고 update delay 시간만큼 기다린 후 또 새로운 노드에서 해당 작업을 반복하는 것" 이다. 이 동안, 서비스는 문제없이 지속된다. 왜 서비스가 문제없이 지속되는지는, 다음 포스팅을 참고한다.

2020/07/08 - [Docker Advanced] - [Docker Advanced] Docker Swarm network 개념 이해

 

 

Docker Swarm 에서 Update Rollback 수행하기

업데이트를 수행한 후, 문제가 있어 이전 버전으로 원상복귀를 원할 때, rollback 명령을 사용할 수 있다.  위에서 업데이트한 상태를 rollback 해 보자. 아래는 현재 상태이다.

 

* 서비스 롤백

docker service rollback myweb

위 명령을 수행하면, 바로 rollback이 진행되며, rollback은 update-delay가 적용되지 않아 빠르게 진행된다. 아래와 같이 최종 결과로 붉은색 네모칸처럼 nginx가 1.18로 롤백되었다.

롤백도 마찬가지로 서비스에 문제없이 지속되며, 업데이트처럼 현재 버전 컨테이너들이 순서대로 하나씩 shutdown 되고 롤백할 낮은 버전으로 새로 컨테이너가 생성된다. 

 

# 참고 : 기록은 언제까지 남아있는가?

docker service ps 명령으로 보면 해당 이미지의 변경 기록이 계속 남아 있는데, 이 값은 docker info의 Task History Retention Limit 값에 의해 히스토리 보관 수량이 결정된다. 이 값은 다음 명령어로 조절할 수 있다.

docker swarm update --task-history-limit 3

 

 

Docker swarm의 node 유지보수

노드, 즉 도커 엔진이 올라가 있는 물리적(또는 가상) 서버에 어떤 작업을 하기 위해 다운타임이 필요할 수 있다. 그러면 해당 노드에 있는 task (컨테이너들)을 제거해야 한다. 이 작업을 위해서는 drain 설정을 사용할 수 있다. 

docker node update --availability drain 노드명

이 명령은 해당 노드의 availability 값을 active에서 drain으로 변경한다. drain 상태의 노드에는 올라가 있던 task들이 모두 종료되고 다른 노드에서 해당 task들이 실행된다. 또한 새로운 task가 실행될 때 drain 상태의 노드에서는 실행되지 않는다. 다음과 같이 모든 컨테이너가 사라진 것을 확인할 수 있다. (myweb의 scale 값은 4이므로, 다른 노드에 myweb이 실행된 것을 확인할 수 있다)

또한 아래와 같이 노드의 상태도 확인할 수 있다.

drain 값을 다시 active하기 위해서는 다음과 같이 수행한다. 이렇게 원복해도, task들이 다시 해당 노드에서 실행되지는 않으며, 현재상태가 계속 유지된다.

docker node update --availability active 노드명

 

 

Docker Swarm 에서 문제가 발생하면?

* 컨테이너에 문제가 생기는 경우

- 예를들어, docker rm -f 컨테이너명 으로 해당 컨테이너를 삭제하면, 컨테이너가 다시 살아납니다.

 

* 노드에 문제가 생기는 경우

- 다음과 같이 swarm-node3를 init 0 으로 종료시켜 버리면, 

- 다른 살아있는 노드로 컨테이너들이 생성됩니다.

- 노드가 다시 살아나도, 다른 노드에 올라온 컨테이너는 다시 돌아오지 않습니다. 그대로 유지됩니다.

Docker Swarm이란?

 

Docker Swarm은 여러가지 컨테이너 오케스트레이션 툴 중 하나이다. (오케스트레이션은 멀티 호스트에서 컨테이너를 관리/배포하는 것) 도커 엔진에 결합된 형태로 제공되는 공식 툴인데, 별도의 도구나 agent를 추가로 설치/설정하지 않아도 매우 간단하게 쓸만한 가용성 클러스터를 만들 수 있다. 아무래도 오케스트레이션 기능으로서는 구글 쿠버네티스가 월등하여 많이 쓰이지는 않는다. 하지만 사용하기 쉽고 간편하여 작은 규모의 시스템이나 개발환경 서포트를 위한 환경에서는 쿠버네티스보다 사용하기 좋다. 또한, Swarm을 Docker Machine과 함께 사용할 때, 클라우드 서비스의 Console에 한 번도 접속하지 않고, 그리고 클라우드 위에 배포한 Host OS에 접속하지 않고도 어지간한 작업을 모두 원격으로 수행할 수가 있어서 사용하기가 매우 편리하다.

 

기능으로서는 기본적으로 각 노드에 Replica (복제된 컨테이너) 를 만들고, Replica 개수도 설정할 수 있다. (여러개의 Replica를 여러 노드에 분산) 또한 컨테이너 자동배치 및 복제, 컨테이너 그룹에 대한 로드밸런싱, 컨테이너 장애 복구, 클러스터 외부에 서비스 노출, 컨테이너 롤링 업데이트, 컨테이너 추가 또는 제거를 이용한 확장 및 축소 등의 기능이 있다.

 

또한 Docker Swarm은 Container 의 유연성과 확장성, 이동의 편리함을 활용해 기업에서 운영하는 Database, LDAP, Jenkins, Docker Registry, Elasticsearch, Grafana 등의 여러가지 서비스를 운영할 수 있다.

 

기본적으로 Docker Swarm은 Manager node Worker node로 시스템이 구성된다. (위 그림 참고) Manager node 에서는 클러스터 관리 작업을 하고 클러스터 상태 유지, 스케줄링 서비스, Swarm HTTP API Endpoint 를 제공한다. Worker Node 는 container 를 실행하는 역할만 수행한다. (쿠버네티스에서는 각각을 Master, node 라고 한다)

 

Docker Swarm에서 사용되는 개념 몇가지

Docker Swarm에서 제어하는 단위는 컨테이너가 아닌 "service" 이다. 서비스는 같은 이미지에서 생성된 컨테이너의 집합이다. 즉, Swarm에게 업무를 할당하는 논리적 단위이다. 서비스를 실행할 때, 자원 정책, 레플리카 갯수, 롤링 업데이트 정책, 스웜 외부에서 해당 서비스에 접속할 포트, 스웜 내부의 다른 서비스와 통신하기 위한 오버레이 네트워크 등을 정의할수 있다.

 

docker service 구문으로 명령을 내리면 설정에 따라 해당 서비스에 1개이상의 컨테이너가 생성될 수 있다. 이러한 컨테이너들은 worker, manager 노드에 분산 할당된다. 이러한 컨테이너들은 task라고 불린다. 또한 각각의 task는 고유의 일련번호를 가지며, 이를 slot 이라고 한다.

 

docker run 명령을 이용한 경우는 그 명령을 받은 docker Engine이 자기 자신 위에서 바로 위의 작업을 수행하게 되지만, Swarm mode의 service 명령을 받은 Manager는 Service를 수행하기 위한 Task를 계산해내고, Task를 처리할 Worker를 선택하여 Worker에게 Task를 전송하는 과정이 추가된다. 일단 Worker가 Task를 받으면, run 명령을 받았을 때와 동일한 Container 생성/기동 과정을 진행하게 된다.

 

Docker Swarm 구축하기

 

0. 기본 설정 (4노드 예시)

* 환경

- 운영체제 : CentOS 7

- 노드 : 총 4개, 가상머신 (Virtual Box)

- 네트워크 : 어댑터에 브리지로 1포트 (모두 인터넷이 가능하고 호스트PC와 같은 네트워크 계층으로 하기 위함)

 

* 각 노드 서버 정보 (Hostname과 IP 정보)

swarm-node1 : 192.168.1.185

swarm-node2 : 192.168.1.206

swarm-node3 : 192.168.1.121

swarm-node4 : 192.168.1.207

(IP 주소가 중구난방인 이유는 가상머신 네트워크를 "어댑터에 브리지" 형태로 DHCP 할당했기 때문 ㅠ)

 

* 사전작업

- 각 노드에 도커를 설치한다. 아래 링크를 참고할 것

2020/04/09 - [Docker Basic] - [Docker Basic] 05. 리눅스에 도커 설치하기

 

[Docker Basic] 05. 리눅스에 도커 설치하기

여기서는 CentOS7, Docker CE 19.03 버전 기준으로 설명합니다. https://docs.docker.com/engine/install/centos/ Install Docker Engine on CentOS To get started with Docker Engine on CentOS, make sure you..

watch-n-learn.tistory.com

* 네트워크 방화벽 설정 (https://docs.docker.com/engine/swarm/swarm-tutorial/)

Docker Swarm의 통신 포트는 다음과 같다. 다음 포트를 오픈하지 않으면 Docker Swarm을 사용할 수 없다. 또한 CentOS7 에서는 Firewalld를 사용하므로, Firewalld에서 해당 네트워크 포트를 오픈해줘야 한다. 만약 Firewalld를 내리면, iptables를 사용할 수 없어 도커 자체의 네트워크 사용이 불가능해지므로 Firewalld를 내리지 말아야 한다. 

 

- Swarm Manager default port = 2377/tcp

- node communication = 7946/tcp, 7946/udp

- overlay network = 4789/udp

 

아래 명령을 모든 Docker Swarm 노드에 입력한다.

firewall-cmd --permanent --zone=public --add-port=2377/tcp
firewall-cmd --permanent --zone=public --add-port=4789/udp
firewall-cmd --permanent --zone=public --add-port=7946/udp
firewall-cmd --permanent --zone=public --add-port=7946/tcp
firewall-cmd --reload
firewall-cmd --list-all

 

1. Swarm manager 설정

Swarm 클러스터에서 manager 역할을 할 노드를 선정한다. 여기서는 "swarm-node1" 로 선택했다. 아래 init 명령을 swarm-node1에서 수행한다. --advertise-addr은 manager 역할을 하는 IP를 입력한다. 즉 여기서는 자신의 IP를 입력한다. 

docker swarm init --advertise-addr 192.168.1.185

결과 중 docker swarm join --token 부분은 연결을 위한 비밀키가 생성된 것이다. 이 전체 라인이 하나의 명령어이며, 복사하여 각 노드들이 이 docker swarm 클러스터에 조인하도록 사용한다. 이 비밀키는 외부에 노출시키면 안된다. 공개 시 누구든 swarm colster에 연결이 가능해진다. 보안 측면 문제가 있으므로, 주기적으로 이 비밀키의 변경이 필요하다. (--rotate)

 

추가적으로, init을 수행하여 클러스터를 시작한다고 선언한 후에는 몇가지 변화가 있는데 그 중 하나는 docker network ls에 ingress 네트워크가 추가된다.

 

# 참고 : 노드 조인 비밀키 갱신하기

현재 노드 조인 비밀키 확인 : docker swarm join-token manager

새로운 노드 조인 비밀키 갱신하기 : docker swarm join-token --rotate manager

 

2. 노드 조인 및 확인

docker swarm join --token SWMTKN-1-3n5fhjksl37b92z49r4l5db5lo9osp7jucl5sqbbwnvfke5f0e-ayfzeurg6pq8iu3s3j5timvaz 192.168.1.185:2377

해당 명령을 입력하면, This node joined a aswrm as a worker 라고 결과가 뜬다.  모든 노드를 등록 후 다음 명령으로 상태를 확인한다. 아래 명령들은 docker swarm manager만 수행할 수 있다.

docker node ls

docker info

아래 내용에서 Swarm : active 항목 아래에는 노드의 수, 매니저 외 여러가지 정보들을 확인할 수 있다. 또한 맨 아래에 Warning 등의 로그가 나오는데, 문제가 있는 경우 여기서 여러 로그를 확인할 수 있다.

 

# 참고 : 조인된 노드를 삭제하기

1. 삭제할 노드에서 명령 수행 : docker swarm leave  // docker node ls 에서 STATUS가 down으로 바뀜

2. 매니저 노드에서 명령 수행 : docker node rm 노드ID // 완전히 해당 노드가 삭제됨

만약 manager node를 제거하는 경우, 더 이상 swarm cluster를 사용할 수 없음.

 

# 참고 : Manager node와 worker node 변경

- worker node -> manager node 로 변경 : docker node promote 노드명

- manager node -> worker node 로 변경 : docker node demote 노드명

 

 

3. Docker Swarm Visualization Tool 설치하기 

이 툴은 공식적인 툴은 아니지만, dockersamples가 만든 visulizer라는 컨테이너이다. 이것은 여러 호스트와 서비스를 처리할 때, 효과적으로 시각적인 피드백을 준다. 한눈에 어떤 노드에 어떤 컨테이너가 올라와 있는지 확인할 수 있다. 구축은 다음 명령어로 수행한다.

docker service create --name=Swarm_Cluster --publish=8881:8080 --constraint=node.role==manager --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock dockersamples/visualizer

브라우저에서 192.168.1.185:8881 실행하면, 아래와 같이 노드들과 컨테이너들을 확인할 수 있다. 아래 보라색 Swarm_Cluster라는 컨테이너도 현재 Manager인 swarm-node1에 올라와 있는 것이다.

 

사전 네트워크 정보

- docker 호스트는 Virtual Box 가상머신이고, 네트워크는 내 컴퓨터 어댑터에 브릿지를 했음.

- 내 컴퓨터는 공유기 밑에서 192.168.1.X 이고, docker 호스트는 192.168.1.61 이다.

- 어댑터에 브릿지를 했으므로, docker 호스트 가상머신은 내 컴퓨터와 동일한 네트워크의 서버로 이해할 수 있다.

 

nginx 컨테이너 생성하기

nginx는 대량의 요청을 처리하는 대규모 사이트에서 주로 이용하며, 리버스 프록시나 로드밸런서와 같은 기능도 갖고 있다.

 

docker container run --name webserver -d -P nginx

- nginx의 포트를 호스트의 임의 포트에 할당하여 백그라운드로 nginx 실행. 컨테이너 이름은 webserver 이다.

- 이미지가 없으면 알아서 자동으로 받는다.

 

2. 현재 상태 확인

docker ps

- 컨테이너의 80번 포트와 호스트의 32805 포트가 연결된 것을 확인할 수 있다.

 

3. 직접 접속 테스트

 

 

node.js 컨테이너 생성하기

1. 컨테이너 생성

docker run -d -it -p 9000:8000 --name=nodejs_test2 node:latest 

- 최신 node.js 컨테이너를 생성함. 백그라운드로 생성하고 인터렉티브 쉘을 열며, 이름은 nodejs_test2 이다.

 

2. 현재 상태 확인

docker ps

- 컨테이너에서 8000번포트를 사용하고, 호스트에서는 9000번 포트를 사용하여 컨테이너의 8000번 포트와 연결

 

3. 예시파일 만들기

var http = require('http');
var content = function(req, resp) {
        resp.end("Welcome to Kubernetes~!" + "\n");
        resp.writeHead(200);
}
var w = http.createServer(content);
w.listen(8000);

- 위 내용을 vi로 호스트 서버에서 nodejs_test.js 로 생성한다.

- 이 예시는 8000번 포트를 listen 하도록 설정하였다. (컨테이너의 열린 포트가 8000이므로)

 

4. 예시파일을 컨테이너에 복사하기

docker cp nodejs_test.js nodejs_test2:/nodejs_test.js

 

5. 컨테이너에 진입 후 node.js 실행

docker exec -it nodejs_test2 /bin/bash

- 진입 후, ls 명령으로 확인하면 nodejs_test.js 가 있는것을 확인할 수 있다.

- 해당 파일 위치를 확인후, 아래와 같이 실행한다.

node nodejs_test.js

- 아래와 같이 프롬프트가 떨어지지 않고 유지된다.

 

6. 직접 접속 테스트

 

 

httpd (Apache) 컨테이너 생성하기

1. 컨테이너 생성

docker run -d -p 8080:80 --name httpd-basic httpd:2.4

- httpd를 백그라운드로, 이름은 httpd-basic, 버전은 2.4 버전으로 컨테이너를 생성한다.

 

2. 현재 상태 확인

docker ps

- 포트는 컨테이너 80번, 호스트OS는 8080번으로 포트를 연결하였음.

 

3. 직접 접속 테스트

 

 

+ Recent posts