---
# System prepended metadata

title: 雲端通訊整合實務(11/17)
tags: [docker, docker swarm]

---

# 雲端通訊整合實務(11/17)
###### tags: `docker`、`docker swarm`

## docker swarm


初始化 docker swarm：
```
docker swarm init --advertise-addr 192.168.102.135
```
我們選擇`VM1`當作manager：
```
root@vm1:~# docker swarm init --advertise-addr 192.168.102.135
Swarm initialized: current node (zjtlil44moo62yxh1m4qxtw6t) is now a manager.

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

    docker swarm join --token SWMTKN-1-4jp4gdvzynvbeh5pwenqexsx2dnpljno5oo4t782ix9478vj97-5rveeqdg1k1uvdsk3w8re7vwq 192.168.102.135:2377

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

將 token 的 command 丟到`VM2`、`VM3`上：
`VM2`為 worker：

```
root@vm2:/home/user/test-dockercompose# docker swarm join --token SWMTKN-1-4jp4gdvzynvbeh5pwenqexsx2dnpljno5oo4t782ix9478vj97-5rveeqdg1k1uvdsk3w8re7vwq 192.168.102.135:2377
This node joined a swarm as a worker.
```

`VM3`為 worker：

```
root@vm3:/home/user# docker swarm join --token SWMTKN-1-4jp4gdvzynvbeh5pwenqexsx2dnpljno5oo4t782ix9478vj97-5rveeqdg1k1uvdsk3w8re7vwq 192.168.102.135:2377
This node joined a swarm as a worker.
```

這時可以做一個簡單的測試，去測試 manager 與 worker 的差異：
對於 manager 來說，是可以使用這項指令`docker node ls`
```
root@vm1:~# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
zjtlil44moo62yxh1m4qxtw6t *   vm1                 Ready               Active              Leader              19.03.7
zo2tgolcnqyj2kcutdy1dssh4     vm2                 Ready               Active                                  19.03.7
7m0j5hd9olqgdm8b77mnw7f3u     vm3                 Ready               Active                                  19.03.13

