尝试从Chef转换到Ansible

转载来源文章:尝试从Chef转向Ansible – MCATM毫无所言。


厨师够了!

「如何在Chef-Solo和Chef-Server之间进行选择!!」或者说「在这之间纠结着的时候,什么是Chef-Zero!!」或者说「对于根本没有启动的服务器,使用OpenSSL进行访问请求之类的,已经晕头转向了(←这只是我自己不明白而已)」,因为感到非常沮丧,所以决定尝试一下传闻更简单的服务器配置管理工具Ansible。以下是备忘录!


最初的设定

由于Ansible的安装方法多种多样,就像这里所示,我就不一一赘述了。我选择使用pip进行安装。

我打算参考这里之类的(资料),而不是费劲地用Vagrant搭建两个虚拟服务器,而是在已经启动的虚拟服务器上,尝试从Mac上进行配置。(这样更符合需求吧…)

使用Vagrant来启动虚拟服务器。

为避免 Provision 执行,执行 $ vagrant up(IP 地址设置为 192.168.33.45)。

确认与虚拟服务器的连通性。

为了确认服务器的连通性,尝试打ping。-m 代表 Module 的 “m”。Ansible 提供了相当多的可以使用的 Module,仅凭这一点就感觉比 Chef 更丰富。可以在这里查看 Module 的详细信息。

$ ansible 192.168.33.45 -m ping
ERROR: Unable to find an inventory file, specify one with -i ?

就是这种感觉,会被温柔地告知”在服务器的配置列表中没有包含这个IP”,然后询问”你没有忘记-i参数吧?”(尾部的问号表达了温柔)。

我们可以使用”-i”选项来指定一个简单列举了IP地址的服务器配置清单列表(称为Inventory)。

由于我想将Ansible文件集中在一个地方,所以我创建了一个名为/ansible的目录。虽然也可以先切换到ansible目录,然后执行命令,但由于我想在项目根目录下进行各种操作,所以我将采用以下写法。

$ echo 192.168.33.45 > ansible/hosts
$ ansible -i ansible/hosts 192.168.33.45 -m ping

接下来,会出现这样的错误信息。

192.168.33.45 | FAILED => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    while connecting to 192.168.33.45:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

要简单说,就是没有SSH连接权限。所以,需要在虚拟服务器上追加公钥,并确认通过SSH进行通信。可以通过命令$ vi ~/.ssh/id_rsa.pub来查看公钥的内容(如果使用Github的话,公钥应该已经存在了,比较随意)。

$ vagrant ssh
$ vi ~/.ssh/authorized_keys

这里,我将补充上次公开密钥的内容。接下来,请再次执行以下命令。

$ ansible -i ansible/hosts 192.168.33.45 -m ping
192.168.33.45 | success >> {
    "changed": false,
    "ping": "pong"
}

确认通畅!

但请等一下。我们的冒险从这里开始。是的,从这里开始,我们决定挑战一下“编写用Ansible构建LAMP环境的Playbook,并通过Vagrant的Provision来运行…”。


写Playbook!

在Ansible中,将任务组合在一起称为”Playbook”。

设置库存

作为本地开发团队,我们定义了一个名为development的主机组。让我们准备一个名为ansible/development的清单文件。在那里,我们将创建一个名为lamp的组。

发展

[lamp]
192.168.33.45

這樣一來,在 “開發環境下只用一台虛擬機,但在生產環境下想要將 WEB 伺服器和資料庫伺服器分開” 的情況下,我們可以在 Ansible/production 中準備 web 和 db 兩個群組,然後分別運行不同的 Playbook …這樣就可以實現。

写Playbook

我会以这样的方式尝试编写测试用的Playbook。这仅仅是一个检查Apache是否运行的Playbook。”become”这一项表示使用sudo执行这个任务。

- hosts: development
  become: yes
  tasks:
    - name: be sure httpd is installed
      yum: name=httpd state=installed
    - name: be sure httpd is running and enabled
      service: name=httpd state=started enabled=yes

执行Playbook!

首先可以进行语法检查。

$ ansible-playbook -i ansible/development ansible/development.yml --syntax-check

在Dry Run中,可以尝试“实际上不进行执行,但如果执行了会是这样的感觉…”的情况。

$ ansible-playbook -i ansible/development ansible/development.yml --check

那么,开始行动吧!

$ ansible-playbook -i ansible/development ansible/development.yml

非常直观啊,这么简单让人兴奋呢。


構成 – To compose, form, constitute.

确认最佳做法

我打算根据Ansible官方文档中的”最佳实践”来建立LAMP服务器。

目录结构

development : 当記事のInventory File。ここは各環境に合わせてください。例えば、production、stagingなんていうInventoryはよく使うことになるでしょう

development.yml : site.ymlから読み込むPlaybookファイル。それぞれの環境に応じたタスクをここに記述します

group_vars/ : グループ毎の設定ファイル

all : 全てのグループで読まれる設定ファイル

host_vars/ : hostsにあるホストごとの設定ファイル

development.yml : こんな感じで設定ファイルを置いておく

roles/ : 各タスクを格納するディレクトリ

xxxx/ : 例えばroles/httpd/みたいな感じで置いたものを、設定ファイルからhttpdタスクとして実行することが可能になります

