• 售前

  • 售后

热门帖子
入门百科

详解基于docker-swarm搭建一连集成集群服务

[复制链接]
lishuixiu006 显示全部楼层 发表于 2021-10-25 19:49:06 |阅读模式 打印 上一主题 下一主题
媒介

本文只为本身搭建过程中的一些简朴的记录。假如实践中有疑问,可以一起探讨。

为了能在本机(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&registor方式)。

3、构建镜像的运维节点 ops:

也即运维机器。一个独立的节点即可。重要负责build镜像,push镜像。在ops里可以构建gitlab的私库。维护构建脚本。机器所需配置不高,对网络宽带照旧尽量多一些。

用docker-machine 模仿集群环境

创建registry节点
  1. docker-machine create -d virtualbox --virtualbox-memory "512" registry
复制代码
–engine-registry-mirror 这个参数是可以设置一些加速堆栈的地点。
创建manager,worker节点

manager
复制代码 代码如下:docker-machine create -d virtualbox --virtualbox-memory "800"  manager1   

worker:
  1. docker-machine create -d virtualbox --virtualbox-memory "800" worker1
  2. docker-machine create -d virtualbox --virtualbox-memory "800" worker2
  3. docker-machine create -d virtualbox --virtualbox-memory "800" worker3
复制代码
创建ops 节点
  1. docker-machine create -d virtualbox --virtualbox-memory "512" ops
复制代码
检察机器列表状态
  1. docker-machine ls
复制代码
创建registry服务

登录到registry机器上。
  1. docker-machine ssh registry
复制代码
创建一个registry服务。
  1. docker run -d -p 5000:5000 --restart=always --name registry \
  2. -v `pwd`/data:/var/lib/registry \
  3. 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文件之后直接启动:
  1. docker-compose up -d
复制代码
当地堆栈push镜像

现在可以尝试拉一个镜像,然后tag到当地的registry堆栈,如
复制代码 代码如下:docker pull lijingyao0909/see:1.0.3 && docker tag lijingyao0909/see:1.0.3 localhost:5000/see:1.0.3

然后再执行push 下令:
  1. docker push localhost:5000/see:1.0.3
复制代码
这个镜像就push到了registry服务中,最直接的方式可以通过检察当地的volumn目次,如本例中的 data目次检察到镜像数据。
假如为了更方便的可视化管理registry,也可以试用下registry UI 相干的镜像如hyper/docker-registry-web。
复制代码 代码如下:docker run -it -p 8080:8080 --name registry-web --link registry-srv -e REGISTRY_URL=http://registry-srv:5000/v2 -e REGISTRY_NAME=localhost:5000 hyper/docker-registry-web
然后访问 hostname:5000/registory/index可以看到简朴的镜像列表UI。
https 问题

在当地测试时假如执行以上步调,在push,大概在其他vb中pull镜像时遇到以下问题:
  1. 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”:
  1. sudo vi /var/lib/boot2docker/profile
复制代码
添加
  1. DOCKER_OPTS="--insecure-registry <host-name>:5000"
  2. DOCKER_OPTS="--insecure-registry registry:5000"
复制代码
由于registry的hostname就是 registry。以是执行docker ifno下令可以看到:
  1. Insecure Registries:
  2. registry:5000
  3. 127.0.0.0/8
复制代码
同时,在其他的worker机器,manager机器也须要修改–insecure-registry属性,才可以pull私库的镜像。修改之后需重新restart vb。

