用 Ansible 执行日常工作

这篇文章是Wano集团 2016年Advent Calendar中第22天的文章。

Ansible 是一种用作为配置管理工具,但是它也可以在日常的小任务中使用。安装特定的软件包,查看日志等操作,如果只需执行一次,似乎并不困难,但是当涉及到大量目标服务器时,逐个登录并执行这些操作会变得非常繁琐。为了处理这种情况,我们可以事先建立一个环境来执行这些操作,并且在实际操作时,只需编写一个 Ansible Playbook,并将其应用于所有服务器,从而减轻工作负担。

用于样本的配置。

服务器管理对象

操作系统

Ubuntu 14.04 is 尤布图 14.04.

生产 × 2 × 2)
    • sample_prod_01

 

    • sample_prod_02

 

    パスワード: prodpasswd
舞台设计 x 2
    • sample_stage_01

 

    • sample_stage_02

 

    パスワード: stagepasswd
发展 x 2
    • sample_dev_01

 

    • sample_dev_02

 

    パスワード: devpasswd
请用中文重述以下内容,只需要一种选项:

用户

管理员

    • sudo 権限あり

 

    • パスワードは上記の通り

 

    管理マシン側から公開鍵認証にてSSHログイン可能

建造程序

这次将工作目录命名为ansible-work。(可以使用任何名称)

$ mkdir ansible-work
$ cd ansible-work

添加默认设置。

[defaults]
hostfile=hosts

管理目标服务器的设置

将要管理的服务器配置到 hosts 文件中。(与 /etc/hosts 不同。请在当前的 ansible-work 目录下创建此文件。)

[production]
sample_prod_01
sample_prod_02

[stage]
sample_stage_01
sample_stage_02

[development]
sample_dev_01
sample_dev_02

[生产][阶段][开发]是组名,我们在这里将每个服务器进行分组。

取消sudo命令时的密码输入

在这个例子中,每个环境的密码都是不同的。
使用带有-K选项的ansible-playbook来输入sudo密码的方法只能一次指定一个密码,对于每个环境都需要执行ansible-playbook非常麻烦。
如果事先为每个环境指定密码,那么就不需要输入密码了。

$ mkdir group_vars
---
ansible_ssh_user: admin 
ansible_sudo_pass: prodpasswd
---
ansible_ssh_user: admin 
ansible_sudo_pass: stagepasswd
---
ansible_ssh_user: admin 
ansible_sudo_pass: devpasswd
--- 
remote_user: admin

请根据组名设置文件名。在 all.yml 中写入所有服务器共有的配置(稍后将在Playbook中使用)。

密码文件的加密

所以,对于个人使用来说这样已经可以了,但是如果在多个成员之间共享执行环境,最好不要把密码明文写在文件中。(即使只是个人使用,拥有密码明文文件也有点不安全感)

因此,我们将使用ansible-vault命令,对包含密码的文件进行共享钥匙方式的加密处理。

首先,将共享密钥保存在版本管理范围之外的位置。

$ echo samplepasswd > ~/.ansible_vault_pass

可以将“samplepasswd”作为密码使用。请根据需要进行更改。文件名也可以不按照上述方式命名,没有问题。

进行加密处理。

$ ansible-vault encrypt group_vars/production.yml --vault-password-file ~/.ansible_vault_pass
$ ansible-vault encrypt group_vars/stage.yml --vault-password-file ~/.ansible_vault_pass
$ ansible-vault encrypt group_vars/development.yml --vault-password-file ~/.ansible_vault_pass

实例

执行示例1:安装软件包。

请安装libxml2-dev软件包作为示例。创建如下文件。

$ mkdir tasks
---
- name: Install libxml2-dev
  hosts: all
  remote_user: "{{ remote_user }}"
  become: yes
  tasks:
    - apt: 
        name: libxml2-dev
        state: present
        update_cache: yes 

我会执行。

$ ansible-playbook tasks/install_libxml2-dev.yml --vault-password-file ~/.ansible_vault_pass

PLAY [Install libxml2-dev] *****************************************************

