博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
持续交付系列(一):使用Docker、Mesos实现持续交付
阅读量:5877 次
发布时间:2019-06-19

本文共 5371 字,大约阅读时间需要 17 分钟。

本文讲的是持续交付系列(一):使用Docker、Mesos实现持续交付
【编者的话】本文主要讲述如何为Node.js应用搭建持续集成环境。包括如何在开发机器上Docker化一个Node.js应用,如何部署Jenkins和Docker registry以实现持续集成。推荐对使用Docker做CI方面的工作感兴趣的同学阅读,CI也是Docker的应用场景之一,本文是很好的教程。

你首先需要在你的Linux机器上安装Docker和Fig。本文主要会介绍如何使用Docker和Mesos实现持续集成。


测试、搭建生产环境可用的Mesos集群以及其它的复杂工作不在本文讨论范围之内,我会在后续文章中详细介绍。接下来,我们将在更多的云平台上支持该解决方案,比如GCE、AWS,并逐渐集成更多的第三方组件,比如


本文所有的代码都可以在
上找到。


整个解决方案中,我们使用到如下工具:

  • Node.js里的HelloWorld项目
  • Git
  • Jenkins
  • Docker
  • Docker Registry
  • Fig
  • Mesos
  • Mesosphere Marathon
  • Zookeeper

开发环境

让我们先从一个简单的HelloWorld先用开始吧,它使用Node.js编写,并且运行在Docker容器中。


从下图中,你可以看到开发人员在本地环境中使用容器运行构建、测试以及其它流程,如下图淡蓝色方块所示。一旦测试通过,他们将会把代码提交到中央Git仓库,接下来会发布到生产环境。


我假定阅读这篇文章的读者都能理解并且自己实现这一步。


首先是Node.js应用app.js:

// Load the http module to create an http server.var http = require('http');// Configure our HTTP server to respond with Hello World to all requests.var server = http.createServer(function (request, response) {response.writeHead(200, {"Content-Type": "text/plain"});response.end("Hello World\n");});// Listen on port 8000, IP defaults to "0.0.0.0"server.listen(8000);// Put a friendly message on the terminalconsole.log("Server running at http://127.0.0.1:8000/");

对应的配置文件package.json:

{"name": "hello-world","description": "hello world","version": "0.0.1","private": true,"dependencies": {"express": "3.x"},"scripts": {"start": "node app.js"}}

上面两步完成之后,可以使用
来Docker化该应用,并且添加如下
Dockerfile

FROM google/nodejsWORKDIR /appADD package.json /app/RUN npm installADD . /appEXPOSE 8000CMD []ENTRYPOINT ["/nodejs/bin/npm", "start"]

开发环境准备好了。现在我们可以构建容器,并确认镜像是否可以正常运行。

$ docker build -t my_nodejs_image .$ docker run -p 8000:8000 my_nodejs_image

现在可以访问
http://127.0.0.1:8000/
,看看是否可以看到“Hello World”!


你可以修改app.js以让它显示其它的字符串。只需要重新构建镜像,然后启动一个新的容器,刷新浏览器,就能够看到这个新的字符串。


这里的配置没有任何测试。并不是因为觉得不需要,而是为了简化配置,将注意力放在Docker和Mesos/Marathon上。优秀的程序员都应该知道没有测试的话,开发项目就不能直接上生产环境。


现在进入下一步。

持续集成/交付


我们需要有一个版本控制系统和构建服务器,以在代码提交后运行构建和测试。为此,我们使用了Jenkins,并将构建结果(artefact)发布到仓库。因为我们使用Docker部署,所最终的artefact就是一个Docker镜像,push也是push到本地Docker Registry上。


为了简化复杂度,我并没有使用Git仓库管理工具,比如GitLab或者GitHub。将Jenkins连接到Git服务器很简单,这里不再赘述。如果想要在Docker上部署Git服务器,可以使用这个


现在,让我们开始编写
fig.yml
吧。Fig是一个编排工具,我们使用一个命令就可以将所有中心化的服务部署好。
只是个开发工具,如果想要在生产环境使用,需要用更复杂的自动化工具替代它。


几天之前,Docker发布了Docker Compose的第一个版本,它可以代替Fig。我还没有测试它,不过应该不需要什么改变,Docker Compose就可以代替Fig了。


如下是搭建本地Docker Registry的
fig.yml

registry:image: registryenvironment:- STORAGE_PATH=/registryvolumes:- registry-stuff:/registryports: - "5000:5000"

这里使用的是标准的Docker Registry镜像,并且将容器外的一个持久存储的卷挂载到上面,因为我们需要重启容器后还能保留构建出的镜像。


接下来运行:

$ fig up

Docker Registry运行在
http://localhost:5000


下一步是构建镜像并将其push到Registry上。

# Build an image$ docker build -t localhost:5000/containersol/nodejs_app# Push it to the registry$ docker push localhost:5000/containersol/nodejs_app

这时Docker Daemon会报如下错误:

Forbidden. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add –insecure-registry 10.0.0.26:5000 to the daemon’s arguments. 

解决这个问题的方法见

