# Docker Swarm 容器集群 ## Docker Swarm 安裝 * 三台 VM * manager * node1 * node2 ### Manager * 初始化 (會給連線用的Token) ```bash= $ sudo docker swarm init --advertise-addr 192.168.68.201 Swarm initialized: current node (lu170z4o841cvflz6kgfqv3dd) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-5ze0djseob3b2sk5658p4lfh317t5ht6oty0qc513n0oyejufz-659xe4d52mn4a0sslqj242q5t 192.168.68.201:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. ``` * 查看連線 ```bash= $ sudo docker node ls [sudo] password for user: ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION lu170z4o841cvflz6kgfqv3dd * docker1 Ready Active Leader 24.0.7 9e58igu1n2rs4q6cz8p4k6nrh docker2 Ready Active 24.0.7 n2zbpzslirsjrazhql3iir30k docker3 Ready Active 24.0.7 ``` * 查看Token ```bash= $ sudo docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-5ze0djseob3b2sk5658p4lfh317t5ht6oty0qc513n0oyejufz-659xe4d52mn4a0sslqj242q5t 192.168.68.201:2377 $ sudo docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-5ze0djseob3b2sk5658p4lfh317t5ht6oty0qc513n0oyejufz-3o35ghm8dh6oujo8ctjqvqeyz 192.168.68.201:2377 ``` ### Node1 * 用建立時給的 Token 連線 ```bash= $ sudo docker swarm join --token SWMTKN-1-5ze0djseob3b2sk5658p4lfh317t5ht6oty0qc513n0oyejufz-659xe4d52mn4a0sslqj242q5t 192.168.68.201:2377 This node joined a swarm as a worker. ``` ### Node2 * 用建立時給的 Token 連線 ```bash= $ sudo docker swarm join --token SWMTKN-1-5ze0djseob3b2sk5658p4lfh317t5ht6oty0qc513n0oyejufz-659xe4d52mn4a0sslqj242q5t 192.168.68.201:2377 This node joined a swarm as a worker. ``` * 執行container ``` sudo docker run -itd -p 8888:8080 -e HOST=192.168.68.201 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock --name visualizer dockersamples/visualizer ``` * 用 Docker Visualizer 查看 方法: [Docker Visualizer](https://hackmd.io/eMFnW-DZT56SKquf7mPY1g) ![image](https://hackmd.io/_uploads/Hy-Rm5NBp.png) ## Docker Swarm Service * 啟動一個服務, 用 httpd:latest ```bash= $ sudo docker service create --name myweb httpd wbejpmbng04dac6oasnm8wod6 overall progress: 1 out of 1 tasks 1/1: running verify: Service converged $ sudo docker service ls ID NAME MODE REPLICAS IMAGE PORTS wbejpmbng04d myweb replicated 1/1 httpd:latest ``` * 再回到 Visualizer **會自動分配工作給底下的 node (再Swarm中, Manager也會被分配任務)** ![image](https://hackmd.io/_uploads/rJR7rqVr6.png) ## Docker Swarm Service 擴容 * 擴容 ```bash= $ sudo docker service scale myweb=3 [sudo] password for user: myweb scaled to 3 overall progress: 3 out of 3 tasks 1/3: running 2/3: running 3/3: running verify: Service converged $ sudo docker service ls ID NAME MODE REPLICAS IMAGE PORTS wbejpmbng04d myweb replicated 3/3 httpd:latest ``` ![image](https://hackmd.io/_uploads/HJpYU9EBT.png) * 再擴 ```bash= $ sudo 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 $ sudo docker service ls ID NAME MODE REPLICAS IMAGE PORTS wbejpmbng04d myweb replicated 5/5 httpd:latest ``` ![image](https://hackmd.io/_uploads/H1pbv5EH6.png) * 縮減 ```bash= $ sudo docker service scale myweb=2 myweb scaled to 2 overall progress: 2 out of 2 tasks 1/2: running 2/2: running verify: Service converged $ sudo docker service ls ID NAME MODE REPLICAS IMAGE PORTS wbejpmbng04d myweb replicated 2/2 httpd:latest ``` ![image](https://hackmd.io/_uploads/BJFdw9ES6.png) ## 工作分配 * 讓指定節點不接收工作 ```bash= $ sudo docker node ls # 三個節點都有工作 ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION p8xeslmh8e26b9tlzxwgn6qsf * docker1 Ready Active Leader 24.0.7 d5kukh9qwfaesvgtki2nshfao docker2 Ready Active 24.0.7 8l061ghpaouhsyeej7xj7glko docker3 Ready Active 24.0.7 $ sudo docker node update --availability drain docker1 # 不分配工作給 docker1 docker1 $ sudo docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION p8xeslmh8e26b9tlzxwgn6qsf * docker1 Ready Drain Leader 24.0.7 d5kukh9qwfaesvgtki2nshfao docker2 Ready Active 24.0.7 8l061ghpaouhsyeej7xj7glko docker3 Ready Active 24.0.7 ``` ```bash= $ sudo docker service ps myweb ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS vlpmxy0pp1yr myweb.1 httpd:latest docker2 Running Running 5 minutes ago sap5oh1wdab0 myweb.2 httpd:latest docker3 Running Running 4 minutes ago 3fcu5n7kq1h0 myweb.3 httpd:latest docker3 Running Running 2 minutes ago 2oitxiwosmle \_ myweb.3 httpd:latest docker1 Shutdown Shutdown 2 minutes ago ``` ![image](https://hackmd.io/_uploads/Hkfr9OSHT.png) * 恢復 ```bash= $ sudo docker node update --availability active docker1 docker1 ``` * 機器故障 **把 docker3 關機** ```bash= $ sudo docker service ps myweb ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS vlpmxy0pp1yr myweb.1 httpd:latest docker2 Running Running 10 minutes ago xkd4pdxfpibg myweb.2 httpd:latest docker2 Running Running 35 seconds ago sap5oh1wdab0 \_ myweb.2 httpd:latest docker3 Shutdown Running 9 minutes ago rojvqyeuwhym myweb.3 httpd:latest docker2 Running Running 35 seconds ago 3fcu5n7kq1h0 \_ myweb.3 httpd:latest docker3 Shutdown Running 7 minutes ago 2oitxiwosmle \_ myweb.3 httpd:latest docker1 Shutdown Shutdown 7 minutes ago ``` ![image](https://hackmd.io/_uploads/SyvR5uSBT.png) :::info 就算機器重新上線, 原有工作內容也不會自動分配出去 ::: ## port 開放 * 原本只有開啟 httpd 的 image (port 的欄位是空的) ```bash= $ sudo docker service ls ID NAME MODE REPLICAS IMAGE PORTS gvuabs89xy5k myweb replicated 3/3 httpd:latest ``` * 更新 port 的開放 ```bash= $ sudo docker service update --publish-add 8080:80 myweb myweb overall progress: 3 out of 3 tasks 1/3: running 2/3: running 3/3: running verify: Service converged ``` * 更新結果 ```bash= $ sudo docker service ls ID NAME MODE REPLICAS IMAGE PORTS gvuabs89xy5k myweb replicated 3/3 httpd:latest *:8080->80/tcp ``` ![1701318572532](https://hackmd.io/_uploads/r1X01qrH6.gif) ## 附載均衡 (Docker Swarm Load Balancer) ![photo_2023-12-01_14-19-33](https://hackmd.io/_uploads/SyVWigPHa.jpg) * 編輯網頁 方便顯示內容 ```bash= $ sudo docker exec -it 533 bash root@533e636e901f:/usr/local/apache2# cd htdocs/ root@533e636e901f:/usr/local/apache2/htdocs# echo "HI docker1" > hi.htm ``` * 在三台都編輯完後, 簡單測試 ```bash= $ for i in `seq 100`; do curl http://192.168.68.202:8080/hi.htm; done ``` * haproxy ```bash= # 在第四台安裝 haproxy $ sudo yum install -y epel-release $ sudo yum install -y haproxy ``` * 編輯檔案 /etc/haproxy/haproxy.cfg ```shell= global daemon chroot /var/lib/haproxy user haproxy group haproxy stats timeout 30s defaults mode http log global option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 frontend http_front bind *:80 stats uri /haproxy?stats default_backend http_back backend http_back balance roundrobin server user4-1 192.168.68.201:8080 check # 改自己IP server user4-2 192.168.68.202:8080 check server user4-3 192.168.68.203:8080 check ``` * 啟動 & 連線 ```bash= $ sudo systemctl restart haproxy ``` ## mysql + php * 透過NFS掛載3台虛擬機目錄 :::info getenforce 跟 firewall 先關閉 ::: * 安裝: `sudo yum install nfs-utils` `sudo systemctl enable rpcbind` `sudo systemctl enable nfs` * Master 端 `sudo vim /etc/exports` 在這裡新增要共享的資料夾跟權限等 **/home/user/Desktop/mydb 192.168.68.0/24(rw,sync,no_root_squash,no_all_squash)** **/home/user/Desktop/myphp 192.168.68.0/24(rw,sync,no_root_squash,no_all_squash)** `sudo systemctl restart nfs` 查看共享目錄: `showmount -e localhost` * Worker 端 查看共享目錄: `showmount -e localhost` 建立連結的目錄(名稱可以不一樣): `mkdir /home/user/Desktop/mydb` `mkdir /home/user/Desktop/myphp` 掛載: `mount -t nfs 192.168.68.148:/home/user/Desktop/mydb /home/user/Desktop/mydb` `mount -t nfs 192.168.68.148:/home/user/Desktop/myphp /home/user/Desktop/myphp` * 建立 overlay 網路 `docker network create -d overlay mynet` * 啟動 db 服務 `docker service create --name mydb --network mynet --mount type=bind,source=/home/user/Desktop/mydb,target=/var/lib/mysql --env MYSQL_ROOT_PASSWORD=123456 --publish published=3306,target=3306 mysql` * db `docker exec -it <ID> bash` `mysql -u root -p` ```sql= show databases; # 顯示目前有的資料庫 create database testdb; # 創建資料庫 use testdb; # 使用資料庫 create table addrbook(name varchar(50) not null, phone char(10)); # 創建資料表 insert into addrbook(name, phone) values ("tom", "0912123456"); # 加入資料 insert into addrbook(name, phone) values ("mary", "0912123567"); # 加入資料 select name,phone from addrbook; # 選擇資料 update addrbook set phone="0987465123"; # 更新資料 ``` * 啟動 apache(php) 服務 `docker service create --name myphp --network mynet --mount type=bind,source=/home/user/Desktop/myphp,target=/var/www/html --publish published=8888,target=80 radys/php-apache:7.4` * php * 與資料庫連結 ```php= <?php $servername="192.168.68.148"; $username="root"; $password="123456"; $dbname="testdb"; $conn = new mysqli($servername, $username, $password, $dbname); if($conn->connect_error){ die("connection failed: " . $conn->connect_error); } else{ echo "connect OK!" . "<br>"; } $sql="select name, phone from addrbook"; $result=$conn->query($sql); if($result->num_rows>0){ while($row=$result->fetch_assoc()){ echo "name: " . $row["name"] . "\tphone: " . $row["phone"] . "<br>"; } } else { echo "0 record"; } ?> ``` ![image](https://hackmd.io/_uploads/S1VKpGj7C.png)
{"description":"高可靠","contributors":"[{\"id\":\"2aa6933a-ff5f-468f-81d7-6752f397faaf\",\"add\":12081,\"del\":1122}]","title":"Docker Swarm"}
Expand menu