版本控制系统    Gitlab Github

持续集成工具    Jenkins

部署工具    Ansible Saltstack Chef

 

本文通过Jenkins + Ansible + Gitlab实现自动化部署。


Ansible介绍

Ansible是一个开源部署工具,由Python开发,不需要安装客户端,通过SSH协议通信,全平台,模块化部署管理。

  • 区别:
Chef
    Ruby开发,C/S架构,配置需要Git依赖,
    Recipe脚本编写规范,需要编程经验
    
Saltstack
    Python开发,C/S架构,模块化配置管理,
    TAML脚本编写规范,适合大规模集群部署
    
Ansible
    Python开发,无Client,模块化配置管理,
    Playbook脚本编写规范,易于上手,适合中小规模快速部署

 

  • ansible的优势:
1. 轻量级,无客户端(agentless)

2. 开源免费,学习成本低,快速上手

3. 使用Playbook作为核心配置架构,统一的脚本格式

4. 完善的模块化扩展,支持目前主流的开发场景

5. 强大的稳定性和兼容性

 


环境准备

3台机器需要做环境准备。

  • 角色划分:
Jenkins + Ansible   192.168.30.128

test host   192.168.30.129

gitlab  192.168.30.130

 

  • 关闭防火墙和selinux:
# systemctl stop firewalld && systemctl disable firewalld# setenforce 0 && sed -i 's/=enforcing/=disabled/g' /etc/selinux/config

 

  • 添加本地dns:
# vim /etc/hosts192.168.30.128 jenkins.lzxlinux.com
192.168.30.129 test.lzxlinux.com
192.168.30.130 gitlab.lzxlinux.com

 

在Windows电脑hosts文件中添加本地dns:

192.168.30.128 jenkins.lzxlinux.com
192.168.30.129 test.lzxlinux.com
192.168.30.130 gitlab.lzxlinux.com

 


Ansible安装

ansible有两种安装方式。

  • yum安装(不推荐):
# yum install -y ansible

 

  • git安装(推荐):
# yum install -y git nss curl zlib* libffi-devel openssl openssl-devel# cd /software# wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz# tar zxf Python-3.7.3.tgz# cd Python-3.7.3# ./configure --prefix=/usr/local --with-ensurepip=install --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"# make && make altinstall# ln -s /usr/local/bin/pip3.7 /usr/local/bin/pip

 

# pip install --upgrade pip# pip install virtualenv# useradd deploy                #创建ansible部署用户deploy# su - deploy$ virtualenv -p /usr/local/bin/python3.7 .py3-a2.8-env

$ cd /home/deploy/.py3-a2.8-env

$ git clone https://github.com/ansible/ansible.git

$ source /home/deploy/.py3-a2.8-env/bin/activate

$ pip install paramiko PyYAML jinja2

$ cd ansible/

$ git checkout stable-2.8

$ source /home/deploy/.py3-a2.8-env/ansible/hacking/env-setup -q

$ ansible --version

