这是一个关于Vagrant的学习系列,包含如下文章:

  1. Vagrant入门
  2. 创建自己的Vagrant box
  3. 用Vagrant搭建Jenkins构建环境
  4. 用Vagrant和Ansible搭建持续交付平台

随着微服务越来越被行业所接受,与之相关的持续集成和持续交付的作用和价值也更加突显。在本文中,我们将使用Vgrant和Ansible来自动地创建一套持续交付平台——ThoughtWorks的GoCD。如果你对Jenkins比较熟悉,也可以参考笔者另外一篇搭建Jenkins多机构建环境的文章。

我们将创建一台Go Server和两台Go Agent,对于不熟悉GoCD的读者来说,可以将Go Server理解成Jenkins的Master,而将Go Agent理解为Jenkins的Slave。

本文源代码:https://github.com/davenkin/vagrant/tree/master/ansible-go-server-2-agents-ubuntu1404

首先,创建如下Vangrantfile:

  1. GO_SERVER_IP="192.168.3.2"
  2. GO_AGENT1_IP="192.168.3.3"
  3. GO_AGENT2_IP="192.168.3.4"
  4.  
  5. Vagrant.configure("") do |config|
  6. config.vm.box = "ubuntu/trusty64"
  7.  
  8. config.vm.define "server" do |server|
  9. server.vm.hostname = "goserver"
  10. server.vm.network "private_network", ip: GO_SERVER_IP
  11. server.vm.provider "virtualbox" do |v|
  12. v.name = "go-server"
  13. v.memory = 1024
  14. v.cpus = 2
  15. end
  16.  
  17. end
  18.  
  19. config.vm.define "agent1" do |agent1|
  20. agent1.vm.hostname = "goagent1"
  21. agent1.vm.network "private_network", ip: GO_AGENT1_IP
  22. agent1.vm.provider "virtualbox" do |v|
  23. v.name = "go-agent1"
  24. v.memory = 1024
  25. end
  26.  
  27. end
  28.  
  29. config.vm.define "agent2" do |agent2|
  30. agent2.vm.hostname = "goagent2"
  31. agent2.vm.network "private_network", ip: GO_AGENT2_IP
  32. agent2.vm.provider "virtualbox" do |v|
  33. v.name = "go-agent2"
  34. v.memory = 1024
  35. end
  36.  
  37. end
  38.  
  39. config.vm.provision "ansible" do |ansible|
  40. ansible.playbook = "ansible/playbook.yml"
  41. ansible.groups = {
  42. "servers" => ["server"],
  43. "agents" => ["agent[1:2]"],
  44. "agents:vars" => {"goserver_ip" => GO_SERVER_IP}
  45. }
  46. end
  47.  
  48. end

以上,我们创建了3台虚拟机,其中Go Server的IP地址为192.168.3.2,两台Go Agent的IP地址分别为192.168.3.3和192.168.3.4。由于采用了Vagrant的private_network网络方式,这3台虚拟机以及Host机器之间都是相互连通的。在config.vm.provision配置项中,我们指定了所使用的Ansible配置文件ansible/playbook.xml,该文件将同时用于Go Server和Go Agent的provision。最后,我们声明了两个Ansible的group,一个名为servers,包含了Go Server;另一个名为agents,包含两台Go Agent。对于两台Go Agent,我们还定义了变量goserver_ip,该变量将用于配置两台Go Agent,用于指向他们需要连接的Go Server。

然后创建playbook.xml如下:

  1. ---
  2. - hosts: servers
  3. become: true
  4. become_method: sudo
  5. roles:
  6. - role: goserver
  7. - role: git
  8. - hosts: agents
  9. become: true
  10. become_method: sudo
  11. roles:
  12. - role: goagent
  13. - role: git

在该文件中,我们定义了两份playbook,一份用于配置Go Server(上文提到的servers这个group),另一份用于配置Go Agent。可以看出,该playbook本身并没有做什么配置工作,而是对于不同的group使用了不同的Ansible role——goserver、goagent和git。

为了引用这些role,他们需要遵循一定的目录结构,比如需要在playbook.xml所在的目录下创建一个名为roles的目录用于存放所有的role。而每个role又有自身的目录结构,比如对于goserver这个role来说,要执行的task应该放在roles/goserver/tasks/main.yml这个文件中。有关role的目录结构细节请参考Ansible的官方文档

这里我们将以goserver这个role为例讲解Go Server的provision过程。goserver这个role的目录包含以下内容:

  1. ├── handlers
  2. └── main.yml
  3. ├── meta
  4. └── main.yml
  5. └── tasks
  6. └── main.yml

