[![logo](https://www.hongsnet.net/images/logo.gif)](https://www.hongsnet.net)

# Service Deploy에 대한 비교 및 검토

> `Swarm과 k8s 모두 Host Mode로 동작되도록 구성`했기 때문에 Replica(set)에 대한 **확장/축소**의 검토는 수행하지 않는다. 단, 최초 도입을 검증했던 Swarm 구성에 대한 검증내역은 다음과 같다..


# hello-world (nodejs) Service

> Service Deploy를 검증하는 간단한 nodejs 컨테이너

> Container Image : registry.hongsnet.net/joohan.hong/docker/nodejs:latest


# Docker Swarm

> URL : https://swarm.freehongs.net


## Dockerfile

```bash
# cat Dockerfile
FROM node
MAINTAINER Hongs <master@hongsnet.net>

RUN mkdir -p /usr/src/app
COPY index.js /usr/src/app

EXPOSE 8080

CMD ["node", "/usr/src/app"]

```

```bash
# cat index.js
var http = require('http');
var os = require('os');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    console.log(req.socket.localAddress)
    res.end(`<h1>Docker Container ID -> ${os.hostname()}</h1><br><h1>Server IP -> ${req.socket.localAddress}</h1><h1>Client IP -> ${req.socket.remoteAddress}</h1><br>Container Tag -> Update_20200316`);
}).listen(8080);

```

## docker-compose.yml

```python
version: '3'

services:
  hongsnet-nodejs:
   image: registry.hongsnet.net/joohan.hong/docker/nodejs:latest
   ports:
     - 8080:8080
   environment:
     - SERVICE_PORTS=8080
   deploy:
     replicas: 1
     update_config:
       parallelism: 5
       delay: 10s
     restart_policy:
       condition: on-failure
       max_attempts: 3
       window: 120s
```

위의 설정 값에 대한 설명은 다음과 같다.

  - 서비스명은 hongsnet-nodejs 이다.
  - 8080번 포트를 외부에 연결하고, 환경 변수로 SERVICE_PORTS를 지정했다.
  - deploy 옵션으로는 1개의 리플레카(replicas)를 만들고 업데이트 설정(update_config)과 재시작 설정(restart_policy)을 추가했다.


## Docker Swarm

다음과 같이 Swarm은 3대로 구성했다.

  - Manager : TB2-DOCKER-MANAGER01 (172.24.0.238)
  - Node01 : TB3-DOCKER-NODE01 (172.16.0.235)
  - Node02 : TB3-DOCKER-NODE02 (172.16.0.236)


먼저 사전에 Docker Swarm 구성이 완료된 상태이며, 다음과 같이 구성된 상태이다.

```bash
# docker node ls
ID                           HOSTNAME              STATUS  AVAILABILITY  MANAGER STATUS
f6zguzgonp1iq8yr3nkahumg0 *  TB2-DOCKER-MANAGER01  Ready   Active        Leader
kj9qfttu2eispr4mvz6e5hulg    TB3-DOCKER-NODE02     Ready   Active
r0wxm3wh0p9vpx334zhllo7zy    TB3-DOCKER-NODE01     Ready   Active
```

그리고 아래와 같이 swarm 네트워크 생성도 완료된 상태이다.

```bash
# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
279270fdaeca        bridge              bridge              local
3bf40dd45669        docker_gwbridge     bridge              local
40f4fa5b4f4f        host                host                local
ymt3wq5s0ikc        ingress             overlay             swarm
a205a35afbb6        none                null                local
```

네트워크, 서비스, 그리고 **모든 컨테이너들을 스택(Stack)**이라고 부른다. 스택을 생성하기 위해서는 **docker stack** 명령어를 사용해야 하지만, 스택을  docker-compose.yml 파일로 수행하기를 원한다. 따라서 다음과 같이 명령어를 실행하면 된다.

```bash
# docker stack deploy --with-registry-auth --compose-file=docker-stack_nodejs.yml prod
```

  - 파일명은 반드시 docker-compose.yml 일 필요는 없다.
  - **--with-registry-auth** 옵션은 Private Repository의 인증정보를 Node에 전달한다는 옵션인데, GitLAB의 Registry의 경우는 제대로 동작하지 않는다. 따라서 일단 Public 하게 권한을 열어서 테스트했다.
  - prod : 이 것은 스택의 이름으로써 임의대로 지정하면 된다.

그럼 다음과 같이 Manager Node에서 컨테이너가 실행된다.

```bash
# docker stack deploy --with-registry-auth --compose-file=docker-stack_nodejs.yml prod
Creating network prod_default
Creating service prod_hongsnet-nodejs
```

그럼, 다음과 같이 Manager Node에만(replica를 1로 했으므로) 컨테이너가 실행된다.

```bash
# docker service ls
ID            NAME                  MODE        REPLICAS  IMAGE
f4axez6hdwo1  prod_hongsnet-nodejs  replicated  1/1       registry.hongsnet.net/joohan.hong/docker/nodejs:latest
```

이제 외부 클라이언트(curl 명령이용)에서 Manager Node로 접속테스트를 해본다.

```bash
# curl http://172.24.0.238:8080
<h1>Docker Container ID -> cube02</h1><br><h1>Server IP -> ::ffff:172.24.0.238</h1><h1>Client IP -> ::ffff:172.24.0.245</h1><br>Container Tag -> Update_20200316[root@TB3-DOCKER-NODE02 ~]#
```


## Docker Swarm 확장

위의 경우 replica를 1로 설정했기 때문에 Manager Node에만 컨테이너가 실행된다. 그럼 정말로 Manager Node에만 확인해보자.

- **Manager Node**

```bash
[root@TB2-DOCKER-MANAGER01 node.js]# docker ps
CONTAINER ID        IMAGE                                                                                                                     COMMAND                  CREATED             STATUS              PORTS               NAMES
aca7b58347c2        registry.hongsnet.net/joohan.hong/docker/nodejs@sha256:733ac091d6a79b4e04b318cd08b775a2c8867f8d1f4f4e7805ab26c09fca4844   "docker-entrypoint..."   4 minutes ago       Up 4 minutes        8080/tcp            prod_hongsnet-nodejs.1.wf13c8g098n0nd8zq60qgseit

[root@TB2-DOCKER-MANAGER01 node.js]# docker service ls
ID            NAME                  MODE        REPLICAS  IMAGE
f4axez6hdwo1  prod_hongsnet-nodejs  replicated  1/1       registry.hongsnet.net/joohan.hong/docker/nodejs:latest
```

- **Node01**

```bash
[root@TB3-DOCKER-NODE01 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

- **Node02**

```bash
[root@TB3-DOCKER-NODE02 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

일단, **Manager Node와 Node01**에 컨테이너를 실행하도록 수행해야하는데, 아래의 명령을 사용하면 된다.

```bash
# docker service update --replicas 2 prod_hongsnet-nodejs
prod_hongsnet-nodejs
```

> 위와 같이 On-demand로 변경해도되고, docker-compose.yml 파일의 replicas 값에 명시해도 된다.

그럼 먼저 다음과 같이 **replica 숫자가 2로 증가**된다.

```bash
# docker service ls
ID            NAME                  MODE        REPLICAS  IMAGE
f4axez6hdwo1  prod_hongsnet-nodejs  replicated  2/2       registry.hongsnet.net/joohan.hong/docker/nodejs:latest
```

이제 다시 Manager/Node01/Node02에서 컨테이너를 확인해보면, 다음과 같다.


- **Manager**

```bash
# docker ps
CONTAINER ID        IMAGE                                                                                                                     COMMAND                  CREATED             STATUS              PORTS               NAMES
aca7b58347c2        registry.hongsnet.net/joohan.hong/docker/nodejs@sha256:733ac091d6a79b4e04b318cd08b775a2c8867f8d1f4f4e7805ab26c09fca4844   "docker-entrypoint..."   9 minutes ago       Up 9 minutes        8080/tcp            prod_hongsnet-nodejs.1.wf13c8g098n0nd8zq60qgseit
```

- **Node01**

```bash
# docker ps
CONTAINER ID        IMAGE                                                                                                                     COMMAND                  CREATED              STATUS              PORTS               NAMES
c2a67cef61e7        registry.hongsnet.net/joohan.hong/docker/nodejs@sha256:733ac091d6a79b4e04b318cd08b775a2c8867f8d1f4f4e7805ab26c09fca4844   "docker-entrypoint..."   About a minute ago   Up About a minute   8080/tcp            prod_hongsnet-nodejs.2.uuh263tfwd632l8p2lktk55xl
```

- **Node02**

```bash
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

## Docker Swarm 축소

위와 같이 Replica의 값이 2인 상태에서 **다시 1로 조정**해보자.

```bash
# docker service ls
ID            NAME                  MODE        REPLICAS  IMAGE
f4axez6hdwo1  prod_hongsnet-nodejs  replicated  2/2       registry.hongsnet.net/joohan.hong/docker/nodejs:latest

# docker service update --replicas 1 prod_hongsnet-nodejs
prod_hongsnet-nodejs
```

- **Manager**

```bash
# docker service ls
ID            NAME                  MODE        REPLICAS  IMAGE
f4axez6hdwo1  prod_hongsnet-nodejs  replicated  1/1       registry.hongsnet.net/joohan.hong/docker/nodejs:latest

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

- **Node01**

```bash
# docker ps
CONTAINER ID        IMAGE                                                                                                                     COMMAND                  CREATED             STATUS              PORTS               NAMES
c2a67cef61e7        registry.hongsnet.net/joohan.hong/docker/nodejs@sha256:733ac091d6a79b4e04b318cd08b775a2c8867f8d1f4f4e7805ab26c09fca4844   "docker-entrypoint..."   6 minutes ago       Up 6 minutes        8080/tcp            prod_hongsnet-nodejs.2.uuh263tfwd632l8p2lktk55xl
```

- **Node02**

```bash
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

위의 경우에는 Manager 노드의 컨테이너가 중지되고, Node01에서 실행된 것을 확인할 수 있다.


