前言
Docker微服务架构,已渐渐成为服务器架构的主流 。 但是对于Docker在生产环境的部署方案,目前没有一个明确的标准或者最佳实践。笔者对比了很多方案,也实践了不少,发现要管理Docker的完整生命周期并非易事。最后经过各种分析后,发现Docker微服务的架构。只要消除一些看上去很必要的特性,其实可以很简单。
这些特性包括:
- 服务发现
- 私有docker仓库
- 蓝绿发布
- 镜像更新,容器重启
- 微服务负载均衡
- 服务于无法热部署的服务器语言(如Java)
- 集中式的服务治理
- 等等
去掉这些特性之后,回归Docker的优势,其实就是应用环境的隔离以及消除差异化。
抛弃这些特性后,剩下一些必要的东西,我的架构看上去是这样的:
image.png- Git Server:这个肯定少不了
- Jenkins server:CI 较成熟的工具,暂时没找着替代品
- 应用服务器宿主机集群:这里部署的都是应用层的服务,对外做负载均衡方案,方案有很多,就不细说。
- 微服务宿主机集群:因为不用做负载均衡方案,宿主机其实可以是分散的,相互之前可以没什么关系。
- 消息服务:适合使用比较稳定的云服务,也可以自己搭集群。
- 若干工作站
所有的宿主机采用的是相同配置和方案,这样复制起来比较简单。
应用服务和微服务只是定义上的差别,实际上都是一样的。
整套方案,连摸索带调试,也就花了一个下午的时间。当然前设是之前踩了不少坑。
实际上这套方案的实施,难点也不多。所以很容易既拿既用。
构建过程
1 准备硬件环境
所有的工作都在一台mac pro 上完成
在这台mac pro上使用Vmware构建了 几台CentOS 7 的虚拟机(Docker 3.x需要运行在至少CentOS 7 上 )
- Mac Pro :192.168.226.1, 工作站
- CentOS 7 Node1 :192.168.226.137 ,部署jenkins server
- CentOS 7 Node2 :192.168.226.138 ,微服务宿主机
- CentOS 7 Node3 :192.168.226.139 ,应用服务宿主机
宿主机的配置都是一样的,可以选择安装完必要的服务后直接克隆(docker,docker-compose,rsync,后面会介绍)。
git server 直接使用github
2 安装Docker
CentOS7 docker 的安装可以看这篇文章:
https://yeasy.gitbooks.io/docker_practice/content/install/centos.html
按步骤安装即可,千万别忘了更改docker镜像地址。
Centos 7 安装docker-compose:
curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
关于镜像地址的获得Docker的基础使用,以及mac下Docker的安装,可以看实践第一篇文章:
docker+consul基于服务发现的极简web架构实践
现在你可以暂时忘记Docker了。
3 安装jenkins
jenkins的安装,你可以按这篇文章:
https://hostpresto.com/community/tutorials/how-to-install-jenkins-on-centos-7/
需要注意的是,文章里有点格式错误
firewall-cmd --zone=public --permanent --add-port=8080/tcp firewall-cmd --reload
这个其实是两行。
firewall-cmd --zone=public --permanent --add-port=8080/tcp
firewall-cmd --reload
4 启动消息服务
Mac 上: docker run -d --name rabbit -p 5672:5672 rabbitmq
5 获得演示代码
Mac 上:
git clone https://github.com/luaxlou/micro-service-practice.git
该项目包含了一个NodeJs 微服务框架的演示代码,其中分两部分。
seneca-listener:微服务
seneca-client: 应用服务
关于seneca的详细介绍,可以看之前的第二篇实践:
docker+jenkins+seneca构建去集中化微服务架构
6 安装Rsync服务
在所有的宿主机上安装Rsync服务,关于服务的安装,可以看下面这篇文章:
http://www.cnblogs.com/zhangeamon/p/5724910.html
记得关闭所有的selinux。
7 开始配置自动集成
原理介绍
好了,所有必要的物件都准备完毕,现在把他们串联起来。
我先讲讲整个机制:
- 工作站提交代码到github
- github通过配置的webhook通知到jenkins服务器
- jenkins发起构建任务:克隆最新的代码,npm 安装扩展,Rsync同步代码到宿主机。
- 第一次部署:宿主机通过代码目录(/var/www)的docker-compose up,启动Docker 实例,Docker实例内部使用PM2管理node进程,并开启代码监听。
- 再次部署:不需要再docker-compose up,Rsync 同步最新的代码到宿主机代码目录,Docker 实例中的PM2监听到代码的变化,重启了node进程。代码更新到最新。
至此,完整的流程走完。
配置jenkins
开始登入我们的Jenkins 虚拟机:
安装必要的工具:git,rsync
进入Jenkins web:http://192.168.226.137:8080/
首先安装NodeJS Plugin,不然NPM安装会不可用。首先安装上插件,重启jenkins。找到jenkins的系统配置,Global Tools Configure,然后 找到NodeJS选项,配置一个可以安装的NodeJS版本。
创建 工作脚本
新建一个自由项目seneca-listener
git 配置:https://github.com/luaxlou/micro-service-practice.git
配置环境勾选上NodeJs
增加构建步骤 Execute Shell:下面是代码
cd seneca-listener
npm install
rsync -avz --password-file=/etc/rsyncd.secrets $WORKSPACE/seneca-listener src@192.168.226.138::srchome
/etc/rsyncd.secrets 是密码文件
rsync 简单说下 src@192.168.226.138::srchome是什么意思
src 是在Rsync服务端设置的账户
srchome 是在Rsync服务端设置的代码目录(/var/www)
详细的服务端配置:
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:
uid = www
gid = www
use chroot = no
read only = no
# max connections = 4
# pid file = /var/run/rsyncd.pid
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
[srchome]
path = /var/www/
comment = hello then
auth users = src
secrets file = /etc/rsyncd.secrets
list=yes
配置完毕,点击开始构建。
创建另一个工作脚本
这次要创建的是应用服务:seneca-client
新建seneca-client 选择从seneca-listener克隆。
更改下构建步骤就可以:
cd seneca-client
npm install
rsync -avz --password-file=/etc/rsyncd.secrets $WORKSPACE/seneca-client src@192.168.226.139::srchome
点击开始构建
8 测试执行
进入 192.168.226.138,微服务宿主机:
cd /var/www/seneca-listener
docker-compose up -d
[root@localhost seneca-client]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c35623a763f senecalistener_agent "pm2-docker proces..." 4 hours ago Up 4 hours senecalistener_agent_1
顺利启动
进入 192.168.226.139,应用服务宿主机:
cd /var/www/seneca-listener
docker-compose up -d
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b23f3b32f71 senecaclient_client "pm2-docker proces..." 4 hours ago Up 6 seconds senecaclient_client_1
同样顺利启动
我们可以看下是否顺利工作:
[root@localhost seneca-client]# docker attach senecaclient_client_1
0|seneca-c | { id: 71,
0|seneca-c | message: 'Hello World!',
0|seneca-c | from: { pid: 22, file: 'index.js' },
0|seneca-c | now: 1507823144963 }
1|seneca-c | { id: 48,
1|seneca-c | message: 'Hello World!',
1|seneca-c | from: { pid: 28, file: 'index.js' },
1|seneca-c | now: 1507823145039 }
可以看到应用服务已经顺利启动,并且得到了微服务的反馈。
先别退出这个终端,我们下面来个测试
9 看看CI是否工作
我们开始更改seneca-client下随便一处的代码,然后提交,为方便测试(可以fork我的项目)。
然后提交。
jenkins 开始构建(webhook的配置略,网上搜下很多)。
构建完毕后,我们看到senecaclient_client_1实例有些变化:
可以看到PM2监听到变化,自动重启了node进程,而没有重启docker实例。
总结
至此,对于Docker微服务的探索阶段已经结束。后面就是一些细化的工作,比如安全性加固,监控,服务健康数据收集等。
这篇算是Docker微服务收关之作吧,如果需要交流,可以加我,知无不言。已经有很多年没有正儿八经写过文章了,文笔已经大不如前,劲量写得不那么晦涩。
非常感谢简书这么照顾,上一篇文章直接给推荐到首页了,好久没感受到这样的荣誉了。
因为失业的缘故,时间有一大把,可以把一些未完的研究做完。接下去还是会继续写下去,有些东西之前一直停留在脑子里,还需要沉淀下。
福兮祸之所伏,祸兮福之所倚。
收工,睡觉。
网友评论