Docker实战:更轻松、更愉快、更高效

本文讲的是Docker实战:更轻松、更愉快、更高效,【编者的话】本文作者(Michael Herman)通过实例展示了Docker在日常开发中的潜力,并不需要花费太多精力,就可以建立一套高效、简洁的流程,包括了项目自动化的测试、持续集成及部署,将开发者从这些令人厌倦的体力劳动中解放出来,同时为我们了解Docker提供了直观的经验。

借助Docker,我们可以更容易地进行Web应用部署,而同时不必头疼于项目依赖、环境变量以及各种配置问题,Docker可以快捷、高效地处理好这一切。

而这也是本教程的目标。

首先我们来学习使用Docker容器运行一个Python Flask应用,然后逐步介绍一套更酷的开发流程,其中涵盖了应用的持续集成与发布........

我(Michael Herman)最初是在2015年2月8日的PyTennessee上介绍了这一工作流程,如果感兴趣的话,你可以直接浏览我当时使用的幻灯片

流程

1. 在本地功能分支上完成应用代码。
2. 在GitHub上发起一个到master分支的Pull Request。
3. 在Docker容器上运行自动测试。
4. 如果测试通过,手动将这个PR merge进master分支。
5. 一旦merge成功,再次运行自动测试。
6. 如果第二次测试也通过,就在Docker Hub上对应用进行构建。
7. 一旦构建完成,自动化地部署到生产环境。

本教程基于Mac OS X,在开始前需要保证以下工具已正确安装配置:Python v2.7.9, Flask v0.10.1, Docker v1.5.0, Docker Compose, v1.1.0, boot2docker 1.5.0, Redis v2.8.19

好了,让我们开始吧。

首先来介绍一些Docker中的基本概念:

  • Dockerfile中包括了一系列语句,用于对镜像的行为进行描述。
  • 镜像是一个模板,用来保存环境状态并创建容器。
  • 容器可以理解为实例化的镜像,并会在其中运行一系列进程。

如果对Dockerfile镜像容器的具体细节感兴趣,那么可以从Docker的官方文档获取更多详细信息。

为什么是Docker?

使用Docker意味着你能在开发机上完美地模拟生产环境,而不用再为任何由两者环境、配置差异所造成的问题而担心,除此之外Docker带给我们的还有:

  1. 良好的版本控制。
  2. 随时便捷地发布/重建整个开发环境。
  3. 一次构建,随处运行,就是这么神奇!

配置Docker

由于Darwin(OS X内核)缺少运行Docker容器的一些Linux内核功能,所以我们需要借助boot2docker,一个用于运行Docker的轻量级Linux发行版(启动一个专门为运行Docker定制过的小型虚拟机)。

首先为我们的Flask项目创建一个名为“fitter-happier-docker”的目录。

接下来遵照官方文档的步骤来完成Docker和boot2docker的安装。

我们可以通过以下命令来验证安装是否正确:

$ boot2docker version
Boot2Docker-cli version: v1.5.0
Git commit: ccd9032

Compose Up!

Docker Compose是官方提供的容器业务流程框架(译者注:曾经的项目名称是Fig,甚至在本译文的初稿时依然是,进化速度之快可见一斑),只需通过简单的.yml配置文件,就能完成多个容器服务的构建和运行。

使用pip来安装Docker Compose,并通过如下命令来确认安装正确:

$ pip install docker-compose
$ docker-compose --version
docker-compose 1.1.0

现在来启动我们的Flask+Redis应用(你可以从这个repo来获取项目的全部源代码),首先在项目根目录下新建docker-compose.yml文件:

web:
build: web
volumes:
    - web:/code
ports:
    - "80:5000"
links:
    - redis
command: python app.py
redis:
image: redis:2.8.19
ports:
    - "6379:6379"

可以看到我们对项目所含两个服务进行的操作:

  • web:我们将在web目录下进行容器的构建,并且将其作为Volume挂载到容器的/code目录中,然后通过python app.py来启动Flask应用。最后将容器的5000端口暴露出来,并将其映射到主机的80端口上。
  • redis:我们直接使用Docker Hub上的官方镜像来提供所需的Redis服务支持,将6379端口暴露并映射到主机上。

你一定注意到了位于web目录下的Dockerfile文件,它用于指导Docker如何构建我们的应用镜像(基于Ubuntu),并且保证了完备的依赖支持。

构建并运行

接下来只需要一行简单命令,就能轻松搞定一切(镜像的构建及容器的启动运行):

Ubuntu

$ docker-compose up

这会根据Dockerfile来构建Flask应用的镜像,从官方仓库拉取Redis镜像,然后将一切运行起来。

