文档章节

使用 Jenkins + Ansible 实现自动化部署 Nginx

Jenkins中文社区
 Jenkins中文社区
发布于 04/25 16:33
字数 2024
阅读 830
收藏 23

本文首发于:Jenkins 中文社区

本文介绍如何使用 Jenkins + Ansible 实现对 Nginx 的自动化部署。最终达到的效果有如下几点:

  1. 只要你将 Nginx 的配置推送到 GitHub 中,Jenkins 就会自动执行部署,然后目标服务器的 Nginx 配置自动生效。这个过程是幂等(idempotent)的,只要代码不变,执行多少遍,最终效果不变。
  2. 如果目标机器没有安装 Nginx,则会自动安装 Nginx。
  3. 自动设置服务器防火墙规则。

1. 实验环境介绍

本次实验使用 Docker Compose 搭建 Jenkins 及 Jenkins agent。使用 Vagrant 启动一台虚拟机,用于部署 Nginx。使用 Vagrant 是可选的,读者可以使用 VirtualBox 启动一个虚拟机。使用 Vagrant 完全是为了自动化搭建实验环境。

以下是整个实验环境的架构图:
Jenkins Ansible Nginx

注意,图中的 5123 <-> 80 代表将宿主机的 5123 端口请求转发到虚拟机中的 80 端口。

  • Vagrant:虚拟机管理工具,通过它,我们可以使用文本来定义、管理虚拟机。
  • Ansible:自动化运维工具
  • Docker Compose:它是一个用于定义和运行多容器 Docker 应用程序的工具。可以使用 YAML 文件来配置应用程序的服务。

2. 启动实验环境

  1. 克隆代码并进入文件夹

    git clone https://github.com/zacker330/jenkins-ansible-nginx.git
    cd jenkins-ansible-nginx
    
  2. 构建 Jenkins agent 的镜像 需要自定义 Jenkins agent 镜像有两个原因:

    1. 本次实验,使用 Swarm 插件实现 Jenkins master 与 agent 之间的通信,所以 Jenkins agent 需要启动 swarm 客户端。
    2. Jenkins agent 必须支持 Ansible。
    docker build -f JenkinsSlaveAnsibleDockerfile -t jenkins-swarm-ansible .
    
  3. 启动 Jenkins master 及 Jenkins agent

    docker-compose up -d
    

    通过 http://localhost:8080 访问 Jenkins master,如果出现“解锁密码”页面,如下图,则执行命令 docker-compose logs jenkins 查看 Jenkins master 启动日志。将日志中的解锁密码输入到表单中。然后就一步步按提示安装即可。 解锁Jenkins

  4. 安装 Jenkins 插件 本次实验需要安装以下插件:

  5. 配置 Jenkins master 不执行任务 进入页面:http://localhost:8080/computer/(master)/configure,如下图所示设置:
    image.png

  6. 确认 Jenkins 安全配置有打开端口,以供 Jenkins agent 连接。 我们设置 Jenkins master 开放的端口,端口可以是固定的 50000 ,也可以设置为随机。设置链接:http://localhost:8080/configureSecurity/image.png

  7. 启动目标机器,用于部署 Nginx 在命令行中执行以下命令:

    vagrant up 
    

    注意,Vagrantfile 文件中的 config.vm.box 值必须改成你的 vagrant box 。

至此,实验环境已经搭建好了。接下来就可以新建 Jenkins 任务了。

3. 在 Jenkins 上创建部署任务

  1. 新建流水线任务
    新建流水线任务
  2. 配置流水线 配置 Jenkins 任务从远程仓库拉取 Jenkinsfile,如下图所示:
    配置流水线
    除此之外,不需要其它配置了,是不是很简单?

4. 手工触发一次自动化构建

点击“立即构建”:
image.png

最终执行日志如下:
部署日志

至此,部署已经完成。以后修改 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 参数指定部署时所使用的环境配置。通过这种方式实现环境配置与执行脚本的分离。这样带来以下几个好处:

  1. 新增环境时,只需要复制现有的环境,然后将里面的变量的值改成新环境的即可。比如,要对测试环境进行部署,只需要将 -i 参数值改成:env-conf/test
  2. 对配置版本化控制。

