目录
官网:https://docs.docker.com/swarm/overview/
Docker Swarm is native clustering for Docker. It turns a pool of Docker hosts into a single, virtual Docker host.
Swarm 是 Docker 官方提供的集群管理工具,其主要作用是把若干台 Docker 主机抽象为一个整体,并且通过一个入口统一管理这些 Docker 主机上的各种 Docker 资源。
一个 Swarm由一个或多个可以互相通信的Docker 节点组成.
节点会被分为两类,Manager节点和Worker节点。
Manager负责控制集群,监控集群状态、分发任务至worker节点等操作;Worker节点则接收来自Master节点的任务并在其上执行
相当于Manager是包工头,Worker是底层实际干活的工人。
搭建Swarm环境
这里使用的docker在线环境 https://labs.play-with-docker.com/
(1)准备3台centos7机器
192.168.0.31 (Manager)
192.168.0.32 (Worker01)
192.168.0.33 (Worker02)
(2)初始化Manager节点
docker swarm init --advertise-addr=192.168.0.31
(3)将worker节点加入到集群里
docker swarm join --token SWMTKN-1-5rxv93eb0hg3mzxze2lukaye7rkqm5uvlyk30n2lk9h2z36j2t-650nf075oarceftbefx6palr2 192.168.0.31:2377
查看集群状态
(4)node类型的转换
#可以将worker提升成Manager节点,从而保证swarm的高可用
docker node promote node2
docker node promote node1
#降级可以用demote
docker node demote node2
swarm基本操作
Service是自 Docker 1.12 后新引入的概念,仅适用于 docker swarm
Service配置的属性和docker的容器属性基本一致,比如容器名、端口映射、network和image. Servcie可以简单理解为一组相同的容器副本
(1)创建一个tomcat的service
docker service create --name my-tomcat tomcat
(2)查看当前swarm的service
docker service ls
(3)查看service的启动日志
docker service logs my-tomcat
(4)查看service的详情
docker service inspect my-tomcat
(5)查看my-tomcat运行在哪个node上
docker service ps my-tomcat
(6)水平扩展service
docker service scale my-tomcat=3
docker service ls
docker service ps my-tomcat
(7)如果停掉一个node的container,service会自动帮我们维护容器副本,创建一个新的容器
(8)删除service
docker service rm my-tomcat
swarm实战
单机docker中使用bridge网络进行连接通信,多机中使用的是overlay网络
1)在manager节点创建一个overlay网络,用于docker swarm中多机通信
docker network create -d overlay my-overlay-net
docker network ls
(2)创建mysql和wordpress的service(Manager node)
docker service create --name mysql --mount type=volume,source=v1,destination=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=examplepass -e MYSQL_DATABASE=db_wordpress --network my-overlay-net mysql:5.6
docker service create --name wordpress -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=examplepass -e WORDPRESS_DB_HOST=mysql:3306 -e WORDPRESS_DB_NAME=db_wordpress -p 8080:80 --network my-overlay-net wordpress
运行成功
通过各个node的ip:8080都能访问成功(这里我通过play-with-docker open port访问8080端口)
这里的wordpress连接mysql是通过服务名mysql来连接的,说明其中一定有dns解析,会根据serviceName查找到对应的ip,进行连接,这样在部署(扩容)的时候就无需关心容器的ip怎么变化
For most situations, you should connect to the service name, which is load-balanced and handled by all containers (“tasks”) backing the service .
docker swarm服务发布模式
Docker Swarm 支持两种服务发布模式:Ingress模式(默认),Host模式。
通过 Ingress 模式发布的服务,可以保证从 Swarm 集群内任一节点(即使没有运行服务的节点)都能访问该服务;以 Host 模式发布的服务只能通过运行服务副本的节点来访问。下图展示了两种模式的区别。
想要进一步了解ingress和服务发现的底层可以阅读以下文章:
https://www.jianshu.com/p/c83a9173459f
https://www.cnblogs.com/zonehoo/p/11401930.html
(1)单机部署一个tomcat service,各个集群node都可以访问到
[node3] (local) [email protected] ~
$ docker service create --name tomcat -p 8080:8080 --network my-overlay-net tomcat
fywyxuvpbpurt3ha0pkq4wwyu
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
[node3] (local) [email protected] ~
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
fywyxuvpbpur tomcat replicated 1/1 tomcat:latest *:8080->8080/tcp
$ docker service ps tomcat
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
8pjqve65ebww tomcat.1 tomcat:latest node1 Running Running 40 seconds ago
#该tomcat容器实际部署再node1上,container为4fa7
[node1] (local) [email protected] ~
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4fa7f6681778 tomcat:latest "catalina.sh run" 5 minutes ago Up 5 minutes 8080/tcp tomcat.1.8pjqve65ebwwi3adp53eb3xbg
其他node节点都能通过访问本地的8080端口访问到该tomcat
(2)部署多副本的whoami service,可以通过serviceName进行负载均衡
[node3] (local) [email protected] ~
$ docker service create --name whoami -p 8000:8000 --network my-overlay-net -d jwilder/whoami
k1d6tus51sirz9xd4elgz2xvm
[node3] (local) [email protected] ~
$ docker service ps whoami
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
8kaudc0xvpdm whoami.1 jwilder/whoami:latest node3 Running Running 10 seconds ago
[node3] (local) [email protected] ~
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb723685302a jwilder/whoami:latest "/app/http" 48 seconds ago Up 47 seconds 8000/tcp whoami.1.8kaudc0xvpdmax2k12nf7h6m5
#不同节点上的tomcat,whomi服务,可以容器内通过serviceName ping通
[node3] (local) [email protected] ~
$ docker exec -it cb72368 ping tomcat
PING tomcat (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.117 ms
64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.093 ms
64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.097 ms
$ docker exec -it 4fa7 ping whoami
PING whoami (10.0.0.5) 56(84) bytes of data.
64 bytes from 10.0.0.5 (10.0.0.5): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from 10.0.0.5 (10.0.0.5): icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from 10.0.0.5 (10.0.0.5): icmp_seq=3 ttl=64 time=0.061 ms
#扩容成3个副本,通过whoami:8000访问,返回不同的hostid
[node3] (local) [email protected] ~
$ docker service scale whoami=3
whoami scaled to 3
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
[node3] (local) [email protected] ~
$ docker service ps whoami
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
8kaudc0xvpdm whoami.1 jwilder/whoami:latest node3 Running Running 3 minutes ago
4jv21432xgqo whoami.2 jwilder/whoami:latest node2 Running Running 8 seconds ago
svg62zqee2g1 whoami.3 jwilder/whoami:latest node1 Running Running 8 seconds ago
[node1] (local) [email protected] ~
$ docker exec -it 4fa7 curl whoami:8000
I'm bca5e1a05a00
[node1] (local) [email protected] ~
$ docker exec -it 4fa7 curl whoami:8000
I'm 6f25815a733c
[node1] (local) [email protected] ~
$ docker exec -it 4fa7 curl whoami:8000
I'm cb723685302a
[node1] (local) [email protected] ~
$ docker exec -it 4fa7 curl whoami:8000
I'm bca5e1a05a00
service对其他服务提供了一个统一的VIP入口,接收其他服务访问时会做负载均衡。
最好再画一张图。
docker stack
在docker中有docker-compose帮助简化部署操作,docker swarm中也可以使用docker stack来进行部署管理servcie
具体的定义方式跟compose差不多,这里就不一一解释了
(1)新建service.yml文件
version: '3'
services:
wordpress:
image: wordpress
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
networks:
- ol-net
volumes:
- wordpress:/var/www/html
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
networks:
- ol-net
deploy:
mode: global
placement:
constraints:
- node.role == manager
volumes:
wordpress:
db:
networks:
ol-net:
driver: overlay
(2)根据service.yml创建service
docker statck deploy -c service.yml my-service
(3)常见操作
查看stack具体信息
docker stack ls
查看具体的service
docker stack services my-service
成功访问