README.md 9.58 KB
Newer Older
JooHan Hong's avatar
JooHan Hong committed
1 2 3 4
[![logo](https://www.hongsnet.net/images/logo.gif)](https://www.hongsnet.net)

# Service Deploy에 대한 비교 및 검토

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


# hello-world (nodejs) Service

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

12
> Container Image : registry.hongsnet.net/joohan.hong/docker/nodejs:latest
JooHan Hong's avatar
JooHan Hong committed
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258


# 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에서 실행된 것을 확인할 수 있다.