基于docker-mile米乐体育
小编给大家分享一下基于docker-swarm搭建持续集成集群服务的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
为了能在本机(macos)模拟集群环境,使用了vb和docker-machine。整体持续集成的几个机器设施如下:
1、服务节点:三个manager节点,一个worker节点。manager需要占用更多的资源,manager配置尽量高一些。swarm的manager节点的容错率是 (n-1)/2 。n是manager节点数。也就是如果有3个manager,那就能容忍一个manager节点挂掉。官方的算法说明:raft consensus in swarm mode。
2、本地的镜像仓库 registry:用来存储所有需要部署的服务docker镜像。
https://docs.docker.com/registry/deploying/
因为使用swarm机制,所以不需要在服务间通信问题考虑服务发现以及负载均衡的问题(代替原有的consul®istor方式)。
3、构建镜像的运维节点 ops:
也即运维机器。一个独立的节点即可。主要负责build镜像,push镜像。在ops里可以构建gitlab的私库。维护构建脚本。机器所需配置不高,对网络宽带还是尽量多一些。
用docker-machine 模拟集群环境
创建registry节点
docker-machinecreate-dvirtualbox--virtualbox-memory"512"registry
–engine-registry-mirror 这个参数是可以设置一些加速仓库的地址。
创建manager,worker节点
manager
复制代码 代码如下:
docker-machine create -d virtualbox --virtualbox-memory "800" manager1
worker:
docker-machinecreate-dvirtualbox--virtualbox-memory"800"worker1 docker-machinecreate-dvirtualbox--virtualbox-memory"800"worker2 docker-machinecreate-dvirtualbox--virtualbox-memory"800"worker3
创建ops 节点
docker-machinecreate-dvirtualbox--virtualbox-memory"512"ops
查看机器列表状态
docker-machinels
创建registry服务
登录到registry机器上。
docker-machinesshregistry
创建一个registry服务。
dockerrun-d-p5000:5000--restart=always--nameregistry\ -v`pwd`/data:/var/lib/registry\ registry:2
命令设置了-v volumn选项,这样在每次容器服务重启的时候,不会丢失已经pull的镜像数据。registry,mysql等存储类型的容器,建议设置一下volumn.如果为了更好的扩展,也可以将镜像仓库备份到其他driver里,如阿里云的oss.
运行docker ps就可以看到一个启动好的registry服务。当然,为了更好的扩展,也可以挂载在自己的域名下,重新run 的时候添加认证信息。
为了更方便管理容器,可以使用docker-compose 组件。安装:
curl-l"https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname-s)-$(uname-m)"-o/usr/local/bin/docker-compose
也可以写好compose文件之后直接启动:
docker-composeup-d
本地仓库push镜像
现在可以尝试拉一个镜像,然后tag到本地的registry仓库,如
dockerpulllijingyao0909/see:1.0.3&&dockertaglijingyao0909/see:1.0.3localhost:5000/see:1.0.3
然后再执行push 命令:
dockerpushlocalhost:5000/see:1.0.3
这个镜像就push到了registry服务中,最直接的方式可以通过查看本地的volumn目录,如本例中的 data目录查看到镜像数据。 如果为了更方便的可视化管理registry,也可以试用下registry ui 相关的镜像如hyper/docker-registry-web。
dockerrun-it-p8080:8080--nameregistry-web--linkregistry-srv-eregistry_url=http://registry-srv:5000/v2-eregistry_name=localhost:5000hyper/docker-registry-web
然后访问 hostname:5000/registory/index可以看到简单的镜像列表ui。
https 问题
在本地测试时如果执行以上步骤,在push,或者在其他vb中pull镜像时遇到以下问题:
error response from daemon: get https://registry:5000/v1/_ping: dial tcp 218.205.57.154:5000: i/o timeout
处理方式是,修改registry的认证,如下先修改“/var/lib/boot2docker/profile”:
sudovi/var/lib/boot2docker/profile
添加
docker_opts="--insecure-registry:5000" docker_opts="--insecure-registryregistry:5000"
因为registry的hostname就是 registry。所以执行docker ifno命令可以看到:
insecureregistries: registry:5000 127.0.0.0/8
同时,在其他的worker机器,manager机器也需要修改–insecure-registry属性,才可以pull私库的镜像。修改之后需重新restart vb。
重启后,在manager重新尝试pull
dockerpullregistry:5000/see:1.0.3
可以看到成功连接仓库并拉取镜像。注意,本示例使用的是机器名,registry,而不是ip地址。所以,在拉取镜像的时候,需在各自的vb 的etc/hosts文件配置ip和机器名的映射。用机器名的方式比较操作易记。当然最好的方式还是通过域名访问仓库。
参考资源
部署registry服务
创建ops服务
swarm的服务集群会直接从registry上pull镜像,直接启动应用的service服务。服务的镜像直接打在registry仓库中,但是源码可以维护在ops机器上。前面创建的ops的virtual-box,可以部署gitlab服务。启动参数可以参考deploy gitlab docker images
先pull一个gitlab镜像
dockerrun--detach\ --hostnamegitlab.lijingyao.com\ --publish443:443--publish80:80--publish22:22\ --namegitlab\ --restartalways\ --volume`pwd`/gitlab/config:/etc/gitlab\ --volume`pwd`/gitlab/logs:/var/log/gitlab\ --volume`pwd`/gitlab/data:/var/opt/gitlab\ gitlab/gitlab-ce:8.14.4-ce.0
使用git私库
因绑定了80端口,启动gitlab后访问:http://machine-host/
第一次进入gitlab会自动跳转到重置密码。可以设置一个新的密码,这个是root账号的密码。后续就可以注册其他git用户使用了。 这里,如果申请了域名服务,或者本地绑定gitlab.lijingyao.com 到这个virtualbox的ip地址,就可以直接访问gitlab.lijingyao.com地址。在实际生产环境有固定公网ip,自己的dns服务,就不需要绑定host。这里只是本地测试,所以暂时就通过绑定host的方式。
swarm
本例中的服务是一个简单的springboot 和gradle的工程,服务镜像可以在docker hub pull,see service image。打包好镜像后,直接在gradle task中push到registry仓库中。在本地环境可以直接在工程目录里执行。gradle task然后push到vb的registry中,再在registry 仓库pull镜像即可。现在开始准备初始化swarm 集群。
现在整个vb 集群的机器,查看如下:
$docker-machinels nameactivedriverstateurlswarmdockererrors haproxy-virtualboxrunningtcp://192.168.99.103:2376v1.12.3 manager1-virtualboxrunningtcp://192.168.99.100:2376v1.12.3 ops-virtualboxrunningtcp://192.168.99.106:2376v1.12.3 registry-virtualboxrunningtcp://192.168.99.107:2376v1.12.3 worker1-virtualboxrunningtcp://192.168.99.101:2376v1.12.3 worker2-virtualboxrunningtcp://192.168.99.102:2376v1.12.3 worker3-virtualboxrunningtcp://192.168.99.105:2376v1.12.3
然后用docker-machine ssh manager1登陆到manager1机器上。
初始化swarm manager节点
在manager1 机器上初始化swarm,这个初始化的机器就是swarm的manager.执行:
dockerswarminit--advertise-addr192.168.99.100
会看到以下执行输出:
swarminitialized:currentnode(03x5vnxmk2gc43i0d7xpycvjg)isnowamanager. toaddaworkertothisswarm,runthefollowingcommand: dockerswarmjoin\ --tokenswmtkn-1-5ru6lyco3upj7oje6hidug3erqczok84wk7bekzfaca4uv51r9-22bcjhkbxnclmw3nl3ui8601l\ 192.168.99.100:2377 toaddamanagertothisswarm,run'dockerswarmjoin-tokenmanager'andfollowtheinstructions.
这个生成的token值,是其他swarm集群节点join到整个swarm的key。如果忘记了token,可以在manager1上执行:
$dockerswarmjoin-tokenmanager
来查看目前的token值。官方建议至少6个月更换以下token。更换命令:
$dockerswarmjoin-token--rotateworker
添加worker节点
分别登录 worker1,worker2,worker3,执行join命令。
在join之前,先查看下docker 网络设施。执行
$dockernetworkls networkidnamedriverscope 4b7fe1416322bridgebridgelocal 06ab6f3352b0hosthostlocal eebd5c8e0d5dnonenulllocal
按照manager1 初始化之后的命令,执行:
dockerswarmjoin\ --tokenswmtkn-1-5ru6lyco3upj7oje6hidug3erqczok84wk7bekzfaca4uv51r9-22bcjhkbxnclmw3nl3ui8601l\ 192.168.99.100:2377
此时在任何worker节点再执行docker network ls 即可看到多了一个overlay的覆盖范围为swarm的网络通道。
三个worker都加入之后,在manager1 上即可看到manager的node节点情况
dockernodels idhostnamestatusavailabilitymanagerstatus 03x5vnxmk2gc43i0d7xpycvjg*manager1readyactiveleader 2y5wrndibe8c8sqv6851vrlgpworker1readyactivereachable dwgol1uinkpsybigc1gm5jgsvworker2readyactive etgyky6zztrapucm59yx33tg1worker3readyactivereachable
manager status的reachable状态表示该节点也是manager节点。这是因为我们在worker1,worker3分别执行了
dockernodepromoteworker1 dockernodepromoteworker3
worker1,worker3此时也可以执行swarm命令,在manager1关停时,就会选举其中之一作为新的leader。如果要去除node的manager状态,可以通过demote命令去除。执行后,worker节点就变成普通的任务节点。
dockernodedemoteworker1worker3
swarm节点的其他状态
swarm节点可以设置drain状态,drain状态的节点不会执行任何service。
将某个node设置不可用:
dockernodeupdate--availabilitydrainworker1
pause,drain,active三个状态,pause标识有任务运行,不接受新任务。
如果要将worker1 节点去除swarm中心,现在需被移除的节点(worker1)执行:docker swarm leave 然后在manager上执行:docker node rm worker1,即可移除一个swarm节点。
创建swarm服务
本例中使用swarm部署一个基于springboot的rest api服务。仓库的地址:springboot-restful-exam,创建的服务name是deftsee,绑定80端口,并且扩展4个运行容器服务。
dockerservicecreate\ --replicas4\ --namedeftsee\ --update-delay10s\ --publish8080:80\ lijingyao0909/see:1.0.3
服务创建之后,可以查看服务节点的状态
docker@manager1:~$dockerservicels idnamereplicasimagecommand a6s5dpsyz7stdeftsee4/4lijingyao0909/see:1.0.3
replicas 代表服务的运行容器数,如果是0/4就代表所有服务都没有起来。详细查看各个节点运行状态可以用docker service ps servicename
docker@manager1:~$dockerservicepsdeftsee idnameimagenodedesiredstatecurrentstateerror 8lsdkf357lk0nmdeqk7bi33mpdeftsee.1lijingyao0909/see:1.0.3worker2runningrunning5minutesago cvqm5xn7t0bveo4btfjsm04jpdeftsee.2lijingyao0909/see:1.0.3manager1runningrunning7minutesago 6s5km76w2vxmt0j4zgzi4xi5fdeftsee.3lijingyao0909/see:1.0.3worker1runningrunning5minutesago 4cl9vnkssedpvu2wtzu6rtgxldeftsee.4lijingyao0909/see:1.0.3worker3runningrunning6minutesago
可以看到任务被平分到所有的四个任务节点运行。下面再扩容deftsee服务
docker@manager1:~$dockerservicescaledeftsee=6 deftseescaledto6 docker@manager1:~$dockerservicepsdeftsee idnameimagenodedesiredstatecurrentstateerror 8lsdkf357lk0nmdeqk7bi33mpdeftsee.1lijingyao0909/see:1.0.3worker2runningrunning8minutesago cvqm5xn7t0bveo4btfjsm04jpdeftsee.2lijingyao0909/see:1.0.3manager1runningrunning10minutesago 6s5km76w2vxmt0j4zgzi4xi5fdeftsee.3lijingyao0909/see:1.0.3worker1runningrunning8minutesago 4cl9vnkssedpvu2wtzu6rtgxldeftsee.4lijingyao0909/see:1.0.3worker3runningrunning9minutesago 71uv51uwvso4l340xfkbacp2ideftsee.5lijingyao0909/see:1.0.3manager1runningrunning5secondsago 4r2q7q782ab9fp49mdriq0sskdeftsee.6lijingyao0909/see:1.0.3worker2runningrunning5secondsago
lijingyao0909/see:1.0.3是dockerhub的公共仓库的镜像,服务创建时会去pull镜像,整体速度偏慢,所以可以结合私有仓库,直接在registry机器上pull镜像。服务可以直接用docker service rm deftsee移除服务,然后通过registry重建服务。
dockerservicecreate\ --replicas6\ --namedeftsee\ --update-delay10s\ --publish8080:80\ registry:5000/see:1.0.4
此时登录任何一台worker服务,查看运行的容器镜像:
docker@worker2:~$dockerps containeridimagecommandcreatedstatusportsnames 89d4f588290bregistry:5000/see:1.0.4"/bin/sh-c'java-dc"aboutaminuteagoupaboutaminute8080/tcpdeftsee.1.eldpgb1aqtf9v49cxolydfjm9
如果要更新服务,可以直接通过update命令更新版本,并且服务滚动发布,通过设置*–update-delay 10s *可以改变更新时各个节点的延迟时间。
dockerserviceupdate--imageregistry:5000/see:1.0.5deftsee
重启某个node的服务
关闭:docker node update –availability drain worker1
开启:docker node update –availability active worker1
更新服务端口
更新一个服务的端口会重启服务(关闭原有服务,重新创建服务并启动):
dockerserviceupdate\ --publish-add: \ docker@manager1:~$dockerserviceupdate\ --publish-add8099:8080\ deftsee docker@manager1:~$dockerservicepsdeftsee idnameimagenodedesiredstatecurrentstateerror 3xoe34msrht9eqv7eplnmlrz5deftsee.1registry:5000/see:1.0.4manager1runningrunning39secondsago eldpgb1aqtf9v49cxolydfjm9\_deftsee.1registry:5000/see:1.0.4worker2shutdownshutdown39secondsago 9u4fh4mi5kxb14y6gih6d8tqvdeftsee.2registry:5000/see:1.0.4manager1runningrunningaboutaminuteago 0skgr5fx4xtt6y71yliksoft0\_deftsee.2registry:5000/see:1.0.4worker1shutdownshutdownaboutaminuteago 8hposdkqe92k7am084z6kt1j0deftsee.3registry:5000/see:1.0.4worker3runningrunningaboutaminuteago c5vhx1wx0q8mxaweaq0mia6n7\_deftsee.3registry:5000/see:1.0.4manager1shutdownshutdownaboutaminuteago 9se1juxiinmetuaccgkjc3rr2deftsee.4registry:5000/see:1.0.4worker1runningrunningaboutaminuteago 4wofho0axvrjildxhckl52s41\_deftsee.4registry:5000/see:1.0.4worker3shutdownshutdownaboutaminuteago
服务验证和网络
例子中的服务启动后,可以直接通过ip:port访问。如http://192.168.99.100:8099/see,可以看到服务请求会分发到各个运行的节点中。也就是swarm的overlay网络层,各个节点的网络是互通的,swarm做了load balance,在swarm的lb的基础上也可搭建自己定义的overlay网络,创建的这个overlay 网络,所有节点都可以和这个network互通。但是在服务创建的时候需要制定network选项。
$dockernetworkcreate\ --driveroverlay\ --subnet10.0.9.0/24\ --optencrypted\ my-network $dockerservicecreate\ --namedeftsee\ --publish8099:80\ --replicas4\ --networkmy-network\ -lcom.df.servicedomain=deftsee.com\ -lcom.df.notify=true\ lijingyao0909/see:1.0.3
–network my-network制定了服务可连接到的docker network,可以在swarm的节点创建一个name为my-network的网络。所以也可以在swarm机制中搭建consul和haproxy的服务发现和lb机制。
当为一个服务指定一个network的时候,swarm上执行的任务也必须都在这个指定的网络上才能和服务互通。如果节点上没有加入到swarm模式的node中,或者没有运行挂载在这个指定网络的时候,也不会和这个network互通.docker network ls也不会查出该网络。创建服务时通过–network my-network这个标签链接到这个网络。在查看网络时,docker network inspect my-network可以查看返回的containers 列出的该节点的挂载容器。
创建了一个网络服务,有service连接到网络时,swarm会给这个网络下的服务(service)指定一个vip. swarm 内部的lb会自动分发服务,不需要指定每个服务端口,即在同一个network连接的容器,通过service name就可以访问到服务。因为所有加入到这个network的容器都会通过gossip协议共享一个dns映射(vip映射根据service name 绑定到的dns别名映射)。
查看服务的vip网络信息:
$dockerserviceinspect\ --format='{{json.endpoint.virtualips}}'\ deftsee 输出:[{"networkid":"dn05pshfagohpebgonkhj5kxi","addr":"10.255.0.6/16"}]
swarm管理
为了保持manager节点的可用性(心跳机制,leader选举),可以将manager节点设置成不接受服务运行,节省manager节点资源,将manager节点隔离出任务环境。
dockernodeupdate--availabilitydrain
备份/var/lib/docker/swarm/raft 状态
清理不可用的节点
dockernodedemotedockernoderm .
节点重新加入manager re-join
$dockernodedemote. $dockernoderm . $dockerswarmjoin...
初始化的时候指定固定ip ,init –advertise-addr。worker节点可以用动态ip 。
以上是“基于docker-swarm搭建持续集成集群服务的方法”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道!