使用 Jenkins + Ansible 实现自动化部署 Nginx
本文首发于:Jenkins 中文社区
本文介绍如何使用 Jenkins + Ansible 实现对 Nginx 的自动化部署。最终达到的效果有如下几点:
- 只要你将 Nginx 的配置推送到 GitHub 中,Jenkins 就会自动执行部署,然后目标服务器的 Nginx 配置自动生效。这个过程是幂等(idempotent)的,只要代码不变,执行多少遍,最终效果不变。
- 如果目标机器没有安装 Nginx,则会自动安装 Nginx。
- 自动设置服务器防火墙规则。
1. 实验环境介绍
本次实验使用 Docker Compose 搭建 Jenkins 及 Jenkins agent。使用 Vagrant 启动一台虚拟机,用于部署 Nginx。使用 Vagrant 是可选的,读者可以使用 VirtualBox 启动一个虚拟机。使用 Vagrant 完全是为了自动化搭建实验环境。
以下是整个实验环境的架构图:
注意,图中的 5123 <-> 80
代表将宿主机的 5123 端口请求转发到虚拟机中的 80 端口。
- Vagrant:虚拟机管理工具,通过它,我们可以使用文本来定义、管理虚拟机。
- Ansible:自动化运维工具
- Docker Compose:它是一个用于定义和运行多容器 Docker 应用程序的工具。可以使用 YAML 文件来配置应用程序的服务。
2. 启动实验环境
-
克隆代码并进入文件夹
git clone https://github.com/zacker330/jenkins-ansible-nginx.git cd jenkins-ansible-nginx
-
构建 Jenkins agent 的镜像 需要自定义 Jenkins agent 镜像有两个原因:
- 本次实验,使用 Swarm 插件实现 Jenkins master 与 agent 之间的通信,所以 Jenkins agent 需要启动 swarm 客户端。
- Jenkins agent 必须支持 Ansible。
docker build -f JenkinsSlaveAnsibleDockerfile -t jenkins-swarm-ansible .
-
启动 Jenkins master 及 Jenkins agent
docker-compose up -d
通过
http://localhost:8080
访问 Jenkins master,如果出现“解锁密码”页面,如下图,则执行命令docker-compose logs jenkins
查看 Jenkins master 启动日志。将日志中的解锁密码输入到表单中。然后就一步步按提示安装即可。 -
安装 Jenkins 插件 本次实验需要安装以下插件:
- Pipeline 2.6:https://plugins.jenkins.io/workflow-aggregator
- Swarm 3.15:https://plugins.jenkins.io/swarm 用于 实现 Jenkins master 与 Jenkins agent 自动连接
- Git 3.9.3:https://plugins.jenkins.io/git
-
配置 Jenkins master 不执行任务 进入页面:http://localhost:8080/computer/(master)/configure,如下图所示设置:
-
确认 Jenkins 安全配置有打开端口,以供 Jenkins agent 连接。 我们设置 Jenkins master 开放的端口,端口可以是固定的 50000 ,也可以设置为随机。设置链接:http://localhost:8080/configureSecurity/。
-
启动目标机器,用于部署 Nginx 在命令行中执行以下命令:
vagrant up
注意,Vagrantfile 文件中的
config.vm.box
值必须改成你的 vagrant box 。
至此,实验环境已经搭建好了。接下来就可以新建 Jenkins 任务了。
3. 在 Jenkins 上创建部署任务
- 新建流水线任务
- 配置流水线 配置 Jenkins 任务从远程仓库拉取 Jenkinsfile,如下图所示:
除此之外,不需要其它配置了,是不是很简单?
4. 手工触发一次自动化构建
点击“立即构建”:
最终执行日志如下:
至此,部署已经完成。以后修改 Nginx 的配置,只需要修改代码,然后推送到远程仓库,就会自动化部署。不需要手工登录到目标机器手工修改了。
最后,我们可以通过访问 http://localhost:5123
,如果出现如下页面说明部署成功:
5. 代码讲解
以上步骤并不能看出自动化部署真正做了什么。那是因为我们所有的逻辑都写在代码中。是的,可以说是 everything is code。
接下来我们介绍代码仓库。
% tree -L 2 ├── JenkinsSlaveAnsibleDockerfile # Jenkins agent 镜像 Dockerfile ├── Jenkinsfile # 流水线逻辑 ├── README.md ├── Vagrantfile # Vagrant 虚拟机定义文件 ├── docker-compose.yml # Jenkins 实现环境 ├── env-conf # 所有应用配置 │ └── dev # dev 环境的配置 ├── deploy # Ansible 部署脚本所在文件夹 │ ├── playbook.yaml │ └── roles └── swarm-client.sh # Jenkins swarm 插件的客户端
5.1流水线逻辑
Jenkinsfile 文件用于描述整条流水线的逻辑。代码如下:
pipeline{ // 任务执行在具有 ansible 标签的 agent 上 agent { label "ansible"} environment{ // 设置 Ansible 不检查 HOST_KEY ANSIBLE_HOST_KEY_CHECKING = false } triggers { pollSCM('H/1 * * * *') } stages{ stage("deploy nginx"){ steps{ sh "ansible-playbook -i env-conf/dev deploy/playbook.yaml" } }}}
environment
部分:用于定义流水线执行过程中的环境变量。triggers
部分:用于定义流水线的触发机制。pollSCM
定义了每分钟判断一次代码是否有变化,如果有变化则自动执行流水线。agent
部分:用于定义整条流水线的执行环境。stages
部分:流水线的所有阶段,都被定义在这部分。
以上只是定义流水线是如何执行的,目前整条流水线只有一个 deploy nginx
阶段,并且只执行了一条 ansible-playbook
命令。但是它并没有告诉我们部署逻辑是怎么样的。
5.2 部署逻辑
所有的部署逻辑,包括 Nginx 的安装启动、配置的更新以及加载,都放在 Ansible 脚本中。对 Ansible 不熟的同学,可以在本文末尾找到介绍 Ansible 的文章。
整个部署逻辑的入口在 deploy/playbook.yaml
,代码如下:
--- - hosts: "nginx" become: true roles: # Nginx 的部署 - ansible-role-nginx # 对防火墙的设置 - ansible-role-firewall
hosts
:定义了 playbook 部署的目标主机分组名为nginx
。roles
:包含了两个执行具体部署动作的 role,至于 role 内部逻辑,不在本文讨论范围,有兴趣的同学阅读源码。
5.3 配置管理
谈到部署,就不得不谈配置管理。
回顾前文中流水线中执行的 shell 命令:ansible-playbook -i env-conf/dev deploy/playbook.yaml
我们通过 -i
参数指定部署时所使用的环境配置。通过这种方式实现环境配置与执行脚本的分离。这样带来以下几个好处:
- 新增环境时,只需要复制现有的环境,然后将里面的变量的值改成新环境的即可。比如,要对测试环境进行部署,只需要将
-i
参数值改成:env-conf/test
。 - 对配置版本化控制。
本次实验中,各个环境的配置放在 env-conf
目录中,目前只有 dev 环境,以下是 env-conf/
目录结构:
% cd env-conf/ % tree └── dev ├── group_vars │ └── nginx.yaml ├── host_vars │ └── 192.168.52.10 └── hosts
- hosts文件:Ansible 中通过“分组”来实现对主机的管理。hosts 文件内容如下:
[nginx] 192.168.52.10
- host_vars 目录:用于存放主机级别的配置变量,本例中
192.168.52.10
是一个 YAML 格式文件。注意文件名是该主机的 IP。我们在文件中放主机相关的配置,比如 Ansible 连接主机时使用到的用户名和密码。 - group_vars 目录:用于存放组级别的配置变量。比如 nginx.yaml 对应的就是
nginx
这个组的的配置变量。文件名与hosts
中的组名对应。
总结
到此,我们完整的自动化部署已经讲解完成。但是还遗留下一些问题:
- 本文只是安装了一个“空”的 Nginx,但是没有介绍 Nginx 真正配置。
- 目前主机的连接信息(SSH 密码)是明文写在
host_vars/192.168.52.10
文件中的,存在安全风险。 - 没有介绍如何当 Java 应用部署时,如何自动更新 Nginx 的配置。
本文属于使用 Jenkins + Ansible 实现自动化部署的入门文章,笔者将根据读者的反馈决定是否写续集。
如果觉得本文讲的 Jenkins 流水线逻辑部分不够过瘾,可以考虑入手一本最近才出版的《Jenkins 2.x实践指南》。长按下图进行扫码购买。
附录
- 本次实验环境代码:https://github.com/zacker330/jenkins-ansible-nginx
- 简单易懂 Ansible 系列 —— 解决了什么:https://showme.codes/2017-06-12/ansible-introduce/
- Puppet,Chef,Ansible 的共性:https://showme.codes/2016-01-02/the-nature-of-ansible-puppet-chef/
作者:翟志军
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
MSSQL-最佳实践-Always Encrypted
author: 风移 摘要 在SQL Server安全系列专题月报分享中,往期我们已经陆续分享了:如何使用对称密钥实现SQL Server列加密技术、使用非对称密钥实现SQL Server列加密、使用混合密钥实现SQL Server列加密技术、列加密技术带来的查询性能问题以及相应解决方案、行级别安全解决方案、SQL Server 2016 dynamic data masking实现隐私数据列打码技术和使用证书做数据库备份加密这七篇文章,直接点击以上文章前往查看详情。本期月报我们分享SQL Server 2016新特性Always Encrypted技术。 问题引入 在云计算大行其道的如今,有没有一种方法保证存储在云端的数据库中数据永远保持加密状态,即便是云服务提供商也看不到数据库中的明文数据,以此来保证客户云数据库中数据的绝对安全呢?答案是肯定的,就是我们今天将要谈到的SQL Server 2016引入的始终加密技术(Always Encrypted)。 使用SQL Server Always Encrypted,始终保持数据处于加密状态,只有调用SQL Server的应用才能读写和...
- 下一篇
iOS面向切面的TableView-AOPTableView
iOS面向切面的TableView-AOPTableView 这个是公司很久之前的开源项目,一个大牛写的,在项目中一直有在用,今天有空发了点时间看下如何实现,看了之后感觉挺有收获,故撰此文,分享给需要的同学。 该库的开源库地址:MeetYouDevs/IMYAOPTableView 概览 WHY AOP TableView 关于为何使用AOP,在MeetYouDevs/IMYAOPTableView这个库的简介中已经有提及到了,主要是针对在我们数据流中接入广告的这种场景,最原始的方法就是分别请求数据以及广告,根据规则合并数据,分别处理业务数据和广告数据的展示这个流程如下图所示。这种方案的弊端就是有很明显的耦合,广告和正常的业务耦合在一起了,同时也违反了设计原则中的单一职责原则,所以这种方式是做的不够优雅的,后期的维护成本也是比较大的。   那么如何解决这个问题呢?如何使用一种不侵入业务的方式优雅的去解决这个问题呢?答案就是使用AOP,让正常的业务和广告并行独立滴处理,下图就是使用AOP方式处理数据流中接入广告流程图  HOW DESIGN AOP TableView 该如何设计...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Hadoop3单机部署,实现最简伪集群
- Mario游戏-低调大师作品
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS关闭SELinux安全模块
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16