您的位置:首页 > 运维架构 > Docker

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 linux 容器