现在你可以去喝一杯咖啡,呃,也许是两杯:首次运行会花费相对较长的时间,事实上Docker会在构建过程中,将Dockerfile中的每一步操作(更正式的说法应该是layer)缓存下来,以后的构建过程会因此提速很多,因为只有发生改变的步骤才会被重新执行。

Docker Compose会并行地启动全部容器,每个容器都会被分配各自的名字,并且会为日志设置可读性更高的配色方案。

好了,那么准备好来测试了吗?

打开你的浏览器,输入主机DOCKER_HOST环境变量所对应的IP地址,例如在我这里是 http://192.168.59.103/(运行boot2docker ip命令可以查询到IP地址)。

接下来你应该会在浏览器中看到以下文本“Hello! This page has been seen 1 times.”: 

刷新页面,如果一切正常的话,计数器变量应该会进行累加。

通过Ctrl-C来终止我们的应用进程,然后通过以下命令让其改为在后台运行:

$ docker-compose up -d

想查看应用进程的运行状态?只需要输入以下命令就可以了:

$ docker-compose ps

Name                          Command             State              Ports
——————————————————————————————————————————————
fitterhappierdocker_redis_1     /entrypoint.sh redis-server   Up      0.0.0.0:6379->6379/tcp
fitterhappierdocker_web_1       python app.py                 Up      0.0.0.0:80->5000/tcp, 80/tcp

可以看到我们的两个进程运行在不同的容器中,而Docker Compose将它们组织在一起!

更进一步

在确定一切正常无误后,使用docker-compose stop命令来终止我们的应用,然后通过boot2docker down来安全地关闭虚拟机。接下来就可以向Git提交本地修改,并推送到GitHub了。

那么,我们刚才都完成了什么呢?

我们建立了本地环境,通过Dockerfile详尽描述了如何构建镜像,并基于该镜像启动了相应容器。我们使用Docker Compose来将这一切整合起来,包括构建和容器之间的关联、通信(在Flask和Redis进程之间)。

接下来,我们来看一个更酷的工作流程,即通过引入CircleCI来实现项目的持续集成。

同样的,你可以从此处获取源代码。

Docker Hub

到目前为止我们已经接触过Dockerfile、镜像以及容器(当然,借助了Docker Compose的帮助)。

如果你很熟悉Git的工作流程,那么可以把Docker镜像理解为Git的repo,而容器类似于该repo的clone,如果将这个比喻继续类推下去,那么Docker Hub也就相当于GitHub的地位了。

  • 为了使用Docker Hub,你可以用GitHub账号来完成注册
  • 添加一个新的自动构建,将刚才完成的项目repo加入进来,一切按照默认选项即可,除了将“Dockerfile Location”改为“/web”。

一旦添加完毕,Docker Hub会进行一次初始化构建,请确保一切正常。

Docker Hub和CI

Docker Hub自身通过配置就可以充当持续集成服务,从而在每次推送Git提交后自动进行构建。

这意味着你不能直接将镜像推送到(通过docker push)Docker Hub上。Docker Hub会自己从repo进行拉取并构建镜像,从而保证整个过程中没有错误。在你的工作流程中请铭记这一点,因为在Docker文档中目前并没有对此进行详细说明。

让我们来试一下,加入以下测试用例:

self.assertNotEqual(four, 5)

提交并推送到GitHub,然后就可以看到Docker Hub如何开始一次新构建了。

由于这是项目部署上线前的最后一道防线,我们当然希望Docker Hub在构建完成之前,能够捕获所有的错误和异常。另外,你肯定也希望能将自己的单元测试和集成测试加入到持续集成流程中, 而这正是CircleCI的用武之地。

CircleCI

CircleCI是一个持续集成/发布平台,支持对Docker容器进行测试。你只需提供一个Dockerfile,CircleCI会据此构建镜像,并启动一个新容器,然后在其中运行你的测试。

还记得我们期望的工作流程吗?链接

现在来看看如何完成它。

安装

CIrcleCI官方提供了很好的入门指导

使用GitHub账号完成注册,然后将你的GitHub repo添加为一个新项目(成功后会收到邮件通知)。这会为该repo增加一个hook,每当你向其推送新的提交时,都会触发一次新的构建。

接下来需要向我们的repo添加一个配置文件,用以指导CircleCI完成构建。

circle.yml的文件内容如下:

machine:
services:
- docker

dependencies:
override:
- pip install -r requirements.txt

test:
override:
- docker-compose run -d --no-deps web
- python web/tests.py

实际上,我们构建了一个新的镜像,并启动了一个新容器,然后进行测试:首先检查web应用是否正常启动运行,然后逐一进行单元测试。

你应该已经注意到我们在这里使用了命令docker-compose run -d --no-deps web而不是docker-compose up来启动应用,这是因为CircleCI已经集成了可用的Redis运行时环境,所以我们只需启动web应用进程就可以了。

