1:HL["/_next/static/css/e0b87381b78a72d0.css",{"as":"style"}] 0:["00Nw3V7p6jjR7VBCI9FoH",[[["",{"children":["blog",{"children":[["slug","2013/04/06/about-ansible","c"],{"children":["__PAGE__?{\"slug\":[\"2013\",\"04\",\"06\",\"about-ansible\"]}",{}]}]}]},"$undefined","$undefined",true],"$L2",[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/e0b87381b78a72d0.css","precedence":"next"}]],"$L3"]]]] 4:I{"id":4896,"chunks":["896:static/chunks/896-da17be67249e7703.js","797:static/chunks/app/blog/[...slug]/page-a20797c105738917.js"],"name":"","async":false} 5:I{"id":3466,"chunks":["272:static/chunks/webpack-a5603073f1184a0b.js","253:static/chunks/bce60fc1-3138fc63e84359d9.js","961:static/chunks/961-177df6473dc74d43.js"],"name":"default","async":false} 6:I{"id":372,"chunks":["272:static/chunks/webpack-a5603073f1184a0b.js","253:static/chunks/bce60fc1-3138fc63e84359d9.js","961:static/chunks/961-177df6473dc74d43.js"],"name":"default","async":false} 2:[["$","html",null,{"lang":"ja","children":["$","body",null,{"children":[["$","header",null,{"children":["$","h1",null,{"id":"site-title","children":["$","$L4",null,{"href":"/","children":"apatheia.info"}]}]}],["$","main",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$L6",null,{}],"templateStyles":"$undefined","notFound":["$","div",null,{"children":[["$","h2",null,{"children":"Not Found"}],["$","p",null,{"children":"Could not find requested resource"}],["$","p",null,{"children":["View ",["$","$L4",null,{"href":"/","children":"all posts"}]]}]]}],"notFoundStyles":[],"childProp":{"current":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","blog","children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$L6",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","blog","children",["slug","2013/04/06/about-ansible","c"],"children"],"error":"$undefined","errorStyles":"$undefined","loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"template":["$","$L6",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$L7",null],"segment":"__PAGE__?{\"slug\":[\"2013\",\"04\",\"06\",\"about-ansible\"]}"},"styles":[]}],"segment":["slug","2013/04/06/about-ansible","c"]},"styles":[]}],"segment":"blog"},"styles":[]}]}],["$","footer",null,{"children":["$","ul",null,{"children":[["$","li",null,{"children":"Link:"}],["$","li",null,{"children":["$","a",null,{"href":"https://twitter.com/f440","children":"Twitter"}]}],["$","li",null,{"children":["$","a",null,{"href":"https://github.com/f440","children":"Github"}]}],["$","li",null,{"children":["$","a",null,{"href":"https://pinbaord.in/u:f440","children":"Pinbaord"}]}]]}]}]]}]}],null] 3:[["$","meta","0",{"charSet":"utf-8"}],["$","title","1",{"children":"構成管理ツール Ansible について - aptheia.info"}],["$","meta","2",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","link","3",{"rel":"alternate","type":"application/rss+xml","href":"/atom.xml"}]] 8:T26e6,
Ansible というサーバーの設定を管理するツールの説明。いわゆる構成管理 (CM: Configuration Management) にカテゴライズされるもので、Puppet や Chef の親戚みたいなものと考えてもらえればだいたいあってる。
リード開発者は Michael DeHaan で、現職の AnsibleWorks の前は Redhat で Cobbler や Func に携わっていたり、Puppet labs でプロダクトマネージャーしたりしているという経歴の持ち主。
Ansible は Python で書かれている。同じジャンルで Python 製というと Salt が有名。Chef の場合、レシピを書くためには Ruby の知識が必要となってくるけど、Ansible はどんな言語でもモジュールが書けるようになっているので、運用にあたって Python の知識は必要無い。
動作の点でも Puppet や Chef などのツールとまったく異なるアプローチをしている。Puppet や Chef は、サーバーとクライアントで構成され、クライアントとなるマシンはサーバーに設定を問い合わせながら、自分自身を「あるべき状態」に収束するよう変更を加えていく。Ansible の場合、サーバー側からクライアントとなるサーバー(群)に対して直接命令を送り込み結果を得る。これは Func、Capistrano、Fabric などに似ているが、これらのデプロイを目的としたツールにはない「何回やっても結果が同じ」(idempotence) という CM ツールらしさはちゃんと備えている。
ドキュメントは12ページしかなく(ちなみに、さっき数えてみたらChefのドキュメントは2834ファイルあった) 非常に習得は簡単。サーバーを立てる必要もなく、クライアントマシンもエージェントレス、加えて短期間で学習できるので手軽感は非常に高いが、モジュール機構が強力なのできわめて実用的になっている。
Ansible を理解する上で重要となる、モジュールとプレーブックについて説明する。
クライアント内での動きはモジュールという形で定義する。
パッケージのインストール、サービスの起動、ユーザーやグループの作成などの基本的なモジュールはあるが、実際には環境に合わせて不足分は自分でモジュールを作っていくことになる。
モジュールは簡単に作れる。モジュールが役割を端的に言うと、以下を行うだけである。
標準入力でオプションを受け取る
標準出力で実行結果を返す
これができる言語であれば、シェルスクリプトでも Perl でも問題ない。
実際の処理では単発のモジュールでサーバーの設定が終わることはないので、モジュールの使い方をまとめたものが必要になる。Ansible では、YAML で処理をまとめたものを プレーブック (Playbook)と呼んでいる。
例: Apache と PHP をインストールする (webapp.yml)
- hosts: webserver
user: vagrant
sudo: yes
tasks:
- name: install apache
action: yum pkg=httpd state=installed
- name: install php
action: yum pkg=php state=installed
例: 実行
# ansible-playbook プレーブック名
$ ansible-playbook webapp.yml
以上は簡単な例だが、設定ファイルを配置したり、それに併せてサービスを再起動させたりといったことも記述可能。
プレーブックには以下のような内容が含まれる:
vars
の変数は、テンプレート内で展開される。設定ファイル配置時にパラメータを変更、といった場合に利用する。
以下では、インストールから簡単なコマンドの実行までの例を挙げる。サーバー、クライアント双方で CentOS 6.4 を利用した。
Ansible を動かすためには、Python 2.6 以上と Ansible のソースコードとごくわずかな Python パッケージだけあればよい。CentOS 6 であれば Python の条件は満たせているし、EPEL で Ansible のパッケージが提供されているので、yum
でインストール可能。
# EPEL 有効化
$ sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
# Ansible インストール
$ sudo yum install ansible
他の Unix 系OSであれば、pip install ansible
でいい。
$ sudo pip install ansible
次に、サーバーからクライアントに SSH でログインできるように調整しておく。
# 以下のマシンを用意した。
# それぞれホスト名でアクセスできる
# Ansible 実行側 ... server
# 変更対象 ... client1, client2
# server側で公開鍵認証用の鍵を作成
$ $ ssh-keygen -t rsa
# client に公開鍵を配置する
$ ssh-copy-id client1
$ ssh-copy-id client2
# 試しにログインしてみる
# 頻繁に実行することになるので、公開鍵にパスフレーズを
# 設定している場合は、ssh-agent を使ってパスフレーズの
# 入力を省略できるようにしておく。
$ ssh client1
$ ssh client2
今度は、対象のサーバーを設定してみよう。環境変数 ANSIBLE_HOSTS
にあるファイルでサーバーの指定が可能。
$ cat <EOD >~/target
> [webserver]
> client1
>
> [dbserver]
> client2
> EOD
$ export ANSIBLE_HOSTS=~/target
設定の中で、[ ]
によりグループを作っている。つまり「webserver グループに client1、dbserver グループに client2 が所属している」ということを表している。グループはオプションなので、単純にホスト名を羅列するだけでもいい。試しに、対象のホストを調べてみよう。
# ansible ホストパターン --list-hosts
# ホスト名を直接指定
$ ansible client1 --list-hosts
client1
# グループ名を指定
$ ansible webserver --list-hosts
client1
$ ansible dbserver --list-hosts
client2
# all を指定した場合、全サーバーを列挙
$ ansible all --list-hosts
client1
client2
これだけで準備は完了。実行してみる。
# コマンドの書式
ansible 対象 -m モジュール名 -a オプション
# 例 ping モジュール
$ ansible all -m ping
client2 | success >> {
"changed": false,
"ping": "pong"
}
client1 | success >> {
"changed": false,
"ping": "pong"
}
-m
をつけないで、直接コマンドを実行することも可能。
# すべてのマシンでカーネルのバージョンを取得
$ ansible all -a 'uname -r'
client2 | success | rc=0 >>
2.6.32-358.el6.x86_64
client1 | success | rc=0 >>
2.6.32-358.el6.x86_64
プレーブックを実行したときは以下のようになる。
# 対象は webserver というグループ(client1 が所属)に対して、
# Apache と PHP をインストールするプレーブック、webapp.yml を実行
# Apache はすでにインストールされていたので、
# PHP のみインストールされることとなった
$ ansible-playbook webapp.yml
PLAY [webserver] *********************
GATHERING FACTS *********************
ok: [client1]
TASK: [install apache] *********************
ok: [client1]
TASK: [install php] *********************
changed: [client1]
PLAY RECAP *********************
client1 : ok=3 changed=1 unreachable=0 failed=0
ロゴのセンスは悪いけど、アプリケーション自体の仕組みはすごくセンスがいい。
他の構成管理ツールと比べると、DSL を覚えるといった「ツールを使うまでののコスト」、ツールのためのサーバー構築・運用といった「ツールを使ってからのコスト」が軽微なので、よりやりたいことに目が向けられるのもうれしい。
最近日本国内でも Chef の話題を聞くことが多いんだけど、Chef Server の運用とかオートスケールとのコンビネーションとかの情報はあまり聞かないので、たぶん割と小規模な環境でリモートサーバーの Chef-solo をキックみたいなケースが多いのかと思う。そういったところだと、Ansible のほうがふさわしいっていうことが多いんじゃないかな。
7:["$","article",null,{"children":[["$","h1",null,{"children":"構成管理ツール Ansible について"}],["$","p",null,{"id":"article-info","children":["2013.04.06"," ",[["$","span","cm",{"children":[["$","$L4",null,{"href":"/blog/categories/cm","children":"cm"}]," "]}]]]}],["$","div",null,{"dangerouslySetInnerHTML":{"__html":"$8"}}]]}]