【教程】使用Ansible基础知识(从安装到在多台服务器上应用更改)

用 (Basic usage of Ansible)

images.png

Ansible是什么?

Ansible是一种用于以可重复使用的代码描述服务器配置的工具。

可以将Chef和Puppet列为类似的工具。
(这些工具集合被称为配置管理工具。)

Ansible特点

用YAML描述

在使用Python或其他编程语言时,我们通常会使用模块等工具,
但基本上会使用一种叫做YAML的数据格式。
与类似于使用Ruby编写的Chef等工具相比,
它(除非涉及复杂任务)拥有更高的可读性和更少的编写量。

使用YAML进行描述

---
- hosts: webservers
  become: True
  tasks:
  - name: install Apache
    yum: name=httpd

2. 推送模式

在希望应用设置时,在目标服务器上通过SSH连接,并逐步应用这些设置。
还有其他形式,其中包括拉取模式。Chef被归类到这种模式中。
在拉取模式中,配置工具会定期去目标服务器获取变更,并在有差异时执行。
对于拉取模式,其优点是只要在可以通过SSH连接的环境里,就无需在变更目标服务器上安装任何内容。

3. 只要做最基本的事情,就非常简单不过了。

只需做最基本的事情,只需要定义连接目标的清单文件和记录变更步骤的Playbook这两个就够了。

教程

让我们尝试基本的用法。
设置内容是通过使用Vagrant创建多个虚拟环境,
并在每个环境中安装Nginx。

执行环境

我正在使用的机器是”MacOS X El Capitan”。
此外,我的工作目录是在根目录下的一个名为ansible的目录中。

[you@local] $ cd ~
[you@local] $ mkdir ansible
[you@local] $ cd ansible

最终,ansible目录的内部将会如下所示。

ansible
├── Vagrantfile
├── ansible.cfg
├── hosts
└── nginx.yml

使用Vagrant进行环境设置

为了使更改生效,我们将使用Vagrant工具。
这次我们将创建两个具有开放80端口的虚拟环境。

1. 安装VirtualBox

请从以下链接下载并安装:
https://www.virtualbox.org/

2. 安装Vagrant

我要安装Vagrant。
我的电脑是MacOS,并且已经安装了homebrew,
所以我使用brew命令来安装。
运行brew install vagrant。
当然,也可以尝试其他安装方法。

用Vagrant创建虚拟环境

设置VagrantFile文件并启动虚拟环境。

首先,我们要进行初始化。

[you@local] $ vagrant init bento/centos-6.7

将VagrantFile文件修改为以下内容。

# -*- mode:ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.ssh.insert_key = false
  config.vm.define "webserver1" do |webserver1|
    webserver1.vm.hostname = "webserver1"
    webserver1.vm.box = "bento/centos-6.7"
    webserver1.vm.network "private_network", ip: "192.168.11.21"
  end
  config.vm.define "webserver2" do |webserver2|
    webserver2.vm.hostname = "webserver2"
    webserver2.vm.box = "bento/centos-6.7"
    webserver2.vm.network "private_network", ip: "192.168.11.22"
  end
end

我們啟動虛擬環境。

[you@local] $ vagrant up

如果成功创建虚拟环境,为了确认SSH连接方式,请执行以下命令。

[you@local] $ vagrant ssh-config

在我的环境中,情况如下所示。

Host webserver1
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/you/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Host webserver2
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/you/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

安装Ansible

如果你正在使用Mac并且已经安装了Homebrew,可以使用以下命令来安装Ansible。

[you@local] $ brew install ansible

如果可用的话,可以使用Python的软件包管理器pip进行安装。

[you@local] $ sudo pip install ansible

库存

库存是目标服务器的列表。
一般来说,它们通常被称为hosts。
我们立即创建hosts的文档。
bash
[you@local] $ vi hosts

[webservers]
192.168.11.21
192.168.11.22