最快最简单的方法是将如下行添加到
/etc/default/docker
,然后重启Docker Daemon:

DOCKER_OPTS="--insecure-registry localhost:5000"

解决问题之后,将镜像push到repo上,并访问该
,检查镜像是否已经被成功push。


接下来添加Jenkins的配置到
fig.yml
文件里,重启系统:

jenkins:image: containersol/jenkins_with_dockervolumes:- jenkins-stuff:/var/jenkins_home- .:/var/jenkins_data- /var/run/docker.sock:/var/run/docker.sock- /usr/bin/docker:/usr/bin/dockerports: - "8081:8080"registry:image: registryenvironment:- STORAGE_PATH=/registryvolumes:- registry-stuff:/registryports: - "5000:5000"

这里详细解释下Jenkins配置。首先,我们在Jenkins容器里挂载了Docker二进制文件(译者注:如上的/usr/bin/docker)和docker daemon使用的socket。这是因为需要从容器里允许Jenkins在主机上运行Docker命令。问题是,只有Docker组里的用户才有权这么做,而Jenkins容器是Jenkins用户,而不是root用户。因此,我们使用如下Dockerfile构建我们自己的Jenkins镜像:

FROM jenkinsMAINTAINER ContainerSolutionsUSER root#TODO the group ID for docker group on my Ubuntu is 125, therefore I can only run docker commands if I have same group id inside. # Otherwise the socket file is not accessible.RUN groupadd -g 125 docker && usermod -a -G docker jenkins USER jenkins

在Dockerfile的文件夹里运行如下命令构建镜像:

$ docker build -t containersol/jenkins_with_docker .

这并不是很巧妙的解决方案,如果你有更好的方法,一定在本文后留言告诉我。


Fig会为Jenkins容器创建持久化的存储,并将当前目录挂载到容器里。这在之后运行build,push并且deploy脚本时就有用了。


要想完成文本介绍的持续集成,还需要添加一些脚本来构建和push Docker镜像,配置Jenkins来运行它们。


build.sh
包含额外的镜像版本信息。每个Jenkins build会为Docker镜像创建新的标签。需要注意,我并不是说这是版本化的正确方式。这个领域很复杂,可能会在以后专门写文章讨论,但是现在就跳过吧。

#!/bin/bashif [ -z "${1}" ]; thenversion="latest"elseversion="${1}"ficd nodejs_appdocker build -t localhost:5000/containersol/nodejs_app:${version} .cd ..

注意构建出的镜像的名字。它首先包含Registry的URL,然后是镜像全名,然后是标签。

还需要注意的是Jenkins在容器里运行,会使用脚本构建镜像,但是在Jenkins容器里执行的docker命令实际上会运行在主机上,因为之前我们挂载了Docker所使用的socket。


push.sh
会push之前步骤构建出的镜像。使用和之前脚本一样的版本。

#!/bin/bashif [ -z "${1}" ]; thenversion="latest"elseversion="${1}"fidocker push localhost:5000/containersol/nodejs_app:"${version}"

最后一步是用Fig重启整个系统,并且配置Jenkins job运行
build.sh
push.sh
。Jenkins在URL
http://localhost:8081
上运行。

这是一个标准的构建job,执行两个shell命令,build的版本是其输入参数:

./build.sh ${BUILD_ID}./push.sh ${BUILD_ID}


现在我们可以执行构建,可以看到新的镜像部署到了Registry里。注意URL包含新的标签。


本文作为该系列的第一篇,讲述了如何在开发机器上Docker化一个Node.js应用,并且如何为了Node.js应用部署Jenkins和Docker Registry。


会接着介绍Mesos和Marathon的搭建,以及如何完成持续集成工作流。


原文链接:(翻译:崔婧雯 校对:郭蕾)
 


===========================

译者介绍

崔婧雯,现就职于VMware,高级软件工程师,负责桌面虚拟化产品的质量保证工作。曾在IBM WebSphere业务流程管理软件担任多年系统测试工作。对虚拟化,中间件技术有浓厚的兴趣。
原文发布时间为:2015-03-11
本文作者:崔婧雯
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:持续交付系列(一):使用Docker、Mesos实现持续交付

转载地址:http://pyuix.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
数据结构之树和二叉树(二)
查看>>
zabbix 3.2 监控Windows 实时内存使用率与CPU使用率
查看>>
oracle 11g常用命令
查看>>
MAVEN指南-5、常用插件解析
查看>>
PDFOA文件格式转换器,给你繁忙的工作降降温
查看>>
Spring MVC 获取静态资源处理方案学习总结
查看>>
我的友情链接
查看>>
xgboost 安装失败
查看>>
LIN总线概要
查看>>
消息模式Toast.makeText的几种常见用法
查看>>
Infobright高性能数据仓库特点
查看>>
通知栏Notification在不同手机上显示的问题总结
查看>>
bootstrap下拉菜单
查看>>
zabbix3.0.4设置邮件告警
查看>>
十六进制转化为ASCII码引起的的进制的故事
查看>>
Java网络编程从入门到精通(1):使用InetAddress类的getHostName方法获得域名
查看>>
event.keycode值大全
查看>>