いまさらAnsibleスタディー?!
と思う方もいらっしゃるかもしれませんが、
特にDevOpsの自動化ツールをご利用していない方に
Ansibleを教えてあげたいと思っております。
初心者方にも役に立つと思っております。
( 実は、社内の新人にAnsibleをスタディーするためw )
アジェンダは以下の通りです。
1.Ansibleとは?
2.Ansibleに関する必要知識
3.Ansibleの構成
4.Ansibleの実習
1.Ansibleとは?
🔗公式ページ
🔗ドキュメントページ
Pythonで開発されたProvision & Configurationマネージャーツールの一つで
構築及び管理をより簡単にすることができる DevOpsの自動化ツール の一つです。
基本オープンソースツールで無料でございます。(Github 6位)
似ているツールとしては、Chef
, Puppet
があります。
デプロイ先のエージェントが不要でrubyが不要、設定ファイルが少ないなどの
特徴がChefとの大きな違いのようです。
他のツールよりAnsibleのメリットは以下の通りです。
- Ad-hocサポート
- Simple
- SSH(非Agent)
- Not DSL (非 Ruby開発者)
- 並列 provisiongサポート
- plug-and-play (module, plugin 利用及び開発可能)
🔗DevOpsの自動化ツール、Ansibleの人気の理由は
🔗構成管理ツールとしてAnsibleを選ぶべき理由
2.Ansibleに関する必要知識
1) DevOps
何回かDevOpsというキーワードが出てきたんですね。
Ansibleを学ぶ前には DevOps の知識が必要でございます。
DevOps とはContinuous Delivery(持続的なデリバリー) の
メカニズムを運用まで拡張して具現したことです。
一つのSoftwareを開発するためには色んな人が同時に開発できる環境が必要、
数千人の利用者を対象にするためには、サーバとストレージ、
運用体制など、裏側で管理しないといけないインフラ環境も備えなければならないです。
それが Ops(運営者) の役割です。
この上で、Dev(開発者) はどんどんシステムが拡張したくて開発生産性を高める新しいFWを
導入したいですが、Ops(運営者) は提供するサービス及びソフトウェアの安全性にもっと関心
を寄せて、安全性が保障されない理由で避けています。
お互いにそれぞれの目的を持ってそれぞれのプロセスでそれぞれのツールを利用して開発に着手していることです。こんな違いのため、DevとOpsには衝突が発生します。
こういう背景で出てきたのが DevOps でございます。
https://ja.wikipedia.org/wiki/DevOps
DepOps とはソフトウェア開発者とIT従事者の間で疎通、協業、融合を強調した
ソフトウェア開発方法論であり、ソフトウェア開発とIT運営間の相互依存関係についた産物でございます。
組織でDevOpsの役割はソフトウェア商品とサービスを早く生産することに
役立つ任務を遂行することになります。
DevとOps間にその目的を一致させ、プロセスや道具に対する接近を共有し、
その差を減らすことを目的としている。
このような自動化ツールの導入は開発から運営に至るまで開発の全過程において、進捗状況に合わせて必要な時に必要な環境を自由に拡大縮小できるようにすることで、システムスケイルリにすごく自由度を提供します。
2) 冪等性
Ansibleの特徴のひとつは、**冪等性(べきとうせい)です。
冪等性はリモートホストの状態を一定に保つためのポリシーですね。
原則としては【Playbookは繰り返し実行してもリモートホストの状態が変更されないように記述】**することです。
もちろん、初回実行時はリモートホストに変更が全て行われます。
しかし、Playbookを変更しない限り、繰り返して実行してもリモートホストに変更が行われません。
それが重要ポイントです!
これは、もしリモートホストに意図しない変更が行われた場合、
Playbookの実行によりその変更を検知できるとも言えますね。
冪等性を保ったPlaybookを維持することで、
####継続的なリモートホストの状態管理を行えるようになります!
あとで、【4.Ansibleの実習】で ansibleを動かしながら、
各タスクのモジュールの結果が**"changed"以外、"ok"**というところが、
実際冪等性が実行されるところなので、一緒に見てみましょう!
もちろんansibleでは冪等性をサポートしていないモジュールも存在します。
その体表的なものがshell, command, fileモジュールでございます。
なるべく、利用することを避けた方が良いと思っております。
3) YMAL
YAML(YAML Ain't Markup Language)はXML, C, Python, Perl, RFC2822で定義されたe-mail 様式で概念を得て作られた'人が簡単に読める'データ直列化様式でございます。
文法は相対的に理解し易いので、可読性が良いです。
ruby, python開発者は propertyファイルで活用していますが、c, c++, java開発者にはよく使われないらしいです。
4) インベントリファイル
Ansible は、インフラ内の複数システムに対して同時に動作します。
Inventory file は、 Ansible が動作する対象のシステムを列挙
するためのファイルです。
もちろん必須ではありません。
使い方としては、Hostだけを列挙して設定したり、
グループを指定してHostを列挙して設定したり色んな便利な追加方があります。
デフォルトのパッチは/etc/ansible/hosts
でございます。
私は、Ansible以外にもCapistrano
なども利用していますので、
ssh config
に設定するのが便利です。
なので、ssh config
のHostネームだけを./ansible/host
に列挙して
グルーピングだけをしています。
グルーピングのメリットはインベントリファイル内で複数のホストのグループして、
独自的にタスクを実行することができます。
あとで、【4.Ansibleの実習】で利用することを見てみましょう。
5) Playbook
Playbookは遠隔ホストの状態を定義します。
もちろん、yaml文法を採用してポリシーを記述します。
一つのPlaybookは一つまたは一つ以上のplayを持ち、
playの目的はそれぞれのホストに良く定義されているroleとtaskを
マッピングする役割を引き取っています。
場合によって、Playbookにrole
を定義せずにすぐtaskを利用することも可能ですが、
再利用, タスクハンドリング
などを考えたら、良い利用方ではありません。
以下に例のよう、指定Host, 権限, 変数設定, マッピングするroleなどを定義することが可能です。
#./playbook.yml
---
- name: web
become: true
hosts: all
user: fusic
vars_files:
- vars.yml
roles:
- common
- apache
- php
- postgresql
あとで、【4.Ansibleの実習】の例示を見たらすぐ理解できると思っております。
3.Ansibleの構成
構成を説明する予定でしたらが、上の【2.Ansibleに関する必要知識】でほぼ出てしまいまして、
残りは、【4.Ansibleの実習】から説明させて頂きます。
4. Ansible実習
実習環境はMacでございます。
・実習構成
Ansibleを動かすためのHostサーバがあります。
そして、2つのWebサーバと 1つのDBサーバをAnsibleで構築します。
その後、2つのWebサーバにCakePHPFrameworkのWebアプリケーション
を入れるため、
taskを調整した後、Ansibleを動かしてDBサーバを変更します。(冪等性)
その後、2つのWebサーバにCakePHPFrameworkのWebアプリケーション
を入れて
DBサーバ(外部サーバ)の接続設定をします。
そして、動作確認したらゴールになるます。
よろしくお願いいたします。
※ 実習に必要なリソースは以下のリポジトリで共有させて頂きます。
🔗leedohyung-dba/ansible_study
1) 各サーバ生成
今回は、vagrantでVirtualBox の 仮想サーバ(VM)にサーバを立ち上げます。
以下のVagrant Cloudでcentos7
を検索すると、vagrant boxを共有していますので、
そのboxを利用しましょう。
🔗Vagrant Cloud
クリックして詳細ページに行くと、以下のように導入する方法がありますが、
そのまま実行せずに、私のリポジトリのvagrant/Vagrantfile
を自分のディレクトリにコピーして、
中のboxの名をVagrant Cloudで探したbox名に変更してから実行します。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.define "host" do |node|
node.vm.box = "geerlingguy/centos7"
node.vm.hostname = "host"
node.vm.network :private_network, ip: "192.168.43.51"
end
config.vm.define "web.a" do |node|
node.vm.box = "geerlingguy/centos7"
node.vm.hostname = "web.a"
node.vm.network :private_network, ip: "192.168.43.52"
end
config.vm.define "web.b" do |node|
node.vm.box = "geerlingguy/centos7"
node.vm.hostname = "web.b"
node.vm.network :private_network, ip: "192.168.43.53"
end
config.vm.define "db" do |node|
node.vm.box = "geerlingguy/centos7"
node.vm.hostname = "db"
node.vm.network :private_network, ip: "192.168.43.55"
end
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
end
vagrant up
※ これからは全てhostのVM中で行うことになります。
2) HostサーバにAnsibleインストール
Hostサーバにsshアクセス後、追加パッケージEPELをインストールします。
# ssh アクセス
vagrant ssh host
# EPELインストール
wget https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# 有効にする
sudo rpm -Uvh epel-release-6-8.noarch.rpm
そして、yumでAnsibleをインストールします。
# Ansibleインストール
sudo yum -y install ansible
# バージョン確認
ansible --version
3) web_a, web_b, dbのそれぞれのサーバにssh config設定をします。
hostの中でweb_a, web_b, dbのサーバにssh [HostName]でアクセス出来るように設定します。
※ 詳しい内容省略
4) ansibleコマンド
ansible
のコマンドには以下の二つがあります。
- ansible : ホストに一つの状態を定義できるコマンドです。
-
ansible-playbook : ホストにのPlaybookとして状態を定義するコマンドです。
※ 詳しい使い方としては、ドキュメントから頂けます。
まず、ansible
コマンドを使ってみましょう。
学習するansibleディレクトリを生成して、
その中にhost
というインベントリファイルを生成します。
[web_group]
web_a
web_b
[db_group]
db
※ デフォルトインベントリファイル:/etc/ansible/hosts
各ホストにPingを投げてみましょう。
ansible all -i host -m ping
また、web_groupのホストたちにtree
というツールをインストールしてみましょう。
ansible web_group -i host -m yum -a 'name=tree state=present' --sudo
設置が成功してますが、注目するところは、changed:のところです。
もう一度同じ命令を投げるとchangedではなく、okが出ます。(冪等性)
-m
のオプションを入れないとデフォルトモジュールはCommand
になります。
ansible all -i host -a "/bin/echo hello"
Localhostにも命令を投げることができます。
ansible "127.0.0.1," -c local -m yum -a 'name=tree state=present' --sudo
インベントリファイルがなくても、ssh configのホスト名をそのまま使えます。
ansible all -i "web_a," -a "/bin/echo hello"
5) playbookでサーバ構築
じゃー、本格的に上に差し上げた構成図の通りサーバを構築してみましょうかね−
もう一度構成図を置いておきます。
さて、私の学習リポジトリにあるansibleディレクトリを皆さんの環境に
コピーして配置してください。
(ansibleコマンドを実行するhost VM内で)
🔗leedohyung-dba/ansible_study
ざっくり、その中の構成を説明させて頂きます。
・ansible playbookの構成
.
├── host 👉 【インベントリファイル】
├── db.yml 👉 【DBサーバのPlaybook】
├── web.yml 👉 【WEBサーバのPlaybook】
├── roles 👉 【それぞれの状態定義(タスク)があるroleたち】
│ ├── apache
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── ...
│ ├── aws-cli
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── ...
│ ├── common
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── ...
│ ├── php
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── ...
│ └── postgresql
│ ├── tasks
│ │ └── main.yml
│ └── ...
└── vars.yml 👉 【交通で使う変数定義】
上端の【2.Ansibleに関する必要知識】でPlaybookの紹介をさせていただきましたとおり、
各Playbookがありまして、一つまたは一つ以上のplayを持ちます。
そして、playの目的はそれぞれのホストに良く定義されているroleとtaskをマッピングしています。
web.ymlのPlaybookを説明させて頂きます。
---
- name: web
# Ansible1.9からはsudo/suの代わりにbecomeを使う
become: true
# webグループだけにタスクする
hosts: web_group
user: vagrant
vars_files:
- vars.yml
roles:
- common
- apache
- php
実行する権限、ホスト(グループ)、ユーザー、編集、rolesを定義しています。
playbook及び各状態定義ファイル(task)の中に何をやっているのか細かく説明コメントを書いて置きましたので、ご覧下と、モジュールの使い方がわからない方は、ドキュメントをご覧ください。
例えば copyのモジュールに関しては🔗こちらを…
vars.ymlに定義されているmain_username
などを好きに変更した後、
他のところは見て大体理解してくださったら嬉しいです。
・ansibleでサーバ構築
じゃーまず、web_aサーバとweb_bサーバを構築してみます。
ansible-playbook -i host web.yml
いい感じですね。
次はdbサーバを構築してみます。
ansible-playbook -i host db.yml
...
44つのok(冪等性でチェックだけ)と41のchanged(状態変更)
になりました。
こちらもいい感じですね。
・構築されたWEBサーバの動作テイスト
次はansible
コマンドで./index.php を各Webサーバに配置して、
正常に動作しているか確認します。
※ scp, mount などで簡単に可能ですが、練習のためです。
ansible all -i "web_a," -m template -a "src=./index.php dest=/var/www/html/index.php owner=lee group=lee" --extra-vars '{"host_name":"WEB_A"}' --sudo
ansible all -i "web_b," -m template -a "src=./index.php dest=/var/www/html/index.php owner=lee group=lee" --extra-vars '{"host_name":"WEB_B"}' --sudo
その後、以下のように動作テストしまします。
・アクセスurl: http://192.168.43.52/
・結果:以下の文言があちこちふざけているとオケーです!
・アクセスurl: http://192.168.43.53/
・結果:以下の文言があちこちふざけているとオケーです!
・CakePHP3のアプリケーションを入れてDBサーバの動作テスト
次は、各WebサーバにCakePHP3のFrameworkを入れて見ましょう!
しかし、その前に必要なAnsible改善事項がいくつかあります。
それは、以下の通りです。
👉 DBサーバに外部からアクセス出来るように設定する
postgresql.confに以下を行を追加します。
#./ansible/roles/postgresql/files/postgresql.conf
...
listen_addresses = '*'
...
pg_hba.confに以下を行を追加します。
#./ansible/roles/postgresql/templates/pg_hba.conf2.j2
...
host all all 0.0.0.0/0 trust
そして、DB生成ぐらいはやって置きますかね。
以下の行を追加します。
#./ansible/roles/postgresql/tasks/main.yml
...
# データベースを作成
- name: create database
become: true
become_user: postgres
postgresql_db: name={{ db_name }} login_password={{db_user_password}}
#./ansible/vars.yml
...
db_name: ansible_std
...
その後、ansibleをまた動かすと、追加した部分だけ変更されます。(冪等性👍)
ansible-playbook -i host db.yml
※ ansibleコマンドにはテストするための-Cオプションがあります。
実際は反映しなく、状態定義の実装に失敗があるか確認するための目的です。
ansibleは残念ながら失敗した時、失敗する前のやつがRollBackされないです。
なので、冪等性がないモジュールが含めているTaskでしたら、
一回テストすることをオススメします。
じゃー環境の準備は出来ましたので、CakePHPアプリケーションを設置します。
各Webサーバに以下のようにCakePHP3のFrameworkを入れて見ます。
これからは、web_a, web_b で直接アクセスして作業しましょう。
※ 以下のやつもAnsibleで頑張ったら出来ますが、これは環境よりアプリケーションの配置なので、
Capistranoとかの別のツールが正常系です。
# composer.phar設置
curl -s http://getcomposer.org/installer | php
# CakePHPアプリケーション設置
php composer.phar create-project --prefer-dist cakephp/app lee
そして、CakePHPアプリケーションの外部DBサーバの接続設定をします。
// ./lee/config/app.php
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Postgres',
'persistent' => false,
'host' => '192.168.43.55',
'port' => '5432',
'username' => 'postgres',
'password' => '1q2w3e',
'database' => 'ansible_std',
'encoding' => 'utf8',
'timezone' => 'UTC',
'flags' => [],
'cacheMetadata' => true,
'log' => false,
'quoteIdentifiers' => false,
'url' => env('192.168.43.55', null),
],
],
そうして以下のurlにアクセスすると
http://192.168.43.52/lee/
http://192.168.43.53/lee/
CakePHP3のアプリケーションとして設定など全ての準備完了されたことが確認できます。
最後にテーブルを一つ生成して、基本的な掲示板ページをback
でパバット生成します。
bin/cake bake all users
その後、
以下のそれぞれのWEBサーバにアクセスすると
http://192.168.43.52/lee/users
http://192.168.43.53/lee/users
同じDB(外部サーバ)を見ているそれぞれのWEBアプリケーションを開けます。
これは一つのサーバが死んだら他のもう一つのサーバを立ち上げる
デュアルサーバー見たいになっていますねw!!!
ある程度終わって気がしますので、構成図をもう一度確認しましょうか。
Um! いい感じですね〜
構成図にAWS S3にバックアップすることが表示していますが、
taskの内容を見ると頑張って実現しておきましたので、
これは皆さんがPlaybookになれるため、頑張って理解してみましょう!
以上、ちょっと長くなりましたが、
Ansible自体を知らない人が本番に使える人になるまでのスタディー
の記事でした。
(韓国人で頑張って日本語書きましたが、やっぱり文書が文法問題だらけかも…)
ありがとうございます!👏👏