- 前言
- docker1.12版本之前版本配置
- 准备工作
- 开始
- 拉取swarm
- 开放2375远程访问端口
- 创建集群的token
- 向集群里添加结点
- 查看集群里有哪些结点
- 创建管理者容器
- 使用集群
- 离开集群
- docker1.12版本之后版本配置
- 准备工作
- 开始
- 集群初始化,在云1上执行。
- 查看结点
- 测试
- 查看创建的服务:
- 查看端口情况
- 查看哪个节点在运行该服务
- 滚动更新
- 命令
- 集群
- 结点
- 服务
- 问题
- Error response from daemon: node izuf6fob4dmcif0myqzjt1z is ambiguous (2 matches found)
前言
自行百度
docker1.12版本之前版本配置
准备工作
云1:116.62.184.190(杭州)
云2:139.196.123.97(上海)
2台阿里云不在同一地区
开始
按阿里云CentOS环境之docker安装,启动,加速器,docker-compose(十四)方式先安装docker
容器
拉取swarm
docker pull swarm
开放2375远程访问端口
不知道怎么修改看Docker学习笔记 — 开启Docker远程访问
如果这里不使用2375端口,比较修改为9000,那下面的命令要做端口映射。
创建集群的token
命令
docker run --rm swarm create
结果得到268a013b7515edfb3c7b3fa361e69661
token是集群标志,用于区别不同集群。同时也是找到集群的令牌,需要单独保存,目前没法重写。
向集群里添加结点
上面创建的是空集群,需要把将结点主机
添加到集群里。swarm join命令将结点主机添加到集群,但要注意并不会去验证主机的健康性。
在云1服务器上执行
命令
docker run -d swarm join --addr=116.62.184.190:2375 token://268a013b7515edfb3c7b3fa361e69661
116.62.184.190是云1公网地址即docker主机ip,2375是开放端口,-d表示后台运行,token即上面集群标识。
命令意思是将116.62.184.190:2375docker主机添加到集群里。
如果本机没开放2375,修改成9000,则命令变成 –addr=116.62.184.190:9000
同样在云2上执行添加集群命令:
docker run -d swarm join --addr=139.196.123.97:2375 token://268a013b7515edfb3c7b3fa361e69661
查看集群里有哪些结点
命令
docker run --rm swarm list token://268a013b7515edfb3c7b3fa361e69661
结果如下:
[root@izbp1hx8v6lzadot5plxh2z sysconfig]# docker run --rm swarm list token://268a013b7515edfb3c7b3fa361e69661
116.62.184.190:2375
139.196.123.97:2375
说明2台docker主机都成功添加到集群。
创建管理者容器
管理主机是对集群的管理,它管理集群下每台主机。在任何一台能上网的机器上通过连接管理者都能控制集群。
同时创建管理都容器可以在任意一台机器上创建,最好单独的稳定的云服务器上。这里在云1上创建管理者容器。
命令:
docker run -d -p 8280:2375 swarm manage token://268a013b7515edfb3c7b3fa361e69661
由于2375
被使用过,这里使用-p(小p)
参数端口映射到云主机的8280端口。
阿里云安全组8280端口要开放
成功创建管理者容器就可以用下面命令查看集群里容器信息
//集群信息
docker -H 116.62.184.190:8280 info
//集群里容器运行信息,类似单个docker主机上执行docker ps查看主机上运行的容器,区别是它管理的集群里所有的。
docker -H 116.62.184.190:8280 ps
//查看集群镜像
docker -H 116.62.184.190:8280 images
上面也说过,在任意一台机器上执行上面命令都可以管理集群。其中docker -H 116.62.184.190:8280 ps命令,现在执行是没有任何信息的,因为集群里没有任意运行的
事实上-H参数表示连接的集群地址,只要加上-H参数,就可以使用docker其它命令,比较kill,stop,rm,rmi等
使用集群
向集群里运行一个镜像,此命令在任何云服务器都可执行(当然要有docker环境)
docker -H 116.62.184.190:8280 run -d -p 8284:80 --name web1 nginx
116.62.184.190:8280是安装管理者容器的ip。运行nginx镜像,访问http://116.62.184.190:8284/
结果如下图:
那么通过这样的方式启动起来的容器会通过一定的策略选择一台合适的主机作为真实的跑容器的平台来运行容器
离开集群
docker swarm leave
如果是管理者,需要加--force
,帮助 信息
docker swarm leave --help
docker1.12版本之后版本配置
准备工作
云1:116.62.184.190(杭州)
云2:139.196.123.97(上海)
2台阿里云不在同一地区
开始
集群初始化,在云1上执行。
docker swarm init --listen-addr 127.0.0.1:8280 --advertise-addr 127.0.0.1
初始化集群,–listen-addr指定开放的远程调用APi对应的IP和端口,可以通过这个组合访问到该节点的docker服务,默认端口2377,默认ip是局域网ip,–advertise-addr指定本机ip地址,广播地址,也就是其他节点加入该swarm集群时,需要访问的IP,我建议不填。
建议命令
docker swarm init
得到结果:
[root@izbp1hx8v6lzadot5plxh2z sysconfig]# docker swarm init
Swarm initialized: current node (7o5bvjqtpnjjt2afajvf4aa3q) is now a manager.To add a worker to this swarm, run the following command:docker swarm join \--token SWMTKN-1-5pws5xth4op6w6ew2axlqk8j3lmakjg2z6mopc8k9zcqnabn24-88d8vu4qsa7ua6r5jj36eetg3 \172.16.78.165:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
初始化完成,添加结点。注意命令中docker swarm join --token SWMTKN-1-5pws5xth4op6w6ew2axlqk8j3lmakjg2z6mopc8k9zcqnabn24-88d8vu4qsa7ua6r5jj36eetg3 172.16.78.165:2377
,如果在公网上执行,172.16.78.165要换成公网ip。
在云2上执行添加结点命令:
docker swarm join --token SWMTKN-1-5pws5xth4op6w6ew2axlqk8j3lmakjg2z6mopc8k9zcqnabn24-88d8vu4qsa7ua6r5jj36eetg3 116.62.184.190:2377
查看结点
docker node ls
结果如下:
[root@izbp1hx8v6lzadot5plxh2z sysconfig]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
7o5bvjqtpnjjt2afajvf4aa3q * izbp1hx8v6lzadot5plxh2z Ready Active Leader
l2jxinvqnwm2kduf1g9r16exa izuf6fob4dmcif0myqzjt1z Ready Active
- 节点id后的星号据说表示的是你当前连接着的节点
- manager本身自动作为worker一员加入集群
测试
在结点上创建服务
docker service create --replicas 2 --mode replicated --name test -p 8284:80 nginx
--replicas
:参数指出希望保持这个服务始终有多少容器在运行。为2则云1和云2docker主机上都会运行一个nginx容器
--name
:参数指定的是服务的名字。
--mode
:replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
global services 每个工作节点上运行一个任务
默认是replicated,建议不填
--network
:在集群上部署应用,就是在共享网络上部署服务(service),通过docker network ls
可查看集群节点中的共享网络,默认的ingress共享网络。建议不填。
前面的docker service create --replicas 2 --name test
基本固定,后面跟着运行容器需要的参数。
查看创建的服务:
docker service ls
结果
[root@izbp1hx8v6lzadot5plxh2z sysconfig]# docker service ls
ID NAME MODE REPLICAS IMAGE
055ndsl7afu6 test replicated 2/2 nginx:latest
访问http://116.62.184.190:8284/
能正常访问页面
查看端口情况
命令
docker service inspect --pretty test
结果如下:
注意不是使用docker ps
,使用docker ps
命令不能查出暴露的主机端口,展示的结果如下:
[root@izbp1hx8v6lzadot5plxh2z target]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eeafd18ed680 nginx@sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884 "nginx -g 'daemon ..." About a minute ago Up About a minute 80/tcp test.2.poz7jx7bjg6ksgb7dv3777vm9
查看哪个节点在运行该服务
docker service ps test
结果如下:
6lmh2yw8q7qx test replicated 2/2 nginx:latest
[root@izbp1hx8v6lzadot5plxh2z sysconfig]# docker service ps test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
780g50xskm5a test.1 nginx:latest izbp1hx8v6lzadot5plxh2z Running Running 15 minutes ago
iju0bqiqmpqa test.2 nginx:latest izuf6fob4dmcif0myqzjt1z Running Running 15 minutes ago
发现云2主机上也有一个nginx容器在运行,试试http://139.196.123.97:8284/
果然有访问。
证明集群起作用了。创建一个服务,指定运行2个容器,集群根据算法在云1和云2上都运行一个ngingx
容器,每个服务下有多个服务结点。
滚动更新
我这里想说的是主要目的就是为了在部署时服务不至于不可用。当镜像提交到镜像仓库里时需要更新服务上应用,一个容器更新完成后再更新另一个容器。
原理:
1. 停止第一个副本。
2. 调度任务,选择 worker node。
3. 在 worker 上用新的镜像启动副本。
4. 如果副本(容器)运行成功,继续更新下一个副本;如果失败,暂停整个更新过程。
2步。
1. 创建服务时指定更新策略
docker service create --replicas 2 --name test --update-delay 10s -p 8284:80 nginx
–update-delay 表示更新服务对应的任务或一组任务之间的时间间隔。时间间隔用数字和时间单位表示,m 表示分,h 表示时。
2. 执行更新命令
docker service update --image 镜像名 服务名
如果镜像内部没变化,更新操作是不会有任何影响的,强制更新
docker service update --force --image 镜像名 服务名
更新操作根据仓库里TAG
标签来更新,如果TAG
没更新,但仓库里IMAGE ID
变了,也是不会更新操作了的。
上面操作是创建时操作,如果服务已经创建好了,我们可以在update命令上下功夫。
如下:
docker service update --update-delay 10s --image 镜像名 服务名
一些其它操作。
--replicas
:扩展副本数量为6,相当于docker service scale test=6
--update-parallelism
:同时更新的副本数量
--update-delay
:更新间隔
例如
docker service update --replicas 6 --update-parallelism 2 --update-delay 1m30s --image 镜像名 服务名
service 增加到六个副本,每次更新两个副本,间隔时间一分半钟。
命令
下面的test是服务名。
集群
初始化一个集群:docker swarm init
强制删除集群,如果是manager,需要加–force:docker swarm leave --force
查看添加到worker的token:docker swarm join-token worker
查看添加到manager的token:docker swarm join-token manager
使旧令牌无效并生成新令牌:docker swarm join-token --rotate
加入worker/manager:docker swarm join --token SWMTKN-1-5d2ipwo8jqdsiesv6ixze20w2toclys76gyu4zdoiaf038voxj-8sbxe79rx5qt14ol14gxxa3wf 公网ip:2377
将节点升级为manager:docker node promote 结点名
将节点降级为worker:docker node demote 结点名
结点
查看结点列表:docker node ls
删除结点:docker node rm 结点名
查看结点信息:docker node inspect 结点名 --pretty
下线某结点上任务(容器):docker node update --availability drain 结点HOSTNAME名
(通过docker node ls)。结点下容器运行状态变成Shutdown
,结点状态为Drain
,同时在其它结点上创建被关闭数量任务副本(如果创建服务时–replicas 指定的容器数量超过1的话)
上线某结点状态:docker node update --availability active 结点HOSTNAME名
暂停某结点,不影响现有任务运行,但不会分配任务:docker node update --availability pause 结点HOSTNAME名
服务
查看服务列表:docker service ls
查看单个服务详情:docker service inspect --pretty test
查看服务下容器具体信息:docker service ps test
伸缩服务结点:docker service scale test=5
删除服务:docker service rm test
,服务删除,所有结点也跟着删除
问题
Error response from daemon: node izuf6fob4dmcif0myqzjt1z is ambiguous (2 matches found)
是因为有2个hostname一样但id不一样的结点,可能是一个结点离开集群又重新加入导致同名不同id,在执行命令时不知道激活哪个结点,这种情况就不用hostname,换成id即可。
比如:
docker node update --availability active l2jxinvqnwm2kduf1g9r16exa(ID)
同时删除同名的另一个结点
docker node rm mgdob3pudnbtf5d1zpmwx9gmz
参考
Docker swarm 模式初体验
docker swarm 学习命令整理