第 4 章:持续交付

持续交付是现代软件开发的基石,通过自动化构建、测试和部署流程,开发者能够快速迭代并持续交付高质量软件。本章将系统介绍 Docker、Wercker 等工具在持续集成与交付中的应用实践。

引言

编写软件是一项需要多年积累的工艺。许多开发者曾误以为代码行数越多,质量越高。随着经验增长,我们逐渐认识到,代码行数与应用质量并无直接关系,真正重要的是对软件的信心——即在部署前确信其能按预期运行。持续交付的核心在于通过自动化和频繁发布来建立这种信心。

本章将围绕持续集成与持续交付展开,主要内容包括:

  • Docker 与 Docker Hub 的介绍及应用
  • Wercker 持续集成工具实践
  • 每次 Git 提交自动构建项目
  • 构建工件自动部署至目标环境

Docker 介绍

Docker 利用 Linux 内核的 cgroups 和命名空间等功能,实现容器级资源隔离,无需完整虚拟机。近年来,Docker 在各行业广泛应用,成为云原生开发的重要工具。

为什么要使用 Docker

Docker 能帮助我们创建可移植、固定版本的软件镜像,只需安装 Docker 即可在任何环境运行,无需关心依赖和配置。例如,将服务镜像发布到 Docker Hub 后,任何安装了 Docker 的用户都能直接运行服务,极大简化了部署流程。

更多 Docker 相关知识可参考 Karl Matthias 和 Sean P. Kane 的《Docker Up and Running》。

持续集成工具可直接将镜像发布到 Docker Hub,实现云端自动化构建与部署,无需本地安装繁琐基础设施。

安装 Docker

在 Mac 上推荐使用 Docker Toolbox 或原生 Docker 应用。Boot2Docker 已弃用,不建议使用。详细安装步骤请参考 Docker 官方文档

如使用 Homebrew,可手动安装 Docker、Docker Machine 和 VirtualBox。启动 Docker Machine:

docker-machine start default

配置环境变量:

eval "$(docker-machine env default)"

此后即可在终端运行 Docker 命令,如 docker images 查看本地镜像。

运行 Docker 镜像

可直接从 Docker Hub 拉取并运行镜像。例如,启动“helloworld”Web 服务:

docker run -p 8080:8080 cloudnativego/book-hello
# [negroni] listening on :8080

通过 Docker 机器的 IP 访问服务:

curl http://192.168.99.100:8080
# Hello from Go!

如需清理磁盘空间,可删除所有容器和镜像:

docker rm $(docker ps -a -q)
docker rmi $(docker images -q)

持续集成与 Wercker 实践

持续集成(CI)是现代开发流程的核心。常见工具有 Jenkins、TeamCity、Concourse 等,本章重点介绍 Wercker。

持续集成最佳实践

持续集成应遵循以下准则:

  • 维护代码仓库(如 GitHub)
  • 自动化构建流程
  • 构建自带测试,确保质量
  • 每天向主库提交代码,频繁发布
  • 每次提交自动执行构建和测试
  • 保持构建速度,避免流程冗长
  • 在生产克隆环境中测试
  • 交付成果易于获取(如 Docker Hub)
  • 构建结果可见,及时处理失败
  • 自动部署,减少人为错误

为什么选择 Wercker

Wercker 优势:

  • 云端构建,无需本地安装复杂服务
  • 免费使用,无需信用卡
  • 配置简单,易于上手
  • 只需三步即可搭建 CI 环境:创建应用、添加 wercker.yml、配置部署目标

创建 Wercker 应用程序

注册 Wercker 账户(推荐使用 GitHub 登录),创建应用并关联代码仓库。Wercker 会自动生成 wercker.yml 文件,但建议根据实际需求自定义配置。

在 Wercker 中创建应用程序
在 Wercker 中创建应用程序
Wercker 应用程序列表
Wercker 应用程序列表

安装 Wercker CLI

本地构建需安装 Wercker CLI,具体安装方法见 Wercker CLI 文档 。安装完成后可通过以下命令验证版本:

wercker version

如需更新,按提示操作或手动下载最新版。

创建 Wercker 配置文件

