docker swarm overlay stack 服務部署記錄
專案xxx(後端),xxx-ui前端(前後端分離的專案)
依賴mysql,elasticsearch.
分別製作了四個映象來做這件事。
希望可以製作跨主機的部署,使用了swarm,以下是學習記錄。
參考 https://www.cnblogs.com/xishuai/p/docker-swarm.html
docker-machine create -d virtualbox manager1 &&
docker-machine create -d virtualbox manager2 &&
docker-machine create -d virtualbox worker1 &&
docker-machine create -d virtualbox worker2
#docker-machine ssh manager1 "docker swarm leave --force"
alias dm=docker-machine
docker-machine ssh manager1 "docker swarm init --advertise-addr 192.168.99.100"
export TOKEN=SWMTKN-1-67oknnrzlnt62wp5xecpz8nvodizd3mdtpvb2thsk6ldvolqx5-4srdcvj0vehcoc6gs8nhcp6lh
docker-machine ssh worker1 docker swarm join --token $TOKEN 192.168.99.100:2377
docker-machine ssh worker2 docker swarm join --token $TOKEN 192.168.99.100:2377
dm ssh manager1 docker swarm join-token manager
dm ssh manager2 docker swarm join --token SWMTKN-1-67oknnrzlnt62wp5xecpz8nvodizd3mdtpvb2thsk6ldvolqx5-6f3po7z2ih2n06qztl2fnj1wb 192.168.99.100:2377
#create a overlay network
當初始化 swarm 叢集或將一個 Docker 主機加入已經存在的 swarm 叢集時,Docker 主機上會建立兩個新網路:
一個稱為 ingress 的 overlay 網路,用來處理與 swarm 服務相關的控制和資料流。
當建立的 swarm 服務沒有連線到使用者自定義的 overlay 網路時,這個服務會預設連線到 ingress 網路。
一個稱為 docker_gwbridge 的bridge 網路,用來將單個的 Docker 守護程序連線到 swarm 中的其他守護程序。
可以使用 docker network create 命令建立使用者定義的 overlay 網路,就像可以建立使用者定義的 bridge 網路一樣。
服務或容器一次可以連線到多個網路。服務或容器只能通過它們各自連線的網路進行通訊。
TCP 埠 2377:用於叢集管理通訊
TCP 和 UDP 埠 7946:用於節點之間通訊
UDP 埠 4789:overlay 網路流量
要建立可以用於 swarm 服務和獨立容器跟其他 Docker 守護程序中執行的獨立容器通訊的 overlay 網路,新增 --attachable 標誌:
docker network create -d overlay --attachable my-overlay
連線到同一 overlay 網路的 swarm 服務可以有效地將所有埠暴露給對方
預設情況下,釋出埠的 swarm 服務使用路由網格(routing mesh)來完成。
當連線到任何 swarm 節點上的已釋出埠(無論是否執行給定服務)時,都會透明地將連線重定向到正在執行該服務的 worker 節點。
實際上,Docker 充當了 swarm 服務的負載平衡器。基於路由網格的服務以虛擬 IP(VIP)模式執行。
可以將 Docker 配置為使用單獨的網路介面來處理兩種不同型別的流量
初始化或加入 swarm 時,分別指定 --advertise-addr 和 --datapath-addr。
一開始在manager1上建立的這個overlay網路,只會同步到同為manager角色的機器上去,而worker節點,只會在分配到任務時才會建立剛才的網路。
#簡單構建docker的私有他庫
docker run -d -v /home/student/docker_registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry
預設拉取推送操作都是使用https協議來做的,做完這個之後,需要修改/etc/docker/daemon.json
以下是我本機的,主要是第一行,下面兩行是配置拉取映象時預設的地址,我使用的是阿里雲的,阿里雲加速,拉取映象會快些。
我們需要在上面的四個虛機中執行
{
"insecure-registries":["192.168.99.1:5000"],
"registry-mirrors": ["https://85qcsfak.mirror.aliyuncs.com"],
"graph": "/home/student/docker_data"
}
在建立的所有虛機中執行如下命令:
sudo touch /etc/docker/daemon.json &&
sudo chmod 777 /etc/docker/daemon.json &&
sudo echo '{ "insecure-registries": ["192.168.99.1:5000"] }' > /etc/docker/daemon.json
#如何把從公有庫中拉取的映象推送到私有倉庫
docker tag nginx 192.168.99.1:5000/nginx:latest
docker push 192.168.99.1:5000/nginx:latest
如上示例,需要先對映象打個標籤,然後就可以push到私服上去。
#刪除某些名字相似的容器
docker rm --force $(docker ps -q -f name=abc*)
#檢視私有倉庫內容
curl http://192.168.99.1:5000/v2/_catalog
#經過測試,通過swarm叢集建好後,可以直接使用standalone的docker run 的方式部署各自的服務,沒有問題。
唯一的一個問題是,在docker-machine創立的虛機中開啟es的時候,因為XMS過大,沒法分配記憶體導致失敗,
把es遷移到宿主機後開啟成功,整個測試也成功了。
1.直接使用standalone的方式,使用docker run -itd --net my-overlay 的方式直接部署,也沒有問題,可以跨主機互訪,服務部署成功。
2.使用docker service的方式部署,這樣可以使用--replicas 同時在多臺主機上部署服務,可以解決單點故障問題。測試成功。
3.使用docker stack deploy的方式部署,暫時還有些問題,服務部署基本成功,沒有測試通過。
docker run -itd --name mysql --net my-overlay \
-e MYSQL_ROOT_PASSWORD=xxx \
-e MYSQL_PASSWORD=xxx \
-e MYSQL_USER=xxx \
-e MYSQL_DATABASE=xxx\
-p 3306:3306 \
192.168.99.1:5000/mysql:5.7
#elastic
docker run -itd --name elastic --net my-overlay -p 9200:9200 -p 9300:9300 elastic
#server backend
docker run -itd --name xxx-server --net my-overlay -p 8080:8080 192.168.99.1:5000/xxx
#ui front end
docker run -itd --name xxx-ui --net my-overlay -p 80:80 192.168.99.1:5000/xxx-ui
下面測試使用docker service ,這樣可以自帶負載均衡和多副本,提高了高可用和高吞吐量。
docker service create --name mysql \
--network my-overlay --hostname mysql \
--replicas 2 \
-e MYSQL_ROOT_PASSWORD=xxx \
-e MYSQL_PASSWORD=xxx \
-e MYSQL_USER=xxx \
-e MYSQL_DATABASE=tss_log_insight_new_new \
192.168.99.1:5000/mysql:5.7
docker service create --name xxx-server --network my-overlay \
--replicas 2 --hostname xxx-server \
-p 8080:8080 192.168.99.1:5000/xxx
docker service create --name xxx-ui --network my-overlay \
--replicas 4 --hostname xxx-ui \
-p 80:80 192.168.99.1:5000/xxx-ui
docker-compose.yaml內容:
version: '3'
services:
tssxxx-ui:
image: 192.168.99.1:5000/xxx-ui
ports:
- 80:80
deploy:
replicas: 5
tssxxx-server:
image: 192.168.99.1:5000/xxx
environment:
- SPRING_PROFILES_ACTIVE=dev,swagger
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/tssxxx?useUnicode=true&characterEncoding=utf8&useSSL=false
- SPRING_DATASOURCE_USERNAME=xxx
- SPRING_DATASOURCE_PASSWORD=xxx
- JHIPSTER_SLEEP=10 # gives time for the database to boot before the application
# - SPRING_DATA_ELASTICSEARCH_CLUSTER_NODES=tssxxx-elasticsearch:9300
# - SPRING_DATA_ELASTICSEARCH_CLUSTER_NAME=elastic
ports:
- 8080:8080
container_name: xxx-server
hostname: xxx-server
tssxxx-mysql:
image: 192.168.99.1:5000/mysql:5.7
container_name: mysql
hostname: mysql
# volumes:
# - ~/volumes/jhipster/tssxxx/mysql/:/var/lib/mysql/
environment:
- MYSQL_USER=tss
- MYSQL_PASSWORD=tss
- MYSQL_DATABASE=tssxxx
- MYSQL_ROOT_PASSWORD=root
ports:
- 3306:3306
command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8mb4 --explicit_defaults_for_timestamp
networks:
default:
external:
name: my-overlay
my-overlay:
driver: overlay
docker stack deploy -c docker-compose.yaml xxx
docker stack ls
docker stack rm xxx
docker stack ps
下面是一個叢集管理服務,可以嘗試。
portainer:
image: 192.168.99.1:5000/portainer/portainer:latest
ports:
- "9000:9000"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
總結:
1.製作服務映象,如mysql,es,後端和前端的應用
2.docker在各主機上的安裝(本機使用最新的docker-ce 18.06),docker-compose單獨安裝
3.構建swarm叢集,通過docker swarm init /docker swarm join 搭建叢集
4.在manager角色的節點上建立overlay驅動的網絡卡
5.使用docker run -t --net 或docker service 或docker stack deploy來部署自己的服務