ansible 2.8.5.post0
  config file = None
  configured module search path = ['/home/deploy/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/deploy/.py3-a2.8-env/ansible/lib/ansible
  executable location = /home/deploy/.py3-a2.8-env/ansible/bin/ansible
  python version = 3.7.3 (default, Oct  9 2019, 18:19:25) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

 

通过这种方式安装的ansible隔离于宿主机的python环境。

  • 免密认证:
(.py3-a2.8-env) [deploy@test1 ansible]$ ssh-keygen -t rsa               #直接回车(.py3-a2.8-env) [deploy@test1 ansible]$ ssh-copy-id -i /home/deploy/.ssh/id_rsa.pub root@test.lzxlinux.com(.py3-a2.8-env) [deploy@test1 ansible]$ ssh root@test.lzxlinux.com
Last login: Fri Oct 11 17:56:06 2019 from 192.168.30.1# logoutConnection to test.lzxlinux.com closed.

 


Playbook介绍

Playbook是ansible的脚本,不同于ansible命令行,是通过YAML格式来编写的。

  • 核心组成元素:
Tasks:任务,执行的任务列表

Vars:变量,执行playbook需要定义的变量

Templates:模板,执行playbook的模板文件,一般为脚本

Handlers:处理器,条件触发执行的操作

Roles:角色,由上面Tasks、Vars、Templates、Handlers等组成

 

  • 框架与格式:

对于一个playbook,如test playbook,大致框架如下,

inventory/      server详细清单目录
    testenv     具体清单与变量声明文件
roles/      roles任务列表
    textbox/        testbox详细任务
        tasks/
            main.yml        testbox主任务文件
            task1.yml       testbox其它任务文件
            task2.yml
deploy.yml      playbook任务入口文件

 

testenv的格式如下,

[testservers]       多个相同部署任务的server组成一个server组
test.example.com        目标部署主机hostname、domain、ip
test.lzxlinux.com
192.168.30.100

[testservers:vars]      server组参数
server_name=test.example.com        目标主机key/value参数
user=root
output=/root/test.txt

 

main.yml的格式如下,

#引用同目录下其它任务文件- include:task1.yml- include:task2.yml

 

task1.yml的格式如下,

- name: print server name               #任务名称
  shell: "echo {{ server_name }}"               #使用shell模块执行命令
  - name: print server user  shell: "echo {{ user }}"

 

deploy.yml的格式如下,

- hosts: "testservers"              #server组
  gather_facts: true                #获取server基本信息,便于使用内置变量,如当前主机ip
  remote_user: root             #执行任务的server系统用户
  roles:
    - testbox               #执行role包含的任务

 

  • ssh免密认证:

ansible部署节点创建ssh本地密钥

# ssh-keygen -t rsa

 

拷贝公钥至目标节点

# ssh-copy-id -i root@test.example.com

 


Ansible常用模块

不管是使用命令行执行ansible命令,还是通过playbook执行ansible命令,都要通过ansible模块来执行。

  • group模块:

管理目标节点上的用户组及其权限。

示例:

- name: create group mysql  group: name=mysql state=present

 

  • user模块:

管理目标节点上的用户及其权限。

示例:

- name: create user mysql  user: name=mysql group=mysql state=present create_home=False shell=/sbin/nologin

 

  • file模块:

在目标节点创建文件或目录,并赋予其系统权限(属主属组、rwx及特殊权限等)。

示例:

- name: create a file  file: name=/root/1.txt state=touch owner=root group=root mode=0644

 

  • copy模块:

实现ansible部署节点到目标节点的文件传送,同时可指定文件的系统权限。

示例:

- name: copy a file  copy: src=/root/1.txt dest=/tmp/1.txt owner=root group=root mode=0644 force=yes

 

  • stat模块:

获取远程文件状态信息。

示例:

- name: check if foo.sh exists  stat: path=/root/foo.sh  register: script_stat

 

  • debug模块:

打印语句到ansible执行输出。

示例:

- debug: msg=foo.sh exists  when: script_stat.stat.exists

 

  • command/shell模块:

用来执行linux命令行。

示例:

- name: run the script  command: "sh /root/foo.sh"
  - name: run the script  shell: "echo 'test' > /root/1.txt"

 

shell支持$home$HOME<<<>>>|;&;而command不支持这些。一般情况下推荐使用shell模块。

  • template模块:

实现ansible部署节点到目标节点的jinja2模板传送,同时可指定文件的系统权限。

示例:

- name: write the nginx config file  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root

 

  • yum模块:

用来管理redhat系的Linux上的安装包。

示例:

- name: install the latest version of Nginx  yum:
    name: nginx    state: latest

 

  • service模块:

用来管理模板节点的系统服务。

示例:

- name: start nginx service and enable nginx service  service: 
    name: nginx    state: started    enabled: yes

 

  • get_url模块:

用来下载指定链接的文件。

示例:

- name: download mysql tar package  get_url: 
    url=https://mirrors.tuna.tsinghua.edu.cn/mysql/downloads/MySQL-5.7/mysql-5.7.25-linux-glibc2.12-x86_64.tar.gz
    dest=/software

 

  • unarchive模块:

用来解压目标节点上的压缩包。

参数:

copy:默认为yes,当copy=yes,那么拷贝的文件是从ansible主机复制到远程主机上的;如果设置为copy=no,那么会在远程主机上src路径寻找源文件。

src:源路径,可以是部署节点上的路径,也可以是目标节点上的路径,如果是目标节点上的路径,则需要设置copy=no。

示例:

- name: unarchive mysql tar package  unarchive: src=/software/mysql-5.7.25-linux-glibc2.12-x86_64.tar.gz dest=/usr/local/ owner=mysql group=mysql copy=no

 

常用模块案例操作参考:ansible-playbook批量部署nginx