TASK [setup] *******************************************************************
ok: [sample_dev_02]
ok: [sample_prod_01]
ok: [sample_prod_02]
ok: [sample_dev_01]
ok: [sample_stage_01]
ok: [sample_stage_02]

TASK [apt] *********************************************************************
changed: [sample_dev_01]
changed: [sample_dev_02]
changed: [sample_prod_02]
changed: [sample_stage_01]
changed: [sample_prod_01]
changed: [sample_stage_02]

PLAY RECAP *********************************************************************
sample_dev_01              : ok=2    changed=1    unreachable=0    failed=0   
sample_dev_02              : ok=2    changed=1    unreachable=0    failed=0   
sample_prod_01             : ok=2    changed=1    unreachable=0    failed=0   
sample_prod_02             : ok=2    changed=1    unreachable=0    failed=0   
sample_stage_01            : ok=2    changed=1    unreachable=0    failed=0   
sample_stage_02            : ok=2    changed=1    unreachable=0    failed=0   

通过添加 –limit 选项,您可以将 libxml2-dev 包仅安装在开发环境中,而不是所有服务器上。

$ ansible-playbook --limit development tasks/libxml2-dev.yml --vault-password-file ~/.ansible_vault_pass

您也可以使用下述命令轻松执行。个人而言,我认为上述方法更可取,因为它可以保存操作记录并且结果易于查看。

ansible all -s -m apt -a 'name=libxml2-dev state=present update_cache=yes' --vault-password-file ~/.ansible_vault_pass

例2:检查包的版本

openssl等安全补丁经常发布的软件包,经常需要确认当前安装的版本是否为最新版本。因此,我们将创建一个Playbook,将版本写入文件并将其传输到本地。

- name: Check version of openssl
  hosts: all
  remote_user: "{{ remote_user }}"
  become: no 
  vars:
      outfile: /tmp/{{ inventory_hostname }}.txt
  tasks:
      - shell: echo {{ inventory_hostname }}
                && sh -c 'dpkg -l | grep openssl | grep -v gnutls'
                && echo >> {{ outfile }}
      - fetch:
            src: "{{ outfile }}"
            dest: /tmp/openssl_version
            flat: yes
            fail_on_missing: yes

事先在管理机器上创建/tmp/openssl_version目录,然后进行执行。

$ mkdir /tmp/openssl_version
$ ansible-playbook tasks/openssl_version.yml --vault-password-file ~/.ansible_vault_pass
PLAY [Check version of openssl] ************************************************

TASK [setup] *******************************************************************
(...略...)

TASK [command] *****************************************************************
(...略...)

TASK [fetch] *******************************************************************
(...略...)

PLAY RECAP *********************************************************************
sample_dev_01              : ok=3    changed=2    unreachable=0    failed=0   
sample_dev_02              : ok=3    changed=2    unreachable=0    failed=0   
sample_prod_01             : ok=3    changed=2    unreachable=0    failed=0   
sample_prod_02             : ok=3    changed=2    unreachable=0    failed=0   
sample_stage_01            : ok=3    changed=2    unreachable=0    failed=0   
sample_stage_02            : ok=3    changed=2    unreachable=0    failed=0   

之后,

cat /tmp/openssl_version/*

如果执行该命令,可以列出每个服务器的 OpenSSL 版本。

sample_dev_01
ii  openssl                         1.0.1f-1ubuntu2.21               amd64        Secure Sockets Layer toolkit - cryptographic utility

sample_dev_02
ii  openssl                         1.0.1f-1ubuntu2.21               amd64        Secure Sockets Layer toolkit - cryptographic utility

(...略...)

sample_stage_02
ii  openssl                         1.0.1f-1ubuntu2.21               amd64        Secure Sockets Layer toolkit - cryptographic utility

只需要一个选项。+ 追加记录

在 Ansible 文档的 Vault 页面中

Ansible 1.5 新增了一个“Vault”功能,它允许将敏感数据(如密码或密钥)保存在加密文件中,而不是以明文形式存在于playbooks或roles中。这些密保文件可以进行分发或放置在源代码控制中。

「文件经过加密后可以发布」。虽然被加密了,但还是能够解密,所以最好从版本控制中排除以确保安全。

广告
将在 10 秒后关闭
bannerAds