Wercker 配置文件为 YAML 格式,包含 dev、build、deploy 三大管道。示例:

box: golang

dev:
  steps:
    - setup-go-workspace:
        package-dir: github.com/cloudnativego/hello
    - script:
        name: env
        code: env
    - script:
        name: go get
        code: |
          cd $WERCKER_SOURCE_DIR
          go version
          go get -u github.com/Masterminds/glide
          export PATH=$WERCKER_SOURCE_DIR/bin:$PATH
          glide install
    - internal/watch:
        code: go run main.go
        reload: true

build:
  steps:
    - setup-go-workspace:
        package-dir: github.com/cloudnativego/hello
    - script:
        name: env
        code: env
    - script:
        name: go get
        code: |
          cd $WERCKER_SOURCE_DIR
          go version
          go get -u github.com/Masterminds/glide
          export PATH=$WERCKER_SOURCE_DIR/bin:$PATH
          glide install
    - script:
        name: go build
        code: |
          go build
    - script:
        name: go test
        code: |
          go test -v $(glide novendor)
    - script:
        name: copy files to wercker output
        code: |
          cp -R ./ ${WERCKER_OUTPUT_DIR}

deploy:
  steps:
    - internal/docker-push:
        username: $DOCKER_USERNAME
        password: $DOCKER_PASSWORD
        cmd: /pipeline/source/hello
        port: "8080"
        tag: latest
        repository: cloudnativego/book-hello
        registry: https://registry.hub.docker.com
    - cng/cf-deploy:
        api: $API
        user: $USER
        password: $PASSWORD
        org: $ORG
        space: $SPACE
        appname: wercker-step-hello
        docker_image: cloudnativego/book-hello

配置文件需注意缩进和格式,可使用 YAML 验证工具 检查。

使用 Wercker 构建与部署

Wercker 构建可通过代码提交自动触发,也可本地运行:

rm -rf _builds _steps _projects
wercker build --git-domain github.com --git-owner cloudnativego --git-repository gogo-service
rm -rf _builds _steps _projects

构建输出示例:

--> Executing pipeline
--> Running step: setup environment
Pulling from library/golang: latest
...
Ok github.com/cloudnativego/gogo-service 0.005s
--> Steps passed: 17.92s
--> Pipeline finished: 19.03s

部署到 Docker Hub:

deploy:
  steps:
    - internal/docker-push:
        username: $USERNAME
        password: $PASSWORD
        cmd: /pipeline/source/gogo-service
        port: "8080"
        tag: latest
        repository: cloudnativego/gogo-service
        registry: https://registry.hub.docker.com

部署对象的用户名和密码通过 Wercker 网站安全环境变量配置。

Wercker 配置部署对象
Wercker 配置部署对象

读者练习:创建完整的开发管道

建议读者实践以下步骤,搭建自己的持续集成与交付管道:

  • $GOPATH/src/github.com/youraccount/pipeline 创建 Go 应用(包名为 main)
  • 编写 main.go,输出“hello world”
  • 本地运行和构建(go run / go build)
  • 提交代码至 GitHub
  • 在 Wercker 创建新应用,关联 GitHub 仓库
  • 添加 wercker.yml,配置自动化构建与部署
  • 本地使用 Wercker CLI 构建
  • 配置 Docker Hub 部署对象
  • 提交代码,观察 Wercker 构建与 Docker Hub 镜像更新
  • 使用 docker run 从 Docker Hub 镜像运行应用

通过以上步骤,读者将拥有一个自动化、可测试、可持续部署的开发环境,为后续项目开发打下坚实基础。

高级挑战:集成第三方库

进一步挑战:在应用中集成第三方包(如 tablewriter),并使用 Glide 管理依赖。确保 vendor 目录签入,Wercker 本地与云端构建均可正常运行。

总结

本章系统介绍了持续集成与持续交付的核心理念与实践方法,重点讲解了 Docker 与 Wercker 的应用。通过自动化构建、测试和部署,开发者能够快速迭代并持续交付高质量软件。建议读者完成练习,建立属于自己的持续交付管道,为后续云原生开发奠定坚实基础。

参考文献

文章导航

独立页面

这是书籍中的独立页面。

书籍首页

评论区