当circle.yml文件修改完成,就可以推送到GitHub来启动一次新构建了。记住,这将同时在Docker Hub上启动一次构建。

一切正常?

在继续下去之前,需要对工作流程进行一些调整,因为我们通常不希望将提交直接推送到master分支上。

功能分支工作流程

>如果不太熟悉这一工作流程,那么可以从此处获得准确生动的解释。

让我们来快速浏览一个示例:

创建功能分支

$ git checkout -b circle-test master
Switched to a new branch 'circle-test'

更新应用

在texts.py里增加一个新的断言:

self.assertNotEqual(four, 6)

发起一个Pull Request

$ git add web/tests.py
$ git commit -m "circle-test"
$ git push origin circle-test

甚至在你真正发起PR之前,CircleCI就已经启动了构建。在PR创建完毕后,只需等待CircleCI通过所有测试,我们就可以点击Merge按钮来合并入master分支了。一旦merge成功,Docker Hub就会触发相应的构建过程。

重构工作流程

如果回到本文开头的工作流程处,你会发现我们实际上希望Docker Hub在master分支上再次进行测试后才启动构建,所以让我们来对现有流程进行以一些快速的调整:

打开你的Docker Hub仓库,在Settings下选择Automated Build。
取消对“When active we will build when new pushes occur”的选中状态。

  1. 保存。
  2. 选择位于Settings下的Build Triggers。
  3. 将status改为on。
  4. 复制以下curl命令:$ curl --data "build=true" -X POST https://registry.hub.docker.co ... 3b66/

将以下代码加入到circle.yml文件末尾:

deployment:
hub:
branch: master
commands:
  - $DEPLOY

现在我们会在merge到master分支并通过测试之后,执行$DEPLOY环境变量所代表的命令,我们需要将这个变量的值加入到CircleCi的环境变量中:

  • 打开 Project Settings,选择 Environment variables。
  • 添加一个名为“Deploy”的新变量,并且将刚才复制的curl命令粘贴进去作为该变量的值。

现在来检验一下成果:

$ git add circle.yml
$ git commit -m "circle-test"
$ git push origin circle-test

发起一个新的PR,一旦其通过CirecleCI测试,将其merge到master分支,这会触发另一次构建。一旦再次通过测试,之前设置的curl命令就会触发Docker Hub去启动一次新构建,一切都很完美。

结论

我们已经跑通了这个基于CircleCI的持续集成工作流程(步骤1-6):

  1. 在本地功能分支上完成应用代码。
  2. 在GitHub上发起一个到master分支的Pull Request。
  3. 在Docker容器上运行自动测试。
  4. 如果测试通过,手动将这个PR merge进master分支。
  5. 一旦merge成功,再次运行自动测试。
  6. 如果第二次测试也通过,就在Docker Hub上对应用进行构建。
  7. 一旦构建完成,自动化地部署到生产环境。

关于整个流程的最后一块拼图呢:及自动化地将应用发布到盛传环境(第7步),你可以在我的另一篇博客中得到答案。

原文链接:Docker in Action - Fitter, Happier, More Productive(翻译:李明 校对:宋瑜)

