本节将测试通过 docker-machine 创建 Docker Swarm 集群,并部署 Traefik
环境介绍
- 宿主机: MacOS 10.14.6
- VirtualBox: 5.2.18 r124319 (Qt5.6.3)
- docker-machine: 0.16.1, build cce350d7
- boot2docker: v19.03.2-rc1
- Docker: 18.09.6, build 481bc77
- traefik: v1.7.14
通过 docker-machine 创建 3 台服务器
主机名 | IP | Swarm 集群角色 | 备注 |
---|---|---|---|
manager | 192.168.99.100 | manager | - |
worker1 | 192.168.99.101 | worker1 | - |
worker2 | 192.168.99.102 | worker2 | - |
前期准备
- 需安装 docker-machine
- 需安装 VirtualBox
为加快 docker-machine 创建 vm 速度,建议:
- 手动下载 boot2docker.iso
- 放到 ~/.docker/machine/cache/boot2docker.iso 目录
- 创建 alias
sudo bash -c 'cat >>~/.profile <<EOF
alias docker-machinec='docker-machine create -d virtualbox --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso'
EOF
source ~/.profile
一、具体操作
1.1 创建并初始化 Docker Swarm 集群
# create docker-machine manager,work1,work2
$ for host in manager worker1 worker2; do docker-machinec $host; done
# init cluster
##manager
$ docker-machine ssh manager "docker swarm init \
--listen-addr $(docker-machine ip manager) \
--advertise-addr $(docker-machine ip manager)"
$ export worker_token=$(docker-machine ssh manager "docker swarm join-token worker -q")
##worker1
$ docker-machine ssh worker1 "docker swarm join \
--token=${worker_token} \
--listen-addr $(docker-machine ip worker1) \
--advertise-addr $(docker-machine ip worker1) \
$(docker-machine ip manager)"
##worker2
$ docker-machine ssh worker2 "docker swarm join \
--token=${worker_token} \
--listen-addr $(docker-machine ip worker2) \
--advertise-addr $(docker-machine ip worker2) \
$(docker-machine ip manager)"
##check
$ docker-machine ssh manager docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
tnc7tqgwjp5eqba0i1zji0mnj * manager Ready Active Leader 18.09.6
lwvomgs80i85zzkh4ptwewpij worker1 Ready Active 18.09.6
w2cgm0zib6dxs9d6mn07ladsf worker2 Ready Active 18.09.6
1.2 部署 Traefik
#创建 traefik 使用的网络
docker-machine ssh manager "docker network create --driver=overlay traefik-net"
# manager 节点部署 traefik 服务
$ docker-machine ssh manager "docker service create \
--name traefik \
--constraint=node.role==manager \
--publish 80:80 --publish 8080:8080 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--network traefik-net \
traefik \
--docker \
--docker.swarmMode \
--docker.domain=traefik \
--docker.watch \
--api"v
启动参数说明:
选项 | 说明 |
---|---|
–publish 80:80 –publish 8080:8080 | 80 端口为集群监听端口,8080 为 webUI 访问端口 |
–constraint=node.role==manager | 指定在集群 manager 角色节点部署 |
–mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock | 监听 Docker socket API 事件(容器创建、删除等) |
–network traefik-net | 指定容器使用的网络名称 |
–docker | 指定为 docker 引擎 |
–api | 开启 WebUI 访问 |
1.3 部署应用
#app1
$ docker-machine ssh manager "docker service create \
--name whoami0 \
--label traefik.port=80 \
--network traefik-net \
containous/whoami"
#app2
$ docker-machine ssh manager "docker service create \
--name whoami1 \
--label traefik.port=80 \
--network traefik-net \
--label traefik.backend.loadbalancer.sticky=true \
containous/whoami"
#检查服务
$ docker-machine ssh manager "docker service ls"
ID NAME MODE REPLICAS IMAGE PORTS
moq3dq4xqv6t traefik replicated 1/1 traefik:latest *:80->80/tcp,*:8080->8080/tcp
ysil6oto1wim whoami0 replicated 1/1 containous/whoami:latest
z9re2mnl34k4 whoami1 replicated 1/1 containous/whoami:latest
说明:通过
--label traefik.backend.loadbalancer.sticky=true
实现会话保持。
1.4. 通过 Traefik 访问应用
#app1: whoami0
$ curl -H Host:whoami0.traefik http://$(docker-machine ip manager)
Hostname: dfa25599e253
IP: 127.0.0.1
IP: 10.0.0.13
IP: 172.18.0.4
GET / HTTP/1.1
Host: whoami0.traefik
User-Agent: curl/7.54.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.255.0.2
X-Forwarded-Host: whoami0.traefik
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 7403d79c27d0
X-Real-Ip: 10.255.0.2
#app2: whoami1
$ curl -H Host:whoami1.traefik http://$(docker-machine ip manager)
Hostname: 44e396b2b959
IP: 127.0.0.1
IP: 10.0.0.17
IP: 172.18.0.5
GET / HTTP/1.1
Host: whoami1.traefik
User-Agent: curl/7.54.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.255.0.2
X-Forwarded-Host: whoami1.traefik
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 7403d79c27d0
X-Real-Ip: 10.255.0.2
如果是 Swarm 模式,访问集群任意节点都可得到相同结果
#cluster worker1
$ curl -H Host:whoami0.traefik http://$(docker-machine ip worker1)
Hostname: f1ecf18a1bd2
IP: 127.0.0.1
IP: 10.0.0.14
IP: 172.18.0.4
GET / HTTP/1.1
Host: whoami0.traefik
User-Agent: curl/7.54.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.255.0.3
X-Forwarded-Host: whoami0.traefik
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 7403d79c27d0
X-Real-Ip: 10.255.0.3
#cluster worker2
$ curl -H Host:whoami1.traefik http://$(docker-machine ip worker2)
Hostname: a7f079a2ec71
IP: 127.0.0.1
IP: 10.0.0.18
IP: 172.18.0.6
GET / HTTP/1.1
Host: whoami1.traefik
User-Agent: curl/7.54.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.255.0.4
X-Forwarded-Host: whoami1.traefik
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 7403d79c27d0
X-Real-Ip: 10.255.0.4
1.5 伸缩服务
$ docker-machine ssh manager "docker service scale whoami0=5"
$ docker-machine ssh manager "docker service scale whoami1=5"
#check
$ docker-machine ssh manager "docker service ls"
ID NAME MODE REPLICAS IMAGE PORTS
k36uevddcmkc traefik replicated 1/1 traefik:latest *:80->80/tcp, *:8080->8080/tcp
tjby5a5gfrti whoami0 replicated 5/5 containous/whoami:latest
246bcqk4imw1 whoami1 replicated 5/5 containous/whoami:latest
1.6 测试会话保持
因 whoami0 未设置会话保持,故每次访问返回容器节点 IP 不同
$ for n in `seq 5`
do
echo "$n >>>"
curl -c cookies.txt -sH Host:whoami0.traefik http://$(docker-machine ip manager) |grep -m 2 'IP'
done
#输出结果(第二行IP)
1 >>>
IP: 127.0.0.1
IP: 10.0.0.11
2 >>>
IP: 127.0.0.1
IP: 10.0.0.12
3 >>>
IP: 127.0.0.1
IP: 10.0.0.6
4 >>>
IP: 127.0.0.1
IP: 10.0.0.13
5 >>>
IP: 127.0.0.1
IP: 10.0.0.14
因 whoami1 已设置会话保持,故每次访问返回容器节点 IP 相同(会话保持)
#第一次访问,设置 cookie
$ curl -c cookies.txt -sH Host:whoami1.traefik http://$(docker-machine ip manager) |grep -m 2 'IP';
# 第二次访问
## 如果访问时指定 cookie 文件,则讲访问同一台服务器(容器)
$ for n in `seq 5`
do
echo "$n >>>"
curl -b cookies.txt -sH Host:whoami1.traefik http://$(docker-machine ip manager) |grep -m 2 'IP';
done
#输出结果
1 >>>
IP: 127.0.0.1
IP: 10.0.0.18
2 >>>
IP: 127.0.0.1
IP: 10.0.0.18
3 >>>
IP: 127.0.0.1
IP: 10.0.0.18
4 >>>
IP: 127.0.0.1
IP: 10.0.0.18
5 >>>
IP: 127.0.0.1
IP: 10.0.0.18
二、懒人版
在初始化 docker-machine 集群后,其中 1.2,1.3 步骤可通过 Docker-compse 编排文件部署 Traefik 及 app 服务 直接替代
2.1 manager 节点操作
docker-compose 单机模式
#登录manager,并安装 docker-compose 工具
$ docker-machine ssh manager
$ sudo curl -o /usr/local/bin/docker-compose https://mirrors.aliyun.com/docker-toolbox/linux/compose/1.21.2/docker-compose-Linux-x86_64 && \
sudo chmod +x /usr/local/bin/docker-compose && \
docker-compose -v
#生成编排文件
$ echo '
version: "3"
services:
reverse-proxy:
image: traefik
restart: always
command: --api --docker
networks:
- traefik-net
ports:
- "80:80"
- "8080:8080"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
deploy:
mode: global
placement:
constraints:
- node.role == manager
whoami0:
image: containous/whoami
restart: always
networks:
- traefik-net
labels:
- "traefik.backend=whoami0"
- "traefik.frontend.rule=Host:whoami0.traefik"
whoami1:
image: containous/whoami
restart: always
networks:
- traefik-net
labels:
- "traefik.backend=whoami1"
- "traefik.backend.loadbalancer.sticky=true"
- "traefik.frontend.rule=Host:whoami1.traefik"
networks:
traefik-net:
driver: overlay
' > docker-compose.yml
#语法检查
$ docker-compose config
#运行
$ docker-compose up -d
#检查
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5451484ec7f9 traefik "/traefik --api --do…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:8080->8080/tcp docker_reverse-proxy_1
3f782ace7aaf containous/whoami "/whoami" About a minute ago Up About a minute 80/tcp docker_whoami1_1
30e1b5c721b4 containous/whoami "/whoami" About a minute ago Up About a minute 80/tcp
后面测试参考 1.4 及以后步骤
docker swarm 集群模式
待补充。。。