重启后,在manager重新尝试pull
  1. docker pull registry: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镜像
  1. docker run --detach \
  2. --hostname gitlab.lijingyao.com \
  3. --publish 443:443 --publish 80:80 --publish 22:22 \
  4. --name gitlab \
  5. --restart always \
  6. --volume `pwd`/gitlab/config:/etc/gitlab \
  7. --volume `pwd`/gitlab/logs:/var/log/gitlab \
  8. --volume `pwd`/gitlab/data:/var/opt/gitlab \
  9. 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 集群的机器,检察如下:
  1. $docker-machine ls
  2. NAME  ACTIVE DRIVER  STATE  URL       SWARM DOCKER ERRORS
  3. haproxy -  virtualbox Running tcp://192.168.99.103:2376   v1.12.3
  4. manager1 -  virtualbox Running tcp://192.168.99.100:2376   v1.12.3
  5. ops  -  virtualbox Running tcp://192.168.99.106:2376   v1.12.3
  6. registry -  virtualbox Running tcp://192.168.99.107:2376   v1.12.3
  7. worker1 -  virtualbox Running tcp://192.168.99.101:2376   v1.12.3
  8. worker2 -  virtualbox Running tcp://192.168.99.102:2376   v1.12.3
  9. worker3 -  virtualbox Running tcp://192.168.99.105:2376   v1.12.3
复制代码
然后用docker-machine ssh manager1登陆到manager1机器上。
初始化swarm manager节点

在manager1 机器上初始化swarm,这个初始化的机器就是swarm的manager.执行:
  1. docker swarm init --advertise-addr 192.168.99.100
复制代码
会看到以下执行输出:
  1. Swarm initialized: current node (03x5vnxmk2gc43i0d7xpycvjg) is now a manager.
  2. To add a worker to this swarm, run the following command:
  3. docker swarm join \
  4. --token SWMTKN-1-5ru6lyco3upj7oje6hidug3erqczok84wk7bekzfaca4uv51r9-22bcjhkbxnclmw3nl3ui8601l \
  5. 192.168.99.100:2377
  6. To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
复制代码
这个天生的token值,是其他swarm集群节点join到整个swarm的key。假如忘记了token,可以在manager1上执行:
  1. $docker swarm join-token manager
复制代码
来检察现在的token值。官方发起至少6个月更换以下token。更换下令:
  1. $docker swarm join-token --rotate worker
复制代码
添加worker节点

分别登录 worker1,worker2,worker3,执行join下令。

在join之前,先检察下docker 网络设施。执行
  1. $ docker network ls
  2. NETWORK ID   NAME    DRIVER    SCOPE
  3. 4b7fe1416322  bridge    bridge    local   
  4. 06ab6f3352b0  host    host    local   
  5. eebd5c8e0d5d  none    null    local
复制代码
按照manager1 初始化之后的下令,执行:
  1. docker swarm join \
  2. --token SWMTKN-1-5ru6lyco3upj7oje6hidug3erqczok84wk7bekzfaca4uv51r9-22bcjhkbxnclmw3nl3ui8601l \
  3. 192.168.99.100:2377
复制代码
此时在任何worker节点再执行docker network ls 即可看到多了一个overlay的覆盖范围为swarm的网络通道。

三个worker都加入之后,在manager1 上即可看到manager的node节点环境
  1. docker node ls
  2. ID       HOSTNAME STATUS AVAILABILITY MANAGER STATUS
  3. 03x5vnxmk2gc43i0d7xpycvjg * manager1 Ready Active  Leader  
  4. 2y5wrndibe8c8sqv6851vrlgp worker1 Ready Active  Reachable
  5. dwgol1uinkpsybigc1gm5jgsv worker2 Ready Active  
  6. etgyky6zztrapucm59yx33tg1 worker3 Ready Active  Reachable
复制代码
manager status的Reachable状态表现该节点也是manager节点。这是由于我们在worker1,worker3分别执行了
  1. docker node promote worker1
  2. docker node promote worker3
复制代码
worker1,worker3此时也可以执行swarm下令,在manager1关停时,就会选举此中之一作为新的leader。假如要去除node的manager状态,可以通过demote下令去除。执行后,worker节点就酿成平凡的使命节点。
  1. docker node demote worker1 worker3
复制代码
swarm节点的其他状态

swarm节点可以设置drain状态,drain状态的节点不会执行任何service。

将某个node设置不可用:
  1. docker node update --availability drain worker1