[webservers:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key

在webservers组中注册先前创建的虚拟环境的IP地址,并将其作为应用于webservers组的变量设置为:
– ansible_ssh_user
– ansible_ssh_private_key_file
这两个变量是ansible在SSH连接时使用的。此外,还有其他变量如:
– ansible_ssh_host
– ansible_ssh_port
– ansible_ssh_pass
– ansible_connection
每个变量都有默认值。

总之,确认沟通并提高氛围。

在这里,我们来试一试能否通过ansible进行通信。

[you@local] $ ansible webservers -i hosts -m ping

– 通过-i选项指定清单(hosts)。
– 通过-m选项指定要使用的模块。
– ping是用于检查通过ssh连接的互通性的模块。

在第一次连接时,您可能会看到一个显示,内容为“无法验证主机 ‘192.168.11.21(192.168.11.21)’ 的真实性。”请继续,并键入“是”。

在我的环境中,结果如下所示。

192.168.11.21 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.11.22 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

这样,确认联络已经完成了。

顺便写下ansible.cnf。

如果在ansible.cnf文件中进行配置,就可以减少对清单的编写或者减少通过命令行编写内容的情况。首先,要编辑清单文件。

[webservers]
192.168.11.21
192.168.11.22

已删除vars的内容。接下来将创建ansible.cnf文件。

[defaults]
hostfile=hosts
remote_user=vagrant
private_key_file=~/.vagrant.d/insecure_private_key

在ansible.cfg文件中,我指定了以下三个选项:
– hostfile(清单文件)
– remote_user(ansible_ssh_user)
– private_key_file(ansible_ssh_private_key_file)

这次执行时不需指定库存。

[you@local] $ ansible webservers -m ping

只要返回相同的内容,ansible.cfg的配置就算成功了。

在Playbook中安装nginx。

我花了很多时间来准备,但现在终于到了编写Playbook(环境搭建)的部分。
如先前所说,我们将使用YAML格式来描述环境搭建。
我们将创建一个名为nginx.yml的Playbook。

---
- hosts: webservers
  become: True
  tasks:
  - name: install nginx repo
    yum: name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present
  - name: install nginx
    yum: name=nginx
  - name: restart nginx
    service: name=nginx state=restarted

请参考维基百科等相关资料学习基本的YAML语法,逐行阅读并理解其内容。

nginx.yml説明hosts: webservershostの指定。今回はグループ名webserversbecome: Truesudoerとして実行tasks:実行するタスクを順に並べた辞書name: install nginx repoひとつ目のタスクの名前。Nginxのレポジトリをインストールyum: name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=presentyumモジュールを使ったタスクの内容。記載のURLからYUMレポジトリをインストール。name: install nginxNginxをインストールする旨の名前yum: name=nginxYUMモジュールを利用してNginxをインストールname: restart nginxNginxを再起動する旨の名前service: name=nginx state=restartedServiceモジュールを利用してNginxを再起動

让我们执行这个Playbook吧。
要执行Playbook,我们需要使用ansible-playbook命令。

[you@local] $ ansible-playbook nginx.yml

在Playbook中,由於指定了要更改的資源主機(hosts),所以指令的參數僅限於yml檔案。

运行结果如下所示。

TASK [setup] *******************************************************************
ok: [192.168.11.22]
ok: [192.168.11.21]

TASK [install nginx repo] ******************************************************
changed: [192.168.11.22]
changed: [192.168.11.21]

TASK [install nginx] ***********************************************************
changed: [192.168.11.21]
changed: [192.168.11.22]

TASK [restart nginx] ***********************************************************
changed: [192.168.11.21]
changed: [192.168.11.22]

PLAY RECAP *********************************************************************
192.168.11.21              : ok=4    changed=3    unreachable=0    failed=0
192.168.11.22              : ok=4    changed=3    unreachable=0    failed=0

スクリーンショット 2016-08-03 18.59.51.png

如果再次执行之前的ansible-playbook命令,会发生什么呢?

PLAY [webservers] **************************************************************

TASK [setup] *******************************************************************
ok: [192.168.11.21]
ok: [192.168.11.22]

TASK [install nginx repo] ******************************************************
ok: [192.168.11.22]
ok: [192.168.11.21]

TASK [install nginx] ***********************************************************
ok: [192.168.11.21]
ok: [192.168.11.22]

TASK [restart nginx] ***********************************************************
changed: [192.168.11.22]
changed: [192.168.11.21]

PLAY RECAP *********************************************************************
192.168.11.21              : ok=4    changed=1    unreachable=0    failed=0
192.168.11.22              : ok=4    changed=1    unreachable=0    failed=0

安裝nginx倉庫和安裝nginx的狀態從”changed”變為”ok”。
這是因為YUM模組會檢查安裝是否已經完成,如果已經安裝,只會返回OK,實際上並不會執行安裝。
反覆安裝可能會導致意外的錯誤和停機時間。
為了避免這種情況,模組會自動處理。

操作程序

然而,重新启动nginx任务只是一个重新启动的任务,无论是更多还是更少,每次执行之后都会标记为更改(changed)。这会导致(非常短暂的)停机时间。为了避免这种情况,有一个称为handler的机制。这是一种在指定任务完成后执行的变更。为了实际使用它,让我们编辑nginx.yml。

---
- hosts: webservers
  become: True
  tasks:
  - name: install nginx repo
    yum: name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present
  - name: install nginx
    yum: name=nginx
    notify: restart nginx
  handlers:
  - name: restart nginx
    service: name=nginx state=restarted

修改的是在“install nginx”的部分新增了“notify”,并将内容更改为“restart nginx”,
将“restart nginx”的任务移动到与“tasks”不同的“handlers”中。
这意味着只有在“install nginx”任务实际发生了更改时,
才会执行“handlers”中的“restart nginx”。

当我们尝试执行与先前一样的 ansible-playbook nginx.yml 命令时,我认为结果会如下所示。

PLAY [webservers] **************************************************************

TASK [setup] *******************************************************************
ok: [192.168.11.21]
ok: [192.168.11.22]

TASK [install nginx repo] ******************************************************
ok: [192.168.11.21]
ok: [192.168.11.22]

TASK [install nginx] ***********************************************************
ok: [192.168.11.21]
ok: [192.168.11.22]

PLAY RECAP *********************************************************************
192.168.11.21              : ok=3    changed=0    unreachable=0    failed=0
192.168.11.22              : ok=3    changed=0    unreachable=0    failed=0

Nginx重启任务已经停止执行。

如果确实安装了Nginx,那么是否需要重新启动Nginx呢?为了确认这一点,我们可以重新创建Vagrant的虚拟环境来尝试一下。

[you@local] $ vagrant destroy
[you@local] $ vagrant up

当虚拟环境重新启动后,我将再次执行命令”ansible-playbook nginx.yml”。

[you@local] $ ansible-playbook nginx.yml

PLAY [webservers] **************************************************************

TASK [setup] *******************************************************************
ok: [192.168.11.22]
ok: [192.168.11.21]

TASK [install nginx repo] ******************************************************
changed: [192.168.11.21]
changed: [192.168.11.22]

TASK [install nginx] ***********************************************************
changed: [192.168.11.21]
changed: [192.168.11.22]

RUNNING HANDLER [restart nginx] ************************************************
changed: [192.168.11.21]
changed: [192.168.11.22]

PLAY RECAP *********************************************************************
192.168.11.21              : ok=4    changed=3    unreachable=0    failed=0
192.168.11.22              : ok=4    changed=3    unreachable=0    failed=0

重新启动Nginx已经执行完毕!成功了!

结束

除了其他各种各样的技巧之外,我认为以上就是基本的使用流程。
我已经用实际测试过的代码和步骤进行了一次全面的解释,如果还有遗漏的地方,请不要犹豫地指出来。
让我们结合Git等工具,共同努力实现用户友好的基础设施建设吧!

参考书籍

    1. Lorin Hochstein(2016)的《Ansible初学者指南》由Sky株式会社翻译,出版于O’Reilly Japan出版社。

新原雅史(2016)的《服务器/基础设施工程师培训读本:DevOps编程》特辑1:最快攻略!使用Ansible 2进行服务器构建,由技术评论社出版。

bannerAds