===========================
译者介绍
李明(微信:hydRAnger; 邮箱:armyiljfe@gmail.com; GitHub: https://github.com/hydRAnger ),云栈科技前端程序猿,本科、硕士皆为生物科学方向,出于热情转投IT领域,做过游戏开发,兴趣广泛以致杂而不精,还需精进,欢迎交流、指导。目前关注于web相关技术、Docker、开源软硬件等领域。

原文发布时间为:2015-03-02

本文作者:hydRAnger

本文来自合作伙伴DockerOne,了解相关信息可以关注DockerOne。

原文标题:Docker实战:更轻松、更愉快、更高效

时间: 2024-10-28 19:10:10

Docker实战:更轻松、更愉快、更高效的相关文章

优云软件老司机:如何让运维操作更轻松、高效

讲师介绍 庞辉富 •广通软件技术总监 •拥有10多年IT运维管理软件研发经验 •致力于自动化运维解决方案的研究和推广 •主导研发的产品广泛应用于海关.公安.能源等多个行业 技术发展给运维带来的挑战 当前的IT建设在这些新技术的演进下,我们看到的是呈现"双态IT"特征.Gartner也提出双模IT理论,与现在谈的双态IT是异曲同工的,不再是一种单纯的形态,而是两种形态交集在一起. 一种是稳态,也是我们经常说的核心业务,比如银行的核心业务.政府的核心业务等,业务系统一般以传统IOE或VCE

不做IT民工 网站优化善于结合工具更轻松

每当听到别人问起网站优化是做什么的?轻不轻松?有没有前途之类的问题时,笔者也不知道怎么去回答,如果从站长的角度去答的话,网站优化就是IT民工,IT民工肯定不会轻松的,前途也是有的,但是更多的则是给互联网制造垃圾,推广广告满天飞.很多人看到网站优化不就是发发外链.更新内容就能赚钱了.其实这只是外行人的看法而已,在站长界里,网站优化其实跟IT民工一样,每天早起晚睡的就为了发外链,有的甚至是每天对着电脑工作个十几小时的站长大有人在.是不是天天呆在电脑前时间越长,网站优化才会有效果,排名才会好呢?笔者告

无线路由器猫三合一让Wi-Fi冲浪更轻松

相信随着无线技术的发展和普及,越来越多的无线产品进入到了寻常百姓家.很多读者都在自己家中建立了WiFi无线网络.不过你是否觉得传统的无线网络搭建非常麻烦呢?要知道以前我们要购买ADSL猫,无线路由器等等多个设置并顺利连接才能实施无线局域网.然而现在不必这么麻烦了,我们可以通过三合一产品让WiFi冲浪更轻松. 一.传统的无线WiFi设备连接方式: 如果家中是采用ADSL方式进行宽带接入的话,首先我们需要一根电话线,然后将这个电话线连接到专用的ADSL调制解调器MODEM的LINE接口,接下来通过R

如何将应用程序更轻松地迁移到WebSphere Application Server

Donald Vines & Andy Hoyt: Application Migration 工具如何将应用程序更轻松地迁移到 WebSphere Application Server 使应用程序分析和迁移更轻松 IBM WebSphere Application Server Migration Toolkit 的 Application Migration 工具能帮助您轻松地将应用程序从一个源应用服务器迁移到 WebSphere Application Server V7.0 上.源应用服

妙用Win7按时自动执行任务让你更轻松

如果你在xp系统的时候就会使用系统的任务计划功能,那么你到了win7系统你就会感觉到,win7系统对应的功能强大了很多,也人性化了很多. 1 win7任务计划功能比xp系统强大的地方 win7系统对任务计划程序界面功能更为完善,设有任务摘要.任务状态.操作功能菜单等,并可以执行连接另一台计算机.创建任务.导入任务等功能. 2 使用方法很简单,有每天定时开启功能如图: 3 要启动的程序也没什么现在,可以是脚本.软件之类的. 4 其他相关的功能非常多,也非常齐全,在这边就不解释了,基本上自己用下都能

5款App让你的数字生活更轻松

Google是市场上最强大的云工具之一.不管你是把它用于个人的事情.学校.企业还是休闲度假,都有大量的应用提供给你.这些应用中有些(例如文档.日历和Gmail)都是被人们广泛使用并且众所周知的.然而,也有其他一些Google应用是你可能还没有涉足过的--这些应用可以让你的生活变得更轻松.这些应用也许稍微任职,但是并不意味着功能较差.下面就让我来给你介绍这样五款应用,你可以把它们集成到你免费的Google账户中. 1.Forms Forms(如图A)可以让你轻而易举地创建各种调查,并把调查发送给你

微容器:更小的,更轻便的Docker容器

本文讲的是微容器:更小的,更轻便的Docker容器,[编者的话]本文介绍了微容器的概念和好处,并用一些例子介绍了如何构建微镜像,从scratch到Alpine Linux,并推荐了一些已有的基础微镜像,方便为几乎所有主流语言的应用构建微镜像.本文也指出了构建微镜像的基本原理:将构建时依赖和运行时依赖分开,构建时所用的镜像包含所有构建所用的工具,它可以比较大,但运行时的基础镜像应该仅包含运行时依赖.使用微容器,no going back! Docker 使你能把你的应用和应用的依赖打包到一个良好的

微软试图让Win32开发者能够更轻松地得到桌面桥(Desktop Bridge)

微软正在采取方法让更多的Win32和.NET开发者能够将他们的应用程序带到Windows 10应用程序商店之中. 微软试图让Win32开发者能够更轻松地得到桌面桥 在9月14日,微软宣布它将在Windows应用商店中推出Desktop App Converter(代码代号为"Project Centennial")供直接下载.微软计划通过应用程序商店为Desktop App Converter推出新功能和补丁. 微软正在与Flexera Software就InstallShield进行

Docker容器:更小不一定更好

本文讲的是Docker容器:更小不一定更好,[编者的话]按正常逻辑来说,我们应该选择体积较小的Docker容器.然而事实是,体积小却并不一定能带来性能上的优势.本文将介绍一个使用了一个体积稍大一点的容器,从而将性能提高30倍以上的例子. 按道理来说,我们应该选择体积较小的Docker容器.然而事实是,体积小却并不一定能带来性能上的优势.本文将介绍一个使用了一个体积稍大一点的容器,从而将性能提高30倍以上的例子. 摘要 当使用grep来处理大量的数据的时候,busybox中带的grep速度慢的让人