文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

ansibleを学ぶ:vol01:vagrantを使ってansibleを動かしてみる

chef・puppetと競合するサーバ管理ツール、ansibleを最近勉強しています。


f:id:treeapps:20160219001058p:plain

ansibleを触ってみて、以下の事を思いました。

ruby使い capistrano chef 重厚で習得が大変。大規模向け?
python使い fabric ansible 軽量で習得が容易。小〜中規模向け?

capistranoとchefはほとんど触ってませんが、chefとansibleは、capistranoとfabricの関係に似ているな、と思いました。

私は軽量で習得が容易なものが好きなので、仕事でfabricを使っています。


では早速ansibleについて、勉強していきましょう。

※ mac上でvagrantとansibleをインストール・実行します。

その前にまずは専門用語と、それが何をする道具なのかをおさらいします。

各ソフトウェアと役割

項目 python ruby その他 何をするか
仮想環境管理 - - virtualbox、vmware 仮想OSの管理・入れ物
仮想環境構築 - vagrant docker 仮想OSをプログラムで作成・操作
サーバ操作・デプロイ fabric capistrano - 主にシェルスクリプトの代用でデプロイで使用
サーバ管理 ansible chef solo、chef server - ソフトウェアのインストール、OSの基本設定等
サーバ構成テスト - serverspec - 作り上げたOS・環境をテストする

大体こんな感じです。
ruby製が多いですが、世界的にはpythonの方が圧倒的に利用されているんですよね。

「サーバ操作」と「サーバ管理」の部分は微妙に役割が被っています。
fabric・capistranoはシェルスクリプトをリモートで実行するためのもので、主にデプロイスクリプトで利用されます。sudoも容易に実行でき、並列にデプロイする事もできます。

ansible・chefは主にソフトウェアのインストールを行います。シェルスクリプトも実行できるので、fabric・capistranoと同じ事もできます。

vagrantのインストール

Vagrant by HashiCorp

DMG形式で簡単にインストールできます。

ansibleのインストール

homebrewで簡単にインストールできます。

brew install ansible

参考程度ですが、CentOSにansibleをインストールする場合は以下の通りです。

sudo rpm -ivh http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
sudo yum -y install ansible
ansible --version

これでvagrantとansibleがインストールできました。

vagrantで仮想環境を構築する

Vagrantfile

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

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
	config.vm.define :git do |node|
		node.vm.box = "chef/centos-6.5"
		node.vm.network :forwarded_port, guest: 22, host: 2001, id: "ssh"
		node.vm.network :private_network, ip: "192.168.33.11", error_check: false
	end

	config.vm.define :node1 do |node|
		node.vm.box = "chef/centos-6.5"
		node.vm.network :forwarded_port, guest: 22, host: 2002, id: "ssh"
		node.vm.network :private_network, ip: "192.168.33.21", error_check: false
	end

	config.vm.define :node2 do |node|
		node.vm.box = "chef/centos-6.5"
		node.vm.network :forwarded_port, guest: 22, host: 2003, id: "ssh"
		node.vm.network :private_network, ip: "192.168.33.22", error_check: false
	end
end

主にこんな感じで設定します。
private_networkについては先日以下の記事を書いたので合わせご覧下さい。
vagrantのprivate_networkのIP指定でエラーが出る人は今すぐアップデートしましょう - 文系プログラマによるTIPSブログ

vagrantの主な操作

とりあえず以下を覚えておけばよいです。

内容 全OSを対象とする時 対象を個別に指定したい時
仮想環境を起動 vagrant up vagrant node1 node2
仮想環境のステータス vagrant status vagrant status
仮想環境のシャットダウン vagrant halt vagrant halt node1 node2
仮想環境の削除 vagrant destroy vagrant destroy node1 node2

例えば仮想OSが3つ合ったとして、「vagrant destroy」とすると3つとも削除対象になります。「vagrant destroy node1」とするとnode1だけが削除対象になります。

仮想環境の起動時間はどれくらい?

オーソドックスにCentOS6.5を起動してみました。
結果は・・・2分52秒 でした。3台起動しているので、遅いですね。

ansibleでサーバ設定する

まずは各仮想環境にパス無しsshできるようにする

ansibleはパスワード無しのsshが必須になります。
幸いvagrantは仮想環境作成と一緒に鍵も作成してくれます。これを利用すると、簡単にパスワード無しsshが出来る状態を作れます。以下のコマンド1発で、全仮想環境の設定が書き込まれます。

vagrant ssh-config > ~/.ssh/config

一応中身を見てみましょう。

treemacpro-2:vagrant tree$ cat ~/.ssh/config
Host git
  HostName 127.0.0.1
  User vagrant
  Port 2001
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/tree/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Host node1
  HostName 127.0.0.1
  User vagrant
  Port 2002
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/tree/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Host node2
  HostName 127.0.0.1
  User vagrant
  Port 2003
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/tree/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