首先在tasks/main.yml中,我们通过apt这个module安装了jdk和go-server:

  1. ---
  2. - name: install jdk
  3. apt: pkg=default-jdk state=present
  4.  
  5. - name: install go sever
  6. apt: pkg=go-server state=present
  7. notify:
  8. - start go server

在安装完成之后,我们还需要保证Go Server是启动的,这个在handlers/main.yml中:

  1. ---
  2. - name: start go server
  3. service: name=go-server state=started

对于Go Server来说,安装过程的最后一步会自动启动Go Server的service,故以上步骤其实省略也可。但是对于Go Agent来说,则不是自动启动的了。

另外,在meta/main.yml文件中,我们声明了goserver依赖于另一个role——apt_update:

  1. ---
  2. dependencies:
  3. - { role: apt_update }

也就是说,在goserver运行之前,apt_update这个role会自动运行,该role主要作用是将apt源从默认的国外转成国内的阿里云,这样在安装软件时速度会更快,另外由于go-server不在阿里云源里,我们还需要手动添加go-server的源。apt_update目录如下:

  1. ├── files
  2.    └── sources.list
  3. └── tasks
  4. └── main.yml

在apt_update/tasks/main.yml文件中,设置阿里云的源和go-server自己的源:

  1. ---
  2. - name: archieve existing sources.list
  3. shell: creates="/etc/apt/sources.list.old" mv /etc/apt/sources.list /etc/apt/sources.list.old
  4.  
  5. - name: copy new sources.list
  6. copy: src=sources.list dest=/etc/apt/
  7.  
  8. - name: add gocd.list
  9. shell: creates="/etc/apt/sources.list.d/gocd.list" echo "deb https://download.go.cd /" | sudo tee /etc/apt/sources.list.d/gocd.list
  10.  
  11. - name: add gocd apt key
  12. shell: curl https://download.go.cd/GOCD-GPG-KEY.asc | sudo apt-key add -
  13.  
  14. - name: update apt cache
  15. apt: update_cache=yes

除了安装Go Server,我们还安装了Git,用于在构建项目时能够顺利从Git服务器(比如Github)下载到项目源代码。

对于两台Go Agent来说,也具有与Go Server相似的过程。

最后,运行vagrant up,我们便可以在Virtualbox中看到这3台虚拟机了:

然后在Host机器上打开http://192.168.3.2:8153/go/pipelines,便可以看到Go Server的页面了:

请注意,此时的两台Go Agent虽然能够正常连接Go Server,但是他们的状态却是disable的,为了正常使用Go Agent来构建项目,你需要先在Go Server中将他们enable。点击页面上方的“AGENTS”,进入agents管理也便可enable/disable所有的agents:

还有个问题,Ansible所需要的inventory在哪里?事实上,Vagrant会基于Vangrantfile自动为我们生成Ansible的inventory文件,并放在与Vgrantfile文件同级的.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory文件中。对于本项目,在笔者的机器上所生成的vagrant_ansible_inventory文件如下:

  1. # Generated by Vagrant
  2.  
  3. agent1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2200 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='/Users/yteng/github/vagrant/ansible-go-server-2-agents-ubuntu1404/.vagrant/machines/agent1/virtualbox/private_key'
  4. agent2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2201 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='/Users/yteng/github/vagrant/ansible-go-server-2-agents-ubuntu1404/.vagrant/machines/agent2/virtualbox/private_key'
  5. server ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='/Users/yteng/github/vagrant/ansible-go-server-2-agents-ubuntu1404/.vagrant/machines/server/virtualbox/private_key'
  6.  
  7. [servers]
  8. server
  9.  
  10. [agents]
  11. agent[1:2]
  12.  
  13. [agents:vars]
  14. goserver_ip=192.168.3.2

