Harada's Diary

Ansibleで楽にサーバ管理をする。

サーバの初期構築が面倒になってきたので、今更 Ansible を使いはじめました。
使い方も非常にシンプルで簡単ですし、エージェントのインストールが不要なところも素敵です。

本投稿では、基本的なAnsibleの利用方法とPlaybookの書き方を紹介します。

構成管理ツールについて


まず、構成管理ツールとはなんぞやと。

例えば、現在僕の自宅にはVMサーバがあり、そこには10台程仮想ホストを運用しています。
で、検証環境なんかで新しくサーバを構築したりしますが、手動で行う初期設定とかが結構大変なんです。

また、とあるパッケージを仮想ホスト全台にインストールしたい時や、ミドルウェアに脆弱性が見つかったときはアップデートが必要ですが、10台もサーバがあると、1台1台作業していくはすごい大変ですね。
このような環境構築やデプロイなどを何度も行う場合は自動化したいところです。

導入の背景

サーバ作業を自動化しようと考えたとき、最初に思い浮かぶのはシェルスクリプトを利用することではないでしょうか。

シェルスクリプトを使って環境構築やリリースを自動化することは可能ですが、これにはいくつか問題があります。

  • 自動化したい作業内容を、環境毎にスクリプトを作らなきゃいけない。
  • シェルスクリプトが実行途中で失敗した場合、実行前の状態に戻さなきゃならない。
    (再実行すると不具合が起こる可能性がある)
  • 依存するライブラリのバージョンアップなどにより実行が失敗する可能性がある。

このような問題を解決するには、構成管理ツールを使うと便利です。
構成管理ツールは、処理を自動化するという観点ではなく、最終的にマシンを目的の状態にする、という観点で作成されたツールのことです。

例えば、「ユーザーを追加する」という目的を考えてみます。
シェルスクリプトではそのまま「ユーザーを追加する」という操作を書くため、既にユーザーが存在する場合、何も考慮しないと再実行時に「既にユーザーが存在する」というエラーとなってしまいます。

一方、構成管理ツールでは「ユーザーが追加されている状態にする」という命令を使います。
「既に目的の状態となっているかどうか(=ユーザーが存在するかどうか)」という判断は構成管理ツールが行ってくれるため、自前で判定処理を書く必要がありません。

上記の構成管理ツールの例のように「同じ操作を何度やっても最終的な状態が同じになる」という性質を「冪等性(べきとうせい)」といいます。

環境構築やデプロイでは、冪等性を意識して処理を自動化することが望ましく、構成管理ツールはその助けとなります。


Ansibleを使ってみる

という訳で早速作業してみたいと思います。
実際の流れは以下の感じ。

  1. Ansibleをインストールする
  2. Ansibleコマンドを実行する
  3. playbookを作成・実行する

同じ様な構成管理ツールとして、ChefとかPuppetがありますが、これらと違ってAnsibleは、対象のサーバに接続していく感じ。
対象のサーバにはとくにエージェントとかいらないのもAnsibleの魅力。

Ansibleから対象サーバへはSSH経由で操作が行われます。

Ansibleをインストールする

今回作業環境となるサーバがDebianになるので、インストールはaptから行います。

apt-add-repository ppa:rquillo/ansible apt-get update apt-get install ansible 

Redhat系でもyumで簡単にインストールできます。

rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm yum install ansible 

インストールされた対象バージョン

 root@manage:/home/harada# ansible -version ansible 2.2.0.0 config file = /etc/ansible/ansible.cfg configured module search path = Default w/o overrides 

インストールすると /etc/ansible 配下には以下のファイルとディレクトリができます。

 root@manage:~# ll /etc/ansible/ total 52 -rw-r-r- 1 root root 14413 Nov 20 17:34 ansible.cfg -rw-r-r- 1 root root 404 Nov 20 16:45 hosts drwxr-xr-x 2 root root 4096 Nov 20 17:34 roles/ 
  • ansible.cfg
    ansible の設定ファイル
  • hosts
    ansible で実行させる対象ホストを指定するファイル。
    ansible コマンドのオプションでhostsファイルを指定しなければ、このファイルに記載されている内容が読まれます。
  • roles ディレクトリ
    インストール後は空のディレクトリですが、ここに playbook を複数格納して、メインの playbook で include ディレクティブを使用して取り込むことができます。

ansibleの設定

ansible.cfgの一部設定を編集します。
下記へと変更します。

root@manage:/etc/ansible# vi ansible.cfg ask_sudo_pass = True ask_pass = True remote_user = harada 

ask_passのコメントアウトを外すことにより、ansibleコマンドの実行時にSSHに必要なパスフレーズを問い合わせるようになります。
※デフォだとSSHログインが鍵認証になります。
また、sudoする際はパスワードが必要になるので、ask_sudo_passもTrueにしておきます。

加えて、SSHを行うために必要なユーザも指定しておきます。
remote_userの箇所は各々の環境に合わせてください。

Ansibleコマンドを実行する

以下、管理サーバにて実施。

カレントディレクトリにて hosts という名前のファイル (インベントリファイルと呼ぶ。Ansible はこのファイルに記載したマシンにしかアクセスできない) を作成する。
ここでは10.0.0.3というホストを登録する。

root@manage:~# echo 10.0.0.3 && cat ./hosts 10.0.0.3 

次に、Ansible を使って ping 疎通してみる。
ここでは SSH パスワード認証するためのオプション -k を指定している。

root@manage:/home/harada# ansible -i ./hosts 10.0.0.3 -u harada -k -m ping SSH password: 10.0.0.3 | FAILED > to use the 'ssh' connection type with passwords, you must install the sshpass program 

おっと、失敗。
なにやらsshpassってのがインストールされてねぇよと怒られている様です。

という訳でパッケージをインストールします。

 root@manage:/home/harada# apt-get install sshpass Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: sshpass 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded. Need to get 10.2 kB of archives. After this operation, 51.2 kB of additional disk space will be used. Get:1 http://jp.archive.ubuntu.com/ubuntu/ trusty/universe sshpass i386 1.05-1 [10.2 kB] Fetched 10.2 kB in 0s (78.0 kB/s) Selecting previously unselected package sshpass. (Reading database ... 61614 files and directories currently installed.) Preparing to unpack .../sshpass_1.05-1_i386.deb ... Unpacking sshpass (1.05-1) ... Processing triggers for man-db (2.6.7.1-1ubuntu1) ... Setting up sshpass (1.05-1) ... 

で、再度実行。

 root@manage:/home/harada# ansible -i ./hosts 10.0.0.3 -u harada -k -m ping SSH password: previous known host file not found 10.0.0.3 | FAILED ; Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host. 

またもや失敗。
このサーバへは一度もSSHログインをしていなかったのだが、どうやらフィンガープリントへ登録しておく必要があるみたいです。

なので一度フィンガープリントへの登録が済ませておきます。

 root@manage:/home/harada# ssh harada@10.0.0.3 The authenticity of host '10.0.0.3 (10.0.0.3)' can't be established. RSA key fingerprint is ba:73:75:0c:7c:7a:db:40:2b:53:04:3a:94:7a:ba:13. Are you sure you want to continue connecting (yes/no)? yes 

で、再チャレンジ。

 root@manage:/home/harada# ansible -i ./hosts 10.0.0.3 -u harada -k -m ping SSH password: 10.0.0.3 | SUCCESS > { "changed": false, "ping": "pong" } 

上記の様な応答が返ってくればOK。

playbookを作成・実行する

moduleを組み合わせて対象サーバに実行する処理をまとめて書いたもの。
Chefのレシピに近くて、書き方はyml形式。

root@manage:/etc/ansible/roles# cat ping.yml --- - hosts: all remote_user: harada tasks: - name: pingしてみる ping: 

hostsに登録してあるサーバすべてにpingモジュールで疎通確認をするもの。
書き方はこんなかんじ

 --- - hosts: all remote_user: harada tasks: - name: pingしてみる ping: 

「---」はここから定義を始めますという意味です。
実行先の情報と実行先の権限を指定したり、変数を定義します。

  • - と hosts、hosts: と all の間はスペースが絶対に必要です。
    tasks: はここから先は実行する項目を書くよという意味です

タスク(項目)ごとに - name: で実行する項目を指定してあげます。
項目ごとに「-」をつけてあげます。
hosts の行から一貫した作業になりますので、インデントして階層構造にしています。

※実行結果

 root@manage:/etc/ansible/roles# ansible-playbook ping.yml SSH password: SUDO password[defaults to SSH password]: PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [localhost] ok: [web] ok: [db] ok: [vyos] ok: [dev] ok: [kanshi] ok: [ns] TASK [pingしてみる] **************************************************************** ok: [web] ok: [vyos] ok: [db] ok: [localhost] ok: [kanshi] ok: [ns] ok: [dev] PLAY RECAP ********************************************************************* db : ok=2 changed=0 unreachable=0 failed=0 dev : ok=2 changed=0 unreachable=0 failed=0 kanshi : ok=2 changed=0 unreachable=0 failed=0 localhost : ok=2 changed=0 unreachable=0 failed=0 ns : ok=2 changed=0 unreachable=0 failed=0 vyos : ok=2 changed=0 unreachable=0 failed=0 web : ok=2 changed=0 unreachable=0 failed=0 

こんな感じでOKが帰ってくれば成功。
unreachableとかfailedとか帰ってきたら失敗してますよー的な。
ちなみにsetupはサーバ情報を取得してる様で、設定でoffにすることもできます。

もうひとつ、yumでパッケージのupdadeをかけるときのplaybook

 root@manage:/etc/ansible/roles# cat yum_upgrade.yml --- - hosts: web db kanshi ns dev remote_user: harada become: yes tasks: - name: yum update yum: name=* state=latest 

ansibleのモジュールにはyumコマンドが存在し、
stateにlatest指定で最新版に更新する、というものになります。

ちなみにyumモジュールのオプションはこんな感じ。

パラメータ

必須

デフォルト値

選択肢

説明

conf_file

no

-

-

対象ホストで /etc/yum.conf以外のファイルを使用する場合に指定する

disable_gpg_check

no

no

yes no

パッケージの署名チェックを無効にする

disablerepo

no

-

-

無効にするリポジトリを指定する。複数の場合はカンマ区切りで記述する。

enablerepo

no

-

-

有効にするリポジトリを指定する。複数の場合はカンマ区切りで記述する。

list

no

-

-

?

name

yes

-

-

パッケージ名を指定する。『state=latest』かつ『name=*』を指定した場合は『yum -y update』を実行する。URLやローカルパスの指定も可能。

state

no

present

present latest absent

present:インストールされていること。 latest:最新に更新する。 absent:インストールされていない。

少しだけ触ってみただけですが、nagiosの監視追加とか、NTPの同期先変更とか遊べそうなことはたくさんありそうなので、利用価値は高いツールです。

※参考サイト
http://iwamocchan11.hatenadiary.jp/entry/2015/09/23/193419
http://qiita.com/yamasaki-masahide/items/3bd2392cad9ac8811197
http://qiita.com/okochang/items/f264825e538dbce5dfac
http://yktmnb.b.osdn.me/?p=151
http://centos.sabakan.red/entry/2015/07/01/140000
http://blog.aotak.me/post/124898363221/ansible-のインベントリファイルを使ってリモートホストに接続する
http://blog.pg1x.com/entry/2016/01/19/222120
http://www.atmarkit.co.jp/ait/articles/1603/24/news014.html