复制代码
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个运行容器服务。
  1. docker service create \
  2. --replicas 4 \
  3. --name deftsee \
  4. --update-delay 10s \
  5. --publish 8080:80 \
  6. lijingyao0909/see:1.0.3
复制代码
服务创建之后,可以检察服务节点的状态
  1. docker@manager1:~$ docker service ls
  2. ID   NAME  REPLICAS IMAGE     COMMAND
  3. a6s5dpsyz7st deftsee 4/4  lijingyao0909/see:1.0.3
复制代码
REPLICAS 代表服务的运行容器数,假如是0/4就代表所有服务都没有起来。详细检察各个节点运行状态可以用docker service ps servicename
  1. docker@manager1:~$ docker service ps deftsee
  2. ID       NAME  IMAGE     NODE  DESIRED STATE CURRENT STATE   ERROR
  3. 8lsdkf357lk0nmdeqk7bi33mp deftsee.1 lijingyao0909/see:1.0.3 worker2 Running  Running 5 minutes ago
  4. cvqm5xn7t0bveo4btfjsm04jp deftsee.2 lijingyao0909/see:1.0.3 manager1 Running  Running 7 minutes ago
  5. 6s5km76w2vxmt0j4zgzi4xi5f deftsee.3 lijingyao0909/see:1.0.3 worker1 Running  Running 5 minutes ago
  6. 4cl9vnkssedpvu2wtzu6rtgxl deftsee.4 lijingyao0909/see:1.0.3 worker3 Running  Running 6 minutes ago
复制代码
可以看到使命被平分到所有的四个使命节点运行。下面再扩容deftsee服务
  1. docker@manager1:~$ docker service scale deftsee=6
  2. deftsee scaled to 6
  3. docker@manager1:~$ docker service ps deftsee
  4. ID       NAME  IMAGE     NODE  DESIRED STATE CURRENT STATE   ERROR
  5. 8lsdkf357lk0nmdeqk7bi33mp deftsee.1 lijingyao0909/see:1.0.3 worker2 Running  Running 8 minutes ago
  6. cvqm5xn7t0bveo4btfjsm04jp deftsee.2 lijingyao0909/see:1.0.3 manager1 Running  Running 10 minutes ago
  7. 6s5km76w2vxmt0j4zgzi4xi5f deftsee.3 lijingyao0909/see:1.0.3 worker1 Running  Running 8 minutes ago
  8. 4cl9vnkssedpvu2wtzu6rtgxl deftsee.4 lijingyao0909/see:1.0.3 worker3 Running  Running 9 minutes ago
  9. 71uv51uwvso4l340xfkbacp2i deftsee.5 lijingyao0909/see:1.0.3 manager1 Running  Running 5 seconds ago
  10. 4r2q7q782ab9fp49mdriq0ssk deftsee.6 lijingyao0909/see:1.0.3 worker2 Running  Running 5 seconds ago
复制代码
lijingyao0909/see:1.0.3是dockerhub的公共堆栈的镜像,服务创建时会去pull镜像,团体速率偏慢,以是可以联合私有堆栈,直接在registry机器上pull镜像。服务可以直接用docker service rm deftsee移除服务,然后通过registry重修服务。
  1. docker service create \
  2. --replicas 6 \
  3. --name deftsee \
  4. --update-delay 10s \
  5. --publish 8080:80 \
  6. registry:5000/see:1.0.4
复制代码
此时登录任何一台worker服务,检察运行的容器镜像:
  1. docker@worker2:~$ docker ps
  2. CONTAINER ID  IMAGE      COMMAND     CREATED    STATUS    PORTS    NAMES
  3. 89d4f588290b  registry:5000/see:1.0.4 "/bin/sh -c 'java -Dc" About a minute ago Up About a minute 8080/tcp   deftsee.1.eldpgb1aqtf9v49cxolydfjm9
复制代码
假如要更新服务,可以直接通过update下令更新版本,并且服务滚动发布,通过设置*–update-delay 10s *可以改变更新时各个节点的延迟时间。
  1. docker service update --image registry:5000/see:1.0.5 deftsee