用Vagrant和Ansible搭建持续交付平台的更多相关文章

  1. SonarQube+Jenkins,搭建持续交付平台

    前言 Kurt Bittner曾说过,如果敏捷仅仅只是开始,那持续交付就是头条! "If Agile Was the Opening Act, Continuous Delivery is ...

  2. 【云计算】Netflix 开源持续交付平台 Spinnaker

    oschina        发布于: 2015年11月19日 (0评)          分享到:    收藏 +1 CDS首都在线全球云主机.全球私有网络,开工送礼,免费试用! »   日前,Ne ...

  3. TOP100summit 2017:【案例分享】魅族持续交付平台建设实践

    本篇文章内容来自第10期魅族开放日魅族运维架构师林钟洪的现场分享.编辑:Cynthia 一.自动化建设历程1.1 魅族互联网发展的时间线 2003-2008年被称之为“互联网1.0时代”.2003年, ...

  4. 基于Docker持续交付平台建设的实践

    导读:中国五矿和阿里巴巴联手打造的钢铁服务专业平台五阿哥,通过集结阿里巴巴在大数据.电商平台和互联网产品技术上的优势,为终端用户带来一站式采购体验.本文是五阿哥运维技术团队针对Docker容器技术在如 ...

  5. CODING DevOps 系列第一课:基于开源工具链打造持续交付平台

    当下软件发展趋势 当今 IT 行业发展中比较流行的几个技术,首先是微服务化,将原有的一个系统拆分成多个,意味着有多个系统需要构建.测试.部署和运维. 第二个是敏捷开发模式,需求粒度更细化,要求一个可独 ...

  6. 利用ansible来做tomcat应用的持续交付

    https://www.jianshu.com/p/fca8f91ae223 在做持续交付这件事,想必大家都是用jenkins这款程序来做基石.当然,我们这次也是用jenkins作为承载工具,jenk ...

  7. (转)初试 Netflix 开源持续云交付平台 Spinnaker

    目录 Spinnaker 介绍 环境.软件准备 安装 Development Spinnaker 配置依赖环境 配置并安装 Spinnaker 演示 Spinnaker Pipeline 演示 Spi ...

  8. 测试需要了解的技术之基础篇三__持续集成持续交付DevOps

    持续集成.持续交付.DevOps 1.容器技术Docker:容器技术介绍.Docker安装与加速配置.Docker基础命令.Docker搭建selenium.Docker搭建持续集成平台Jenkins ...

  9. 玩转spring boot——结合阿里云持续交付

    前言 在互联网项目中,项目测试.部署往往需要花费大量时间.传统方式是在本地打包.测试完毕程序,然后通过ftp上传至服务器,再把测试的配置文件修改为生产环境的配置文件,最后重新运行服务.这一过程如果交给 ...

随机推荐

  1. java学习之面向对象(3)

    下面来谈谈java编程中的一些语法: 1.什么是对象数组? 对象数组就是数组里的每个元素都是类的对象,赋值时先定义对象,然后将对象直接赋值给数组. 对象数组的声明: 类名[]  对象数组名称  = n ...

  2. MySQL 启动原理剖析

    200 ? "200px" : this.width)!important;} --> 介绍 本篇文章主要从查看MySQL的启动命令的代码来详细了解MySQL的启动过程,内容 ...

  3. Module-Zero之租户管理

    返回<Module Zero学习目录> 开启多租户 租户实体 租户管理者 默认租户 开启多租户 ABP和Module-Zero可以运行多租户或单租户模式.多租户默认是禁用的.我们可以在mo ...

  4. EF Codefirst 多对多关系 操作中间表的 增删改查(CRUD)

    前言 此文章只是为了给新手程序员,和经验不多的程序员,在学习ef和lambada表达式的过程中可能遇到的问题. 本次使用订单表和员工表建立多对多关系. 首先是订单表: public class Ord ...

  5. Atitti 存储引擎支持的国内点与特性attilax总结

    Atitti 存储引擎支持的国内点与特性attilax总结 存储引擎处理的事情: · 并发性:某些应用程序比其他应用程序具有很多的颗粒级锁定要求(如行级锁定). · 事务支持:并非所有的应用程序都需要 ...

  6. 使用angular中ng-repeat , track by的用处

    我们见到最简单的例子是: <div ng-repeat="link in links" ></div> 如果item的值有重复的,比如links=[&quo ...

  7. Sublime Text执行js

    Sublime Text执行js 在Build Sytem添加以下内容: { "cmd": ["node", "$file"], " ...

  8. 回发或回调参数无效。在配置中使用 pages enableEventValidation=true 或在页面中使用 %@ Page EnableEventValidation=true % 启用了事件验证

    WebForm中回发或回调参数无效问题的解决 解决 .NET中回发或回调参数无效问题的解 该错误的详细提示信息为: 回发或回调参数无效.在配置中使用 <pages enableEventVali ...

  9. c#写windows服务

    序言 前段时间做一个数据迁移项目,刚开始用B/S架构做的项目,但B/S要寄存在IIs中,而IIs又不稳定因素,如果重启IIs就要打开页面才能运行项目.有不便之处,就改用Windows服务实现.这篇就总 ...

  10. ExtJS面向对象

    序言 1.ExtJs是一套很好的后台框架.现在很流行的,我们要会. 2.这是我写ExtJs的第一篇,以后会写很多直到把这框架运用的炉火纯青,走火入魔. ExtJs中的命名空间 我是做.net的,这命名 ...