```
但是對於 worker 來說，`docker node ls`這項指令會出現報錯：
```
root@vm2:/home/user/test-dockercompose# docker node ls
Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
root@vm2:/home/user/test-dockercompose# 
```
```
root@vm3:/home/user# docker node ls
Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
root@vm3:/home/user# 
```
> 因為 `worker` 權限不夠去執行這行指令，只有`manager`去給予權限時才可使用。

更新vm1的docker swarm狀態為`drain`：
```
docker node update --availablity drain vm1
```
> drain：代表任何節點都不會在你的drain機器上工作，只有當你將drain狀態改回active後，才會回到該節點上工作。


```
root@vm1:~# docker node update --availability drain vm1
vm1
root@vm1:~# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
zjtlil44moo62yxh1m4qxtw6t *   vm1                 Ready               Drain               Leader              19.03.7
zo2tgolcnqyj2kcutdy1dssh4     vm2                 Ready               Active                                  19.03.7
7m0j5hd9olqgdm8b77mnw7f3u     vm3                 Ready               Active                                  19.03.13
p57x8bdqz57au5stc4j08l1c0     vm3                 Down                Active                                  19.03.13
root@vm1:~# 
```

若想要移除當前的節點以及工作站：

1. 刪除`worker`節點:
```
root@vm1:~# docker node rm vm2
vm2
root@vm1:~# docker node rm vm3
vm3
```
2. 離開當前工作站:
```
root@vm1:~# docker swarm leave --force
Node left the swarm.
```
> force:強制執行
> `manager`和`worker`都要執行

## docker swarm visualizer：
從 **dockerhub** 去 `pull` visualizer 套件：
```
docker pull dockersamples/visualizer
```
```
root@vm1:~# docker pull dockersamples/visualizer
Using default tag: latest
latest: Pulling from dockersamples/visualizer
cd784148e348: Pull complete 
f6268ae5d1d7: Extracting  9.437MB/18.87MB
f6268ae5d1d7: Pull complete 
97eb9028b14b: Pull complete 
9975a7a2a3d1: Pull complete 
ba903e5e6801: Pull complete 
7f034edb1086: Pull complete 
cd5dbf77b483: Pull complete 
5e7311667ddb: Pull complete 
687c1072bfcb: Pull complete 
aa18e5d3472c: Pull complete 
a3da1957bd6b: Pull complete 
e42dbf1c67c4: Pull complete 
5a18b01011d2: Pull complete 
Digest: sha256:54d65cbcbff52ee7d789cd285fbe68f07a46e3419c8fcded437af4c616915c85
Status: Downloaded newer image for dockersamples/visualizer:latest
docker.io/dockersamples/visualizer:latest
```

將 docker swarm virtualizer 執行起來：
```
root@vm1:~# docker run -itd -p 8888:8080 -e HOST=192.168.102.135  -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock --name visualizer dockersamples/visualizer
5250b5694fbb0a2c1dc3ce7ae242ca18f94b477435477bcd725a7321fe7bc970
```
確認一下容器已經執行：
```
root@vm1:~# docker ps -a
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                   PORTS                    NAMES
5250b5694fbb        dockersamples/visualizer   "npm start"              3 minutes ago       Up 3 minutes (healthy)   0.0.0.0:8888->8080/tcp   visualizer
b3e97042c8f5        testgolang                 "./testgolang"           7 hours ago         Up 7 hours               0.0.0.0:8001->8001/tcp   testgolang
b8f4ca51448e        iris                       "/bin/sh -c 'python …"   25 hours ago        Up 25 hours              0.0.0.0:5000->5000/tcp   iris
becebb97850a        httpd                      "httpd-foreground"       30 hours ago        Up 30 hours              0.0.0.0:8080->80/tcp     laughing_tereshkova
```

接下來可以到本地端網頁進行查看：

![](https://i.imgur.com/NsOBntX.png)

出現這個結果代表已經成功執行了 docker swarm virtualizer 了。

使用docker swarm啟動web服務：
```
docker service create --name myweb -p 8880:80 httpd
```
啟動完後，用`docker service ls`進行查看：
```
root@vm1:~# docker service create --name myweb -p 8880:80 httpd
t6xl05inn6u0g1p8366kpohnn
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 
root@vm1:~# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
t6xl05inn6u0        myweb               replicated          1/1                 httpd:latest        *:8880->80/tcp
root@vm1:~# 
```
而 myweb 會運行在 virtualizer 上：

![](https://i.imgur.com/DmQlGov.png)

若你想增加 myweb 的數目，可以使用：
```
docker service scale myweb=5
```
```
root@vm1:~# docker service scale myweb=5
myweb scaled to 5
overall progress: 5 out of 5 tasks 
1/5: running   
2/5: running   
3/5: running   
4/5: running   
5/5: running   
verify: Service converged 
root@vm1:~# 
```

其結果會像這樣：

![](https://i.imgur.com/AcYAEm2.png)

而你會發現，vm1上都沒有任何工作節點，是因為上面有將vm1的狀態設置成`drain`，因此任何工作節點都不會分配給vm1。

而你可以將vm1狀態改回`active`：
```
docker node update --availability active vm1
```

```
root@vm1:~# docker node update --availability active vm1
vm1
root@vm1:~# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
zjtlil44moo62yxh1m4qxtw6t *   vm1                 Ready               Active              Leader              19.03.7
zo2tgolcnqyj2kcutdy1dssh4     vm2                 Ready               Active                                  19.03.7
7m0j5hd9olqgdm8b77mnw7f3u     vm3                 Ready               Active                                  19.03.13
p57x8bdqz57au5stc4j08l1c0     vm3                 Down                Active                                  19.03.13
root@vm1:~# docker service scale myweb=4
myweb scaled to 4
overall progress: 4 out of 4 tasks 
1/4: running   
2/4: running   
3/4: running   
4/4: running   
verify: Service converged 
root@vm1:~# docker service scale myweb=5
myweb scaled to 5
overall progress: 5 out of 5 tasks 
1/5: running   
2/5: running   
3/5: running   
4/5: running   
5/5: running   
verify: Service converged 
root@vm1:~# 
```

我們只需要確認狀態是`active`後，將節點數重新設置一次，你就會發現到：

![](https://i.imgur.com/uRayjT2.png)

自從vm1狀態改回`active`，工作節點`myweb`就會重新在vm1上執行了。

## docker swarm 應用

查看節點`myweb`運行狀態：

```
docker service ls myweb
```

而docker swarm有一個特點，就是當你其中一個vm上執行了一個節點，其他vm都能互相通用，以`myweb`為例：
當你輸入了`vm1`的ip以及`vm2`、`vm3`，

![](https://i.imgur.com/C5oNSDA.png)

![](https://i.imgur.com/MLpYbhD.png)

![](https://i.imgur.com/u0JxgwC.png)

你可以看到說，當你打上不同`vm`的ip時，它都是可以通的。


## docker swarm 網路環境

根據上個例子，明明只有一個節點工作在vm2，但是為什麼其他vm1、vm3可以同樣運行，原因是docker swarm內建的loan balance + Routing Mesh幫我們完成這些事。

**docker swarm network environment：**

![](https://i.imgur.com/Q3Sj3WY.png)


查看docker Network：
```
docker network ls
```
```
root@vm1:~# docker network ls
NETWORK ID          NAME                         DRIVER              SCOPE
b899f2b11ad8        bridge                       bridge              local
1a6eeeb1e7d1        docker_gwbridge              bridge              local
631d77694a9e        harbor_harbor                bridge              local
cadc2c574a1e        host                         host                local
e6p8a0mx0fze        ingress                      overlay             swarm
d6559cfe24a2        mynet                        bridge              local
c7c68c4b8261        none                         null                local
ace41fd2ee84        test-dockercompose_default   bridge              local
```

查詢某個網路的資訊，例如`overlay`：
```
docker network inspect e6p
```

```
(省略)
...
"IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "10.0.0.0/24",
                    "Gateway": "10.0.0.1"
                }
            ]
        },
