docker实战2 (docker swarm的应用,docker集群的构建,在docker集群中部署服务的创建与更新)
2017-06-01 22:34
1201 查看
前言:
在之前曾写过一个关于docker集群创建的教程,但是不够深入,只是停留到集群的初始化和节点加入上,这次具体到服务,并详细讲解其中的原理。而且总结了很多自己做的过程中所踩过的很多坑(比如镜像的digest问题)。在查阅资料的过程还了解到了谷歌的kubernetes和swarm是一个类似的东西,准备在之后开一篇入门的坑,毕竟谷歌的东西还是很有意思的。
集群拓扑:
Linux版本:Red Hat Enterprise Linux Server release 7.3 (Maipo
docker版本:
Client: Version: 17.03.0-ce API version: 1.26 Go version: go1.7.5 Git commit: 3a232c8 Built: Tue Feb 28 08:10:07 2017 OS/Arch: linux/amd64 Server: Version: 17.03.0-ce API version: 1.26 (minimum version 1.12) Go version: go1.7.5 Git commit: 3a232c8 Built: Tue Feb 28 08:10:07 2017 OS/Arch: linux/amd64 Experimental: false
一.创建docker swarm集群
官方文档中对应的部分:docker swarm官方这一部是关于docker这个服务的集群,并不是我们容器所涉及服务的集群
docker swarm init --advertise-addr 172.25.3.250
只用这条命令就可以创建以172.25.3.250为manager的docker集群,–advertise-addr不是必须的,但是当你的计算机上有多个网卡时候就要指定了。
docker swarm join --token ***** ip:2377
别的机器想要加入这个docker集群使用上面的命令就可以了。
[root@foundation3 ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-4jlxqqc9jg39a7ll5npktriayhnk040vuunhcwj2h6ntvcy3j0-3x6za4vgrabq5ydivyxvd6kma \ 172.25.3.250:2377 [root@foundation3 ~]# docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-4jlxqqc9jg39a7ll5npktriayhnk040vuunhcwj2h6ntvcy3j0-602yfdl0qc5zmhcvo1etytu7y \ 172.25.3.250:2377
根据token的不同,我们来区分加入集群的是manager节点还是普通的系节点。
[root@foundation3 ~]# docker swarm join-token manager --quiet SWMTKN-1-4jlxqqc9jg39a7ll5npktriayhnk040vuunhcwj2h6ntvcy3j0-602yfdl0qc5zmhcvo1etytu7y
通过加入–quiet参数可以只输出token,在需要保存token的时候还是十分有用的。
二.在docker集群中部署服务
1.部署服务前注意
按照本教程做的小伙伴,建议每台机器都可以连接外网,可以从docker镜像仓库下载镜像。原因在稍后解释。讲到下载镜像,可能很多兄弟要说下载镜像速度太慢了从Docker Hub上,这里我推荐一个国内的镜像加速器非常好用DaoCloud – 企业级云计算领域的创新领导者。
注册账号后进入自己的用户界面,在右上角点击我上图画圈处,进入加速器界面。
直接输入这个所指示的命令即可配置加速器。如果使用他指示的命令配置失败的也可以手动配置
[root@foundation3 docker]# pwd /etc/docker [root@foundation3 docker]# ls daemon.json key.json test1.tar test2.tar [root@foundation3 docker]#
编写daemon.json文件(下面的*替换成你的私有镜像地址)
"registry-mirrors":["http://**********"]
现在就可以畅快的pull镜像了,我们本次需要的镜像是Nginx的镜像。
[root@foundation3 docker]# docker search nginx NAME DESCRIPTION STARS OFFICIAL AUTOMATED nginx Official build of Nginx. 6085 [OK] jwilder/nginx-proxy Automated Nginx reverse proxy for docker c... 1038 [OK] richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable ... 381 [OK] jrcs/letsencrypt-nginx-proxy-companion LetsEncrypt container to use with nginx as... 182 [OK] webdevops/php-nginx Nginx with PHP-FPM 78 [OK] million12/nginx-php Nginx + PHP-FPM 5.5, 5.6, 7.0 (NG), CentOS... 77 [OK]
通过这里我们可以看到很多nginx的镜像,根据stars数量我们可以选择最可靠的镜像,在这里我们要强调一个事情,就是docker 的tag。我们建议我们使用的每个镜像都要带上tag,比如我列出我的几个Nginx镜像
[root@foundation3 docker]# docker images | grep nginx nginx 1.12 17daebd00e2c 2 weeks ago 109 MB nginx 1.13 3448f27c273f 2 weeks ago 109 MB
这些tag并不是默认的latest,因为这个默认的tag会造成很多困扰,因为很多时候那个带latest的镜像并不一定是”latest”,这会很让人困扰。那么既然我们使用镜像要带tag但是根据上search出的官方docker镜像信息并没有tag信息,怎么办呢,我建议大家在查找需要下载的镜像时去镜像的官网查看下,但是DockerHub官网访问速度太慢,这时还是用我们国内的这个docker镜像源。
通过这里提供的接口我们可以看到Docker Hub的镜像信息
进入nginx的详情页后我们就可以看到具体的tag了。比如我们想下载1.12.0版本的nginx镜像可以使用的tag就有 stable,1.12等
docker pull nginx:1.12
现在都配置好后,我们在manager,node1,node2上将nginx:1.12和nginx:1.13镜像均pull下来。如果你只是在manager上pull下来会导致部署服务失败。
2.部署单节点服务
[root@foundation3 docker]# docker service create --name web_t nginx:1.12
这条命令让我们在manager节点上部署了一个Nginx容器。
[root@foundation3 docker]# docker service ls ID NAME MODE REPLICAS IMAGE gy0slheb99he web_t replicated 1/1 nginx:1.12
通过REPLICAS项目可以看到集群节点的启动状况,”/”左面是集群中启动的个数,”/”右面是集群节点的总个数。
[root@foundation3 docker]# docker service ps web_t ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 6qzlzycuageu web_t.1 nginx:1.12 Nored.example.com Running Running 4 minutes ago
docker service ps可以看到集群节点具体运行在哪台机器上。运行时间等。本次是单节点集群,我们可以看到,容器就运行在本机上。
3.部署多节点集群
[root@foundation3 docker]# docker service create --replicas 3 --name web_a nginx:1.12
添加–replicas 3就是代表集群的个数变为3。manager会将容器平均分配到三个节点上
[root@foundation3 docker]# docker service ls ID NAME MODE REPLICAS IMAGE q8dsqiesl347 web_a replicated 3/3 nginx:1.12
通过docker service ls 可以看到三个节点均运行了起来。
[root@foundation3 docker]# docker service ps web_a ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 5pavjoz2f7wi web_a.1 nginx:1.12 worker1.mo.com Running Running 6 minutes ago ug3hbmlfy95g web_a.2 nginx:1.12 foundation3.ilt.example.com Running Running 6 minutes ago 94dyllk3k1sg web_a.3 nginx:1.12 worker2.mo.com Running Running 6 minutes ago
通过docker service ps 可以看到nginx容器分别运行在三台不同的主机上,为了证明他在另一台主机上运行,我们登陆其中的worker1.mo.com
[root@worker2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ed905660baeb nginx@sha256:0d71ff22db29a08ac7399d1b35b0311c5b0cbe68d878993718275758811f652a "nginx -g 'daemon ..." 29 minutes ago Up 29 minutes 80/tcp web_a.3.94dyllk3k1sgy44fha1ho0kss e5423ea1a6aa
可以看到在docker2上这个容器正在运行。
4.部署服务过程踩过的坑(解释为什么每个节点都要从DockerHub上pull镜像)
我在第一次部署服务的时候由于node1,node2无法联网,所以将Manager上pull下来的镜像直接save成了tar包,在node1,node2上使用load导入这个tar包后部署的nginx服务,但是发现容器只能在manager上运行,接下来问题重现。将你的node1与node2与外网的连接断开
[root@worker2 ~]# ls | grep nginx_1.12.tar nginx_1.12.tar
这个是Nginx镜像的tar包我们将他导入到node1和node2上。在这之前删掉原本有的nginx镜像
docker rmi nginx:1.12
导入镜像
[root@worker2 ~]# docker load -i nginx_1.13.tar Loaded image: nginx:1.12 f12c15fc56f1: Loading layer [==================================================>] 52.75 MB/52.75 MB 08e6bf75740d: Loading layer [==================================================>] 3.584 kB/3.584 kB Loaded image ID: sha256:17daebd00e2c95abb02cd48bcbf562c1993460d40d626501f23985126ea26b21 Loaded image ID: sha256:3448f27c273f3122fc554d7acf33796efb4df2ad9886efc092c3bfe716e897b7
现在开始重新部署服务
[root@foundation3 images]# docker service create --replicas 3 --name web nginx:1.12 x4s7b1iccoebir6avpdnwjcb2
查看集群状态
[root@foundation3 images]# docker service ps web ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS gf040hgh3krc web.1 nginx:1.12 foundation3.ilt.example.com Running Preparing 3 seconds ago jradnn5lgvxl web.2 nginx:1.12 worker2.mo.com Ready Rejected 1 second ago "No such image: nginx@sha256:0…" tez20wghmtpf \_ web.2 nginx:1.12 worker2.mo.com Shutdown Rejected 3 seconds ago "No such image: nginx@sha256:0…" yge4dufnmozw web.3 nginx:1.12 worker1.mo.com Ready Rejected 1 second ago "No such image: nginx@sha256:0…" esprx0otnwj5 \_ web.3 nginx:1.12 worker1.mo.com Shutdown Rejected 2 seconds ago "No such image: nginx@sha256:0…"
可以看到明明在node1,node2上load nginx:1.12的镜像了怎么会创建失败呢。根据ps的显示node1,node2拒绝了的原因是没有nginx的镜像,仔细看后发现后面还有个@sha….,我们猜测是不是由于我们导入的镜像的@后面的值和manager上的不一致导致node1,node2拒绝创建的呢。
现在就引出了一个问题,就是我们如何确定nginx:1.12镜像就是官方给的那个镜像呢,根据后面的tag吗,显然不够安全,这时就需要一个类似于hash签名的东西来标记,但在docker这里这个值叫digests。我们查看下manager上nginx:1.12的digests。
[root@foundation3 images]# docker images --digests|grep nginx nginx 1.12 sha256:0d71ff22db29a08ac7399d1b35b0311c5b0cbe68d878993718275758811f652a 17daebd00e2c 2 weeks ago 109 MB
再看下node2上的nginx:1.12镜像的digests呢
[root@worker2 ~]# docker images --digests REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE nginx 1.12 <none> 17daebd00e2c 2 weeks ago 109 MB
可以看到是一个none。看到这里我想大家应该明白为什么重新部署的这次服务失败了,因为虽然我们自己可以确定那个nginx镜像是我们自己save再load过去的,但是docker无法解析根据这个tag解析出digests所以认为镜像不同,导致服务创建失败。
解决方法:目前只能让你的所有节点都连上网,如果你的镜像在save过程没有出错的话,那么我们现在将node1,node2连上外网,再重新部署集群node1,node2上的docker就会自己去DockerHub上查询tag对应的digests了,也就部署成功了。但是有些环境下,我们的节点无法连接外网该怎么办呢,目前还没有解决,解决之后我会马上更新告诉大家。本部分涉及的像digests这些知识点在Docker官网链接。
三.创建服务时的详细参数配置与更新部署的服务
1.将主机中的文件挂载到服务中[root@foundation3 tmp]# docker service create --name web --mount type=bind,src=/tmp/in_in,dst=/ini nginx:1.12
将本机中的/tmp/in_in文件挂载到容器中的/ini上。这个参数与docker run中的-v差不多,但是要记住指定type。
(图片引自Docker官网)
只读挂载
[root@foundation3 ~]# docker service create --mount type=bind,src=/tmp/in_in,dst=/in,ro=true --name web nginx:1.12
默认挂载是读写挂载的,如果你不希望容器修改数据,请加上ro=true参数。
2.创建时更新方法的配置
docker service create \ --replicas 12 \ --name my_web \ --update-delay 10s \ --update-parallelism 2 \ --update-failure-action continue \ nginx:1.12
上面是创建了一个节点的docker集群,通过指定”–update-delay”来确定每组更新的间隔,”–update-parallelism”来确定同时更新的容器数量,”–update-failure-action continue”来却id那个当更新失败时候执行的操作,是继续允许还是不继续。
docker service update \ --rollback \ --update-delay 0s web
上面是回滚服务使用的命令。
相关文章推荐
- docker创建镜像、单个容器、swarm集群启动、更新服务等常用指令
- 如何调用docker swarm service的API来创建及更新服务
- Swarm创建docker集群:服务发现-etcd
- Docker应用示例2--使用Docker创建简单集群服务
- 生产环境部署swarm集群及 swarm-overlay-portainer(webui) 实战应用
- 构建微服务实验环境(二):Docker Swarm 集群
- Docker Swarm集群部署应用
- 搭建Docker Swarm集群实战(二)(服务发现使用consul)
- 搭建Docker Swarm集群实战(一)(服务发现使用consul)
- Swarm创建docker集群:服务发现-etcd
- Swarm创建docker集群:服务发现-配置文件法
- Docker Swarm 集群 微服务部署
- 通过Mongo, Docker和Rancher创建Node.js应用集群
- Linux应用服务器搭建手册—Weblogic服务域的创建与部署
- 跟我学习dubbo-构建Dubbo服务消费者Web应用的war包并在Tomcat中部署(6)
- 创建docker swarm集群的两种方式
- 实战部署weblogic集群及发布应用(2)
- 通过docker-machine和etcd部署docker swarm集群
- 使用概要管理工具创建定制概要文件,并在此节点上 创建集群以及在集群服务器中部署应用
- 实战部署weblogic集群及发布应用(6)