handlers/ : 再起動や終了など、何かのタスクをフックにアクションを起こしたいときは、ここにハンドラーとして登録します

tasks/ : タスクファイル(yml)を格納。基本、task httpdとやると、roles/httpd/tasks/main.ymlが読み込まれる

templates/ : タスクで利用する設定ファイルなどの雛形を格納します。httpd.confなどをここに置いています

site.yml : マスターのPlaybookファイル

设定 site.yml

site.yml是所有大型Playbook的总体。执行方式为 $ ansible-playbook -i ansible/development ansible/site.yml ,所以当然不一定非得使用site.yml这个名字,我们可以任意选择。在这里,我们将使用development.yml进行加载。

场地.yml

- include: development.yml

让我们看一下被加载的 development.yml 文件。

---
- name: Install LAMP
  hosts: lamp
  remote_user: vagrant
  become: yes
  vars_files:
    - host_vars/development.yml
  roles:
    - common
    - httpd
    - php
    - mysql

在这里,我们使用“roles”作为任务的设置方式。正如前面所述,我们会去找到在每个角色下的Playbook(roles/xxxx/tasks/main.yml)并执行它。hosts已经配置了lamp,所以在Inventory File(development)中加载的lamp组将成为本次目标服务器。

vars_files是配置文件,在这里写入变量,可以在Playbook中以{{ “{{ hostname ” }}}}这样的方式进行引用。当然,在模板中也可以灵活使用(像Chef的node和variables的概念有点复杂…)。

设定任务

让我们来看一下安装Apache的任务。它在/roles/httpd/tasks/main.yml中进行了设置。

/roles/httpd/tasks/main.yml的本地化中文释义:

/角色/HTTP服务器/任务/主要.yml

- name: Install httpd
  yum: name=httpd state=present
  tags: [lamp, httpd]

你可以选择在name中输入yum的软件包名称,在state中选择present(当前版本)、latest(最新版本)、absent(删除)。关于这些规范的详细信息,请查看$ ansible-doc yum。

tags是在运行Ansible Playbook时使用的选项,通过指定-t httpd等选项,可以只执行带有该标签的任务。其主要用途是在某个操作失败时,使用标签来快速跳过之前成功的操作,或者在需要仅运行部分任务的情况下(例如修改php.ini),使用标签来指定任务。

检查任务清单

还可以查看实际执行的任务列表,非常方便!

$ ansible-playbook -i ansible/development ansible/site.yml --list-tasks

开始行动!

$ ansible-playbook -i ansible/development ansible/site.yml

作为 Vagrant 的 Provisioner,使用 Ansible

如果能做到这一步,剩下的就非常简单了。

Vagrant文件

设置本身就是这样的。

config.vm.provision "ansible" do |ansible|
  ansible.limit = 'all'
  ansible.inventory_path = "ansible/development"
  ansible.playbook = "ansible/site.yml"
end

limit : ここにはallを入れておきます

inventory_path : Inventory Fileのパスです。Vagrantで使用するのであれば、developmentを参照すればOKですね

playbook : Playbookのパスです。site.ymlを指定します

如果你运行$ vagrant up或者$ vagrant provision,虚拟环境应该会在瞬间建立完成。如果事先注册为Vagrant的配置管理工具,那么无需设置SSH密钥,非常方便。


整理

虽然我匆匆忙忙地完成了这个任务,但我成功地从Chef迁移到了Ansible。

请您浏览一下我在GitHub上公开的一套文件,用于搭建一个仍处于非常基础的LAMP服务器配置水平的系统。

就个人而言,将Ansible与Chef进行比较时,Ansible的优点如下:

設定が直感的(コンソールの出力も見やすいです)
ファイル構成をある程度自由に組みかえられる
設定先のサーバーを弄る必要がほとんどないので、認証周りの厄介なトラブルを避けられる

Vagrantの設定がすげー簡潔

逆而说,以下可能是缺点。

berkshelfの不在
PlaybookをScaffolding出来ない

冪等性を担保するのがChefよりしんどい

然而,我个人不太使用Berkshelf,因为它变得很难理解,而Ansible更易于使用,而且有更小的知识单元可以重复利用,所以我认为没什么问题。

关于幂等性,由于Playbook在Yaml中进行描述,所以分支和其他复杂操作会有些困难的印象。然而,正因为如此,它更加灵活。比如,如果在使用阶段是CentOS,在生产环境中是Ubuntu这样的特殊案例,我认为可以巧妙地利用清单组来处理。

希望将Playbook的Scaffolding实施起来。(我并没有仔细阅读文档,所以也许已经存在了)

因此,我已经毕业成为一名厨师。从明天开始,我将以Ansible的身份生活!请大家多多支持我!


相关链接 (Guanlian lianjie)

Ansible is Simple IT Automation

Ansible Documentation
Best Practices — Ansible Documentation

mcatm/studying-ansible
Ansible チュートリアル | Ansible Tutorial in Japanese
エージェントレスでシンプルな構成管理ツール「Ansible」入門 – さくらのナレッジ
構成管理ツール Ansibleを使ってみる | Developers.IO
Vagrant の provision を Ansible で行う – ぶるーすくりーん

bannerAds