复制代码
重启某个node的服务

关闭:docker node update –availability drain worker1

开启:docker node update –availability active worker1
更新服务端口

更新一个服务的端口会重启服务(关闭原有服务,重新创建服务并启动):
  1. docker service update \
  2. --publish-add <PUBLISHED-PORT>:<TARGET-PORT> \
  3. <SERVICE>
  4. docker@manager1:~$docker service update \
  5. --publish-add 8099:8080 \
  6. deftsee
  7. docker@manager1:~$ docker service ps deftsee
  8. ID       NAME   IMAGE     NODE  DESIRED STATE CURRENT STATE    ERROR
  9. 3xoe34msrht9eqv7eplnmlrz5 deftsee.1  registry:5000/see:1.0.4 manager1 Running  Running 39 seconds ago  
  10. eldpgb1aqtf9v49cxolydfjm9 \_ deftsee.1 registry:5000/see:1.0.4 worker2 Shutdown  Shutdown 39 seconds ago  
  11. 9u4fh3mi5kxb14y6gih5d8tqv deftsee.2  registry:5000/see:1.0.4 manager1 Running  Running about a minute ago
  12. 0skgr5fx4xtt6y71yliksoft0 \_ deftsee.2 registry:5000/see:1.0.4 worker1 Shutdown  Shutdown about a minute ago
  13. 8hposdkqe92k7am084z6kt1j0 deftsee.3  registry:5000/see:1.0.4 worker3 Running  Running about a minute ago
  14. c5vhx1wx0q8mxaweaq0mia6n7 \_ deftsee.3 registry:5000/see:1.0.4 manager1 Shutdown  Shutdown about a minute ago
  15. 9se1juxiinmetuaccgkjc3rr2 deftsee.4  registry:5000/see:1.0.4 worker1 Running  Running about a minute ago
  16. 4wofho0axvrjildxhckl52s41 \_ deftsee.4 registry:5000/see:1.0.4 worker3 Shutdown  Shutdown about a minute ago
复制代码
服务验证和网络

例子中的服务启动后,可以直接通过ip:port访问。如http://192.168.99.100:8099/see,可以看到服务哀求会分发到各个运行的节点中。也就是swarm的overlay网络层,各个节点的网络是互通的,swarm做了load balance,在swarm的lb的底子上也可搭建本身定义的overlay网络,创建的这个overlay 网络,所有节点都可以和这个network互通。但是在服务创建的时候须要制定network选项。
  1. $docker network create \
  2. --driver overlay \
  3. --subnet 10.0.9.0/24 \
  4. --opt encrypted \  
  5. my-network
  6. $docker service create \
  7. --name deftsee \
  8. --publish 8099:80 \
  9. --replicas 4 \
  10. --network my-network \
  11. -l com.df.serviceDomain=deftsee.com \
  12. -l com.df.notify=true \
  13. 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网络信息:
  1. $docker service inspect \
  2. --format='{{json .Endpoint.VirtualIPs}}' \
  3. deftsee
  4. 输出:[{"NetworkID":"dn05pshfagohpebgonkhj5kxi","Addr":"10.255.0.6/16"}]
复制代码
swarm管理

为了保持manager节点的可用性(心跳机制,leader选举),可以将manager节点设置成不接受服务运行,节省manager节点资源,将manager节点隔离出使命环境。
  1. docker node update --availability drain <NODE>
复制代码
备份/var/lib/docker/swarm/raft 状态

整理不可用的节点
  1. docker node demote <NODE>
  2. docker node rm <id-node>.
复制代码
节点重新加入manager re-join
  1. $docker node demote <NODE>.
  2. $docker node rm <NODE>.
  3. $docker swarm join ...
复制代码
初始化的时候指定固定ip ,init –advertise-addr。worker节点可以用动态ip 。

参考资源

Swarm mode

以上就是本文的全部内容,希望对各人的学习有所帮助,也希望各人多多支持脚本之家。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作