一、Docker-Swarm介绍
(一)简介
docker-swarm是用来在多机部署多容器的一个工具,当然目前主流的是使用k8s部署,但是这个还是可以了解一下,其和k8s还有很多相似之处。
我们日常在机器上运行docker命令其实就是使用Docker Cli和Docker Server进行交互,因此使用docker-swarm也是通过docker cli进行交互,也是通过命令。
docker-swarm既然是运行在多机环境下的,其对应的机器就会区分主从,在docker-swarm中叫做manager节点和worker节点,其中manger节点负责调度,健康检查等等,当然manager节点也运行对应的容器,集群工作模式如下图:
二、搭建Docker-Swarm集群
(一)环境准备
需要三台机器,每台机器最少1g1核,这是最低的要求,且三台机器能能够互相ping通,这就需要个人自己准备,我这边有三台机器,后缀分别是11,12,13。
如果实在没有机器又想搭建,可以登录一个免费的在线网站:http://labs.play-with-docker.com,该网站提供4个小时的免费试用时间。
(二)搭建docker-swarm集群
1、选择manager节点
manager既可以作为主节点调度又可以作为worker节点使用,从三台节点中随便选择一台作为manager节点,然后在该节点上运行如下命令:
docker swarm init --advertise-addr=192.168.0.11
观察日志,日志中会出现worker节点加入集群所需要的命令,例如我的机器日志中展示的命令如下:
docker swarm join --token SWMTKN-1-0a5ph4nehwdm9wzcmlbj2ckqqso38pkd238rprzwcoawabxtdq-arcpra6yzltedpafk3qyvv0y3 192.168.0.11:2377
2、worker节点加入集群
在另外2台机器上分别运行如下命令计入节点:
docker swarm join --token SWMTKN-1-0a5ph4nehwdm9wzcmlbj2ckqqso38pkd238rprzwcoawabxtdq-arcpra6yzltedpafk3qyvv0y3 192.168.0.11:2377
3、进入manager节点查看集群状态
docker node ls
至此docker-swarm集群搭建结束,是不是很简单。
4、节点类型转换
如果想将worker节点转换为manager节点,可以运行如下命令:
docker node promote worker01-node
docker node promote worker02-node
上面的worker01-node和worker02-node分别是12和13机器的别名,这样manager节点就是高可用的了,一旦11挂了,12,13就能顶上。
这里需要注意一点,运行docker node ls会看到12和13的状态并不是leader而Reachable,代表这2个节点是管理节点,一旦11挂了他们2个才会竞争其中一个成为leader。
如果想要节点降级,可以用以下命令:
docker node demote worker01-node
三、Docker-Swarm部署项目
例如我们要使用docker-swarm部署tomcat容器,我三台机器上都已经拉取了tomcat的镜像。
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
日志
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
u6o4mz4tj396 my-tomcat.1 tomcat:latest worker01-node Running Running 3 minutes ago
6、水平扩展service
docker service scale my-tomcat=3
docker service ls
docker service ps my-tomcat
日志
:可以发现,其他node上都运行了一个my-tomcat的service
[root@manager-node ~]# docker service ps my-tomcat
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
u6o4mz4tj396 my-tomcat.1 tomcat:latest worker01-node Running Running 8 minutes ago
v505wdu3fxqo my-tomcat.2 tomcat:latest manager-node Running Running 46 seconds ago
wpbsilp62sc0 my-tomcat.3 tomcat:latest worker02-node Running Running 49 seconds ago
此时到worker01-node上:docker ps,可以发现container的name和service名称不一样,这点要知道
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc4b9bb097b8 tomcat:latest "catalina.sh run" 10 minutes ago Up 10 minutes 8080/tcp my-tomcat.1.u6o4mz4tj3969a1p3mquagxok
7、如果某个node上的my-tomcat挂掉了,这时候会自动扩展
[worker01-node]
docker rm -f containerid
[manager-node]
docker service ls
docker service ps my-tomcat
8、删除service
docker service rm my-tomcat
四、多机网络通信
业务场景
:workpress+mysql实现个人博客搭建
(一) 传统手动方式实现
一台centos上,分别创建容器
01-创建mysql容器[创建完成等待一会,注意mysql的版本]
docker run -d --name mysql -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=examplepass -e MYSQL_DATABASE=db_wordpress mysql:5.6
02-创建wordpress容器[将wordpress的80端口映射到centos的8080端口]
docker run -d --name wordpress --link mysql -e WORDPRESS_DB_HOST=mysql:3306 -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=examplepass -e WORDPRESS_DB_NAME=db_wordpress -p 8080:80 wordpress
03-查看默认bridge的网络,可以发现两个容器都在其中
docker network inspect bridge
04-访问测试
win浏览器中输入:ip[centos]:8080,一直下一步
(二) 使用docker compose创建
docker-compose的方式还是在一台机器中,网络这块很清晰
01-创建wordpress-mysql文件夹
mkdir -p /tmp/wordpress-mysql
cd /tmp/wordpress-mysql
02-创建docker-compose.yml文件
文件内容
version: '3.1'
services:
wordpress:
image: wordpress
restart: always
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wordpress:/var/www/html
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
volumes:
wordpress:
db:
03-根据docker-compose.yml文件创建service
docker-compose up -d
04-访问测试
浏览器ip[centos]:8080,一直下一步
05-值得关注的点是网络
docker network ls
docker network inspect wordpress-mysql_default
(三)Swarm中实现
还是wordpress+mysql的案例,在docker swarm集群中怎么玩呢?
(1)创建一个overlay网络,用于docker swarm中多机通信
【manager-node】
docker network create -d overlay my-overlay-net
docker network ls[此时worker node查看不到]
(2)创建mysql的service
【manager-node】
01-创建service
docker service create --name mysql --mount type=volume,source=v1,destination=/var/lib/mysql --env MYSQL_ROOT_PASSWORD=examplepass --env MYSQL_DATABASE=db_wordpress --network my-overlay-net mysql:5.6
02-查看service
docker service ls
docker service ps mysql
(3)创建wordpress的service
01-创建service [注意之所以下面可以通过mysql名字访问,也是因为有DNS解析]
docker service create --name wordpress --env WORDPRESS_DB_USER=root --env WORDPRESS_DB_PASSWORD=examplepass --env WORDPRESS_DB_HOST=mysql:3306 --env WORDPRESS_DB_NAME=db_wordpress -p 8080:80 --network my-overlay-net wordpress
02-查看service
docker service ls
docker service ps mysql
03-此时mysql和wordpress的service运行在哪个node上,这时候就能看到my-overlay-net的网络
(4)测试
浏览器访问ip[manager/worker01/worker02]:8080都能访问成功
(5)查看my-overlay-net
docker network inspect my-overlay-net
(6)为什么没有用etcd?docker swarm中有自己的分布式存储机制
五、Routing Mesh
(一)Ingress
通过前面的案例我们发现,部署一个wordpress的service,映射到主机的8080端口,这时候通过swarm集群中的任意主机ip:8080都能成功访问,这是因为什么?
把问题简化
:docker service create --name tomcat -p 8080:8080 --network my-overlay-net tomcat
(1)记得使用一个自定义的overlay类型的网络
docker network create -d overlay my-overlay-net
(2)查看service情况
docker service ls
docker service ps tomcat
(3)访问3台机器的ip:8080测试
发现都能够访问到tomcat的欢迎页
(二)Internal
之前在实战wordpress+mysql的时候,发现wordpress中可以直接通过mysql名称访问
这样可以说明两点,第一是其中一定有dns解析,第二是两个service的ip是能够ping通的
思考
:不妨再创建一个service,也同样使用上述tomcat的overlay网络,然后来实验docker service create --name whoami -p 8000:8000 --network my-overlay-net -d jwilder/whoami
(1)查看whoami的情况
docker service ps whoami
(2)在各自容器中互相ping一下彼此,也就是容器间的通信
#tomcat容器中ping whoami
docker exec -it 9d7d4c2b1b80 ping whoami
64 bytes from bogon (10.0.0.8): icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from bogon (10.0.0.8): icmp_seq=2 ttl=64 time=0.080 ms
#whoami容器中ping tomcat
docker exec -it 5c4fe39e7f60 ping tomcat
64 bytes from bogon (10.0.0.18): icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from bogon (10.0.0.18): icmp_seq=2 ttl=64 time=0.080 ms
(3)将whoami进行扩容
docker service scale whoami=3
docker service ps whoami #manager,worker01,worker02
(4)此时再ping whoami service,并且访问whoami服务
#ping
docker exec -it 9d7d4c2b1b80 ping whoami
64 bytes from bogon (10.0.0.8): icmp_seq=1 ttl=64 time=0.055 ms
64 bytes from bogon (10.0.0.8): icmp_seq=2 ttl=64 time=0.084 ms
#访问
docker exec -it 9d7d4c2b1b80 curl whoami:8000 [多访问几次]
I'm 09f4158c81ae
I'm aebc574dc990
I'm 7755bc7da921
小结
:通过上述的实验可以发现什么?whoami服务对其他服务暴露的ip是不变的,但是通过whoami名称访问8000端口,确实访问到的是不同的service,就说明访问其实是像下面这张图。
也就是说whoami service对其他服务提供了一个统一的VIP入口,别的服务访问时会做负载均衡。
六、Stack
docker stack deploy:https://docs.docker.com/engine/reference/commandline/stack_deploy/
compose-file:https://docs.docker.com/compose/compose-file/
有没有发现上述部署service很麻烦?要是能够类似于docker-compose.yml文件那种方式一起管理该多少?这就要涉及到docker swarm中的Stack,我们直接通过前面的wordpress+mysql案例看看怎么使用咯。
(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)常见操作
01-查看stack具体信息
docker stack ls
NAME SERVICES ORCHESTRATOR
my-service 2 Swarm
02-查看具体的service
docker stack services my-service
ID NAME MODE REPLICAS IMAGE PORTS
icraimlesu61 my-service_db global 1/1 mysql:5.7
iud2g140za5c my-service_wordpress replicated 3/3 wordpress:latest *:8080->80/tcp
03-查看某个service
docker service inspect my-service-db
"Endpoint": {
"Spec": {
"Mode": "vip"
},
"VirtualIPs": [
{
"NetworkID": "kz1reu3yxxpwp1lvnrraw0uq6",
"Addr": "10.0.1.5/24"
}
]
}
(4)访问测试
浏览器ip[manager,worker01,worker02]:8080