本次实验中,各个环境的配置放在 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 中的组名对应。

总结

到此,我们完整的自动化部署已经讲解完成。但是还遗留下一些问题:

  1. 本文只是安装了一个“空”的 Nginx,但是没有介绍 Nginx 真正配置。
  2. 目前主机的连接信息(SSH 密码)是明文写在 host_vars/192.168.52.10 文件中的,存在安全风险。
  3. 没有介绍如何当 Java 应用部署时,如何自动更新 Nginx 的配置。

本文属于使用 Jenkins + Ansible 实现自动化部署的入门文章,笔者将根据读者的反馈决定是否写续集。

如果觉得本文讲的 Jenkins 流水线逻辑部分不够过瘾,可以考虑入手一本最近才出版的《Jenkins 2.x实践指南》。长按下图进行扫码购买。

附录

作者:翟志军

© 著作权归作者所有

Jenkins中文社区

Jenkins中文社区

粉丝 53
博文 58
码字总数 91584
作品 2
杭州
私信 提问
基于jenkins结合svn、ansible、shell和mysql版本迁移实现多服务器批量发布

hello,大家好! 由于工作原因,本篇博文迟迟没有发布上来,在此深表歉意!因宅鸟作为一个老鸟,还有很多东西需要和大家分享,所以宅鸟有意将本篇博文作为Jenkins持续集成自动测试部署系列的收...

birdinroom
2018/06/28
0
0
ChatOps实战

image.png ChatOps概念在国内已经有一些文章谈过,但是都处于理论范畴。而本文则是一篇ChatOps实践的文章。 有必要说明我对ChatOps的理解,ChatOps表面上就是在一个聊天窗口中,发送一个命令...

翟志军
2017/10/08
0
0
jenkins集成ansible注意事项Failed to connect to the host via ssh.

  在集成jenkins和ansible实现自动化部署时,root用户下执行ansible命令时可以正常运行。由于是通过jenkins用户去执行ansible命令,而jenkins用户却报如下异常: XXXXXXX | UNREACHABLE! =...

无声胜有声
2016/07/11
0
0
jenkins自动部署

一.说明 经过一段时间的研究与讨论(关于自动化部署及自动化运维),初步确定方案,并已经开始实施。 根据目前公司的服务器环境及系统架构,以及当前市面流行趋势,对工具的使用进行了确定,为...

邱野
2016/10/12
0
0
jenkins + supervisor + ansible 实现netcore程序的多机一键部署

     上一篇我们简单的说到了使用jenkins+supervisor实现了一个单机版的多副本部署,但是在更多的场景下还是需要netcore程序的多机一键部署,那么多 机器间如何分发呢? 肯定不能使用scp...

一线码农
01/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

关于运维,该怎么决定它的方向,这个似工作又似兴趣的存在

我之前主要从事网络、桌面、机房管理等相关工作,这些工作使我迷惘,这应该是大多数运维人都经历过的过程; 18年国庆,我从国内前三的消费金融公司裸辞,下海创业,就是想要摆脱这样的困境。...

网络小虾米
6分钟前
1
0
Java Timer的用法

Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { System.out.println("11232"); } }, 200000 , 1000); public void schedule(TimerTask task, long delay......

林词
9分钟前
3
0
使用js动态加载外部js文件以及动态创建script脚本

动态脚本指的是在页面加载时不存在,但将来的某一时刻通过修改该DOM动态添加的脚本。和操作HTML元素一样,创建动态脚本也有两种方式:插入外部文件和直接插入JavaScript代码。 动态加载外的外...

Bing309
17分钟前
2
0
从零开始入门 K8s | Kubernetes 网络概念及策略控制

作者 | 阿里巴巴高级技术专家 叶磊 一、Kubernetes 基本网络模型 本文来介绍一下 Kubernetes 对网络模型的一些想法。大家知道 Kubernetes 对于网络具体实现方案,没有什么限制,也没有给出特...

阿里巴巴云原生
21分钟前
2
0
天气获取

本文转载于:专业的前端网站➨天气获取 $.get("http://wthrcdn.etouch.cn/WeatherApi", { citykey: cityCode }, function (d) { //创建文档对象 var parser = new ......

前端老手
21分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部