如何使用 Ansible 打补丁以及安装应用
使用 Ansible IT 自动化引擎节省更新的时间。
Ansible
使用 Ansible IT 自动化引擎节省更新的时间。

> 
> 使用 Ansible IT 自动化引擎节省更新的时间。
> 
> 
> 


![](/data/attachment/album/201805/20/035937k1jc6t90wi80je66.jpg)


你有没有想过，如何打补丁、重启系统，然后继续工作？


如果你的回答是肯定的，那就需要了解一下 [Ansible](https://www.ansible.com/overview/how-ansible-works) 了。它是一个配置管理工具，对于一些复杂的有时候需要几个小时才能完成的系统管理任务，又或者对安全性有比较高要求的时候，使用 Ansible 能够大大简化工作流程。


以我作为系统管理员的经验，打补丁是一项最有难度的工作。每次遇到<ruby> 公共漏洞批露 <rt>  Common Vulnearbilities and Exposure </rt></ruby>（CVE）通知或者<ruby> 信息保障漏洞预警 <rt>  Information Assurance Vulnerability Alert </rt></ruby>（IAVA）时都必须要高度关注安全漏洞，否则安全部门将会严肃追究自己的责任。


使用 Ansible 可以通过运行[封装模块](https://docs.ansible.com/ansible/latest/list_of_packaging_modules.html)以缩短打补丁的时间，下面以 [yum 模块](https://docs.ansible.com/ansible/latest/yum_module.html)更新系统为例，使用 Ansible 可以执行安装、更新、删除、从其它地方安装（例如持续集成/持续开发中的 `rpmbuild`）。以下是系统更新的任务：



```
  - name: update the system
    yum:
      name: "*"
      state: latest

```

在第一行，我们给这个任务命名，这样可以清楚 Ansible 的工作内容。第二行表示使用 `yum` 模块在CentOS虚拟机中执行更新操作。第三行 `name: "*"` 表示更新所有程序。最后一行 `state: latest` 表示更新到最新的 RPM。


系统更新结束之后，需要重新启动并重新连接：



```
  - name: restart system to reboot to newest kernel
    shell: "sleep 5 && reboot"
    async: 1
    poll: 0

  - name: wait for 10 seconds
    pause:
      seconds: 10

  - name: wait for the system to reboot
    wait_for_connection:
      connect_timeout: 20
      sleep: 5
      delay: 5
      timeout: 60

  - name: install epel-release
    yum:
      name: epel-release
      state: latest

```

`shell` 模块中的命令让系统在 5 秒休眠之后重新启动，我们使用 `sleep` 来保持连接不断开，使用 `async` 设定最大等待时长以避免发生超时，`poll` 设置为 0 表示直接执行不需要等待执行结果。暂停 10 秒钟以等待虚拟机恢复，使用 `wait_for_connection` 在虚拟机恢复连接后尽快连接。随后由 `install epel-release` 任务检查 RPM 的安装情况。你可以对这个剧本执行多次来验证它的幂等性，唯一会显示造成影响的是重启操作，因为我们使用了 `shell` 模块。如果不想造成实际的影响，可以在使用 `shell` 模块的时候 `changed_when: False`。


现在我们已经知道如何对系统进行更新、重启虚拟机、重新连接、安装 RPM 包。下面我们通过 [Ansible Lightbulb](https://github.com/ansible/lightbulb/tree/master/examples/nginx-role) 来安装 NGINX:



```
  - name: Ensure nginx packages are present
    yum:
      name: nginx, python-pip, python-devel, devel
      state: present
    notify: restart-nginx-service

  - name: Ensure uwsgi package is present
    pip:
      name: uwsgi
      state: present
    notify: restart-nginx-service

  - name: Ensure latest default.conf is present
    template:
      src: templates/nginx.conf.j2
      dest: /etc/nginx/nginx.conf
      backup: yes
    notify: restart-nginx-service

  - name: Ensure latest index.html is present
    template:
      src: templates/index.html.j2
      dest: /usr/share/nginx/html/index.html

  - name: Ensure nginx service is started and enabled
    service:
      name: nginx
      state: started
      enabled: yes

  - name: Ensure proper response from localhost can be received
    uri:
      url: "http://localhost:80/"
      return_content: yes
    register: response
    until: 'nginx_test_message in response.content'
    retries: 10
    delay: 1

```

以及用来重启 nginx 服务的操作文件：



```
# 安装 nginx 的操作文件
  - name: restart-nginx-service
    service:
      name: nginx
      state: restarted

```

在这个角色里，我们使用 RPM 安装了 `nginx`、`python-pip`、`python-devel`、`devel`，用 PIP 安装了 `uwsgi`，接下来使用 `template` 模块复制 `nginx.conf` 和 `index.html` 以显示页面，并确保服务在系统启动时启动。然后就可以使用 `uri` 模块检查到页面的连接了。


这个是一个系统更新、系统重启、安装 RPM 包的剧本示例，后续可以继续安装 nginx，当然这里可以替换成任何你想要的角色和应用程序。



```
  - hosts: all
    roles:
      - centos-update
      - nginx-simple

```

 


这只是关于如何更新系统、重启以及后续工作的示例。简单起见，我只添加了不带[变量](https://docs.ansible.com/ansible/latest/playbooks_variables.html)的包，当你在操作大量主机的时候，你就需要修改其中的一些设置了：


* [async & poll](https://docs.ansible.com/ansible/latest/playbooks_async.html)
* [serial](https://docs.ansible.com/ansible/latest/playbooks_delegation.html#rolling-update-batch-size)
* [forks](https://docs.ansible.com/ansible/latest/intro_configuration.html#forks)


这是由于在生产环境中如果你想逐一更新每一台主机的系统，你需要花相当一段时间去等待主机重启才能够继续下去。




---


via: <https://opensource.com/article/18/3/ansible-patch-systems>


作者：[Jonathan Lozada De La Matta](https://opensource.com/users/jlozadad) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出