...
(省略)
```
你可以看到`overlay`的subnet為`10.0.0.0/24`，以及gateway為`10.0.0.1`



```
root@vm1:~# docker ps 
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                 PORTS                    NAMES
5250b5694fbb        dockersamples/visualizer   "npm start"              2 hours ago         Up 2 hours (healthy)   0.0.0.0:8888->8080/tcp   visualizer
b3e97042c8f5        testgolang                 "./testgolang"           9 hours ago         Up 9 hours             0.0.0.0:8001->8001/tcp   testgolang
b8f4ca51448e        iris                       "/bin/sh -c 'python …"   27 hours ago        Up 27 hours            0.0.0.0:5000->5000/tcp   iris
becebb97850a        httpd                      "httpd-foreground"       32 hours ago        Up 32 hours            0.0.0.0:8080->80/tcp     laughing_tereshkova
root@vm1:~# 
```

查看docker的`svc`資訊
```
root@vm1:~# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
f8qkvqabta11        web1                replicated          0/2                 httpd:latest        *:8000->80/tcp
```

刪除`service`服務

```
root@vm1:~# docker service rm web1
web1
root@vm1:~# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
```

`service`創建`httpd`服務，名稱叫`myweb`
```
root@vm1:~# docker service create --name myweb httpd
5pexf763sw4kmcudj511vetea
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged
```

更新`service`
```
docker service update --publish-add 8880:80 myweb
```

```
root@vm1:~# docker service update --publish-add 8880:80 myweb
myweb
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 
root@vm1:~# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
5pexf763sw4k        myweb               replicated          1/1                 httpd:latest        *:8880->80/tcp
```

查看 `myweb` 的`log`

```
root@vm1:~# docker service logs 5pe
myweb.1.9u8pvtnanpzu@vm1    | AH00557: httpd: apr_sockaddr_info_get() failed for 1323f15512d9
myweb.1.9u8pvtnanpzu@vm1    | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
myweb.1.bmt564ann0wd@vm1    | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
myweb.1.9u8pvtnanpzu@vm1    | AH00557: httpd: apr_sockaddr_info_get() failed for 1323f15512d9
myweb.1.bmt564ann0wd@vm1    | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
myweb.1.9u8pvtnanpzu@vm1    | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
myweb.1.bmt564ann0wd@vm1    | [Fri Jan 01 07:57:27.762173 2021] [mpm_event:notice] [pid 1:tid 140315680138368] AH00489: Apache/2.4.46 (Unix) configured -- resuming normal operations
myweb.1.9u8pvtnanpzu@vm1    | [Fri Jan 01 08:09:59.074157 2021] [mpm_event:notice] [pid 1:tid 140496198902912] AH00489: Apache/2.4.46 (Unix) configured -- resuming normal operations
myweb.1.9u8pvtnanpzu@vm1    | [Fri Jan 01 08:09:59.074470 2021] [core:notice] [pid 1:tid 140496198902912] AH00094: Command line: 'httpd -D FOREGROUND'
myweb.1.bmt564ann0wd@vm1    | [Fri Jan 01 07:57:27.762306 2021] [core:notice] [pid 1:tid 140315680138368] AH00094: Command line: 'httpd -D FOREGROUND'
myweb.1.bmt564ann0wd@vm1    | [Fri Jan 01 08:09:56.249892 2021] [mpm_event:notice] [pid 1:tid 140315680138368] AH00492: caught SIGWINCH, shutting down gracefully
```

若要隨時監控 log 檔的話，可以使用`-f`:
![](https://i.imgur.com/9dX5vSd.png)


## Reference
1. [上課影片](https://drive.google.com/drive/folders/1oM_ejAeSIhGbDGAVBDnVRv4DuoXaDwYw?usp=sharing)