これで、「ssh git」「ssh node1」「ssh node2」でsshできるようになります。

ansibleのフォルダ構成

最初からplaybookを使う前提でいきます。

ansibleにはベストプラクティな構成を、公式が提案しています。
http://docs.ansible.com/playbooks_best_practices.html:title:bookarm
もう少し噛み砕いて画像で見てみると、以下のようになります。
f:id:treeapps:20140612010204p:plain

起点となる実行ファイル

ansible-playbookコマンドに渡すファイルは「site.yml」です。
site.ymlを起点に、各roles/XXXX/tasks/main.yml を実行していきます。

コマンドを実行するサーバの設定

コマンドを実行するサーバはインベントリと言われるhostsファイルで管理されます。
各サーバはグループ分けする事ができ、site.ymlではグループ名に対し、どのrolesを適用するかと設定していきます。インベントリは必ず指定する必要があります。

定数

group_varsフォルダ配下のファイルは定数ファイルで、各ファイルで変数として呼び出す事ができるようになります。ソフトウェアのバージョンやパスを記述したりします。

ansibleを実行してみる

シンタックスチェック

シンタックスエラーを事前にチェックする事ができます。

ansible-playbook -i hosts simple-playbook.yml --syntax-check

タスク一覧

どんなタスクが定義されているか一覧表示する事ができます。

ansible-playbook -i hosts simple-playbook.yml --list-tasks

dry-run

もし実行したらどうなるか、のシミュレーション結果を見る事ができます。

ansible-playbook -i hosts simple-playbook.yml --check

playbookを実行!

これでplaybookを実行します。

ansible-playbook -i hosts  simple-playbook.yml

困った点

基本的にsudoになってしまう

vagrantで作業しているせいもあるかもしれませんが、基本的に全てsudoでコマンドを実行する事になります。

ユーザ:グループを変更したい場合は、

name: Change ownership of Tomcat installation
  file: path={{TOMCAT_HOME}} owner=tomcat group=tomcat state=directory recurse=yes

こんな感じで一旦root:rootから、tomcat:tomcatに変更したりしていきます。

sudoを使わないコマンドよりもsudoを使うコマンドの方が多いので、site.ymlのsudo:はyesになってしまいました。

ダウンロードが遅い

当たり前ですが、例えばopenjdkをwgetする部分、滅茶苦茶遅いです。数百メガもあるファイルをサーバ台数分DLしようとするので、ローカルネットワークに配置しておいて、それをコピーする形にしないととんでもなく時間がかかります・・・

あれどうやるの?

java -jar xxx.war

hostsで設定したgitですが、gitbucket専用の環境としました。
Releases · gitbucket/gitbucket · GitHub
gitbucketはwarだけで簡単に動くgithubクローンで、javaコマンドだけで動きます。
しかし、以下のようにするとansibleが終了しません。

- name: Start gitbucket
  command: java -jar /tmp/gitbucket.war &

調べてみると、非同期オプションと何秒待つかのオプションがありました。
以下のように指定すると、非同期コマンドも正常に終了します。

- name: Start gitbucket
  command: java -jar /tmp/gitbucket.war &
  async: 10
  poll: 0

勿論ansible-playbook終了後もちゃんとgitbucketのプロセスは生き続けます。

雑感

ansibleを軽く触ってみたわけですが、


次のプロジェクトで絶対に使う!

(こっそりバレないように・・・)

と思っています。これは大変便利です。
最初は頑張ってrolesを書かないといけませんが、1回書くと後は必要なrolesを組み合わせていくだけなので、本当に楽です。vagrant destroyして仮想環境を破壊し、vagrant upで新たに仮想環境を作り直し、まっさらな環境がすぐにできる。凄いです。

chefと違いymlを使った軽量で習得が容易な仕組みなので、すぐ覚えられます。

ネット上でchefとansibleの比較を見かけますが、

複雑な環境ではchefが有利。だが、そんな複雑な環境はそんなに無いのでは?複雑な環境にする時点で設計を誤っていないか?それならansibleでいいんじゃないか?

等という意見があります。

本当に巨大なシステムでなければ、シンプルにansbleを使う方がいいのかもしれませんね。

Ansible実践ガイド 第2版 (impress top gear)

Ansible実践ガイド 第2版 (impress top gear)

ansibleを学ぶ:vol01:vagrantを使ってansibleを動かしてみる - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol02:Oracle JDK1.8のインストール、ユーザパスワード設定等 - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol03:実行中のホスト名を書き込む、変数の値に変数を使用する - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol04:よくハマる部分とその解決法 - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol05:対象サーバのid_rsa.pubを対象サーバのauthorized_keysに登録する - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol06:mysql-serverのインストールからcreate databaseまでを自動化する - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol07:figletで動的にホスト名をmotdに書き込んでニヤニヤする - 文系プログラマによるTIPSブログ