サーバーの運用管理には「課題」がたくさんあります。
例えば
- 毎日数十台のサーバーを構築する
- 1つ1つ設定を変えて構築する
- サーバーを100%正確に構築する
- セキュリティを担保する
- 数分程度でサーバーを構築する
- 誰でも同じレベルでサーバーを構築する
などなど、課題はたくさんあります。
どうすればいいのでしょうか?
AWS EC2 を Ansible で構成管理をする場合の設定方法については以下の記事を参照ください。
ansible-playbookの作成方法&使い方については以下の記事を参照ください。
インフラ構成管理の重要性
「インフラ」とか「構成管理」という言葉を聞いたことはあるでしょうか?
インフラとは、サーバーやネットワークなどシステムを動かす基盤のことを言います。
ITの世界では
- サーバー
- クライアント
- L2スイッチ
- ルーター
- ミドルウェア(Apache、オラクル、MySQL)
- ファイアウォール
- ストレージ
などシステムを動かすための土台を作るものすべてを言います。
インフラ構成管理とは、上記のようにシステムの基盤となる機器の構成を管理するということです。
イメージしにくいと思うので具体的に言うと、
- サーバー100台に対してIPアドレスを割り当てる
- IPアドレスが重複しないようにする
- どのサーバーがどのIPか把握する
- 障害時・機器の入れ替え時でも正しくIPを設定する
- 環境が変わったらIPアドレスを更新する
など、何がどうなっているのかを正しく把握できている状態です。
もしこれがきちんと管理できていないと、
- どのサーバーがどのIPか分からない
- 新サーバーにどのIPをつければいいのか分からない
- 障害が発生しても原因の特定に時間が掛かる
- ヒューマンエラーが多発する
など様々なトラブルを引き起こします。
→その結果、業務時間が大幅に増えます。(赤字になります)
昔と今のインフラエンジニアの役割が変わっている
昔と今の比較をしてみるとこんな感じでしょうか。
昔 → 物理サーバー
今 → 仮想・クラウド・物理混在環境
昔 → 一度構築したら変更しない
今 → パッチが出たらすぐ適用、常に最新にアップデート、セキュリティ重要
昔 → 時間を掛けて構築
今 → 朝構築依頼、夕方リリース
昔 → 重鎮、職人のサーバー管理者がいる
今 → 数年でどんどん人が入れ替わる環境
昔と比べると時代と共に価値観がどんどん変わっているような気がします。
今の時代は即応性が求められている
昔は各会社にいわゆる「職人」さんがいて、1台のサーバーのクセまで手に取るように把握しているような方もいました。
しかし今はクラウド環境で開発が「こんなサーバーが欲しい」を要望を出したら、すぐに指定のサーバーを提供するという「即応性」が求められる時代になりました。
もちろん、ビジネスなので間違ったサーバーを構築することはできません。
Infrastructure as Code
「Infrastructure as Code」とは、「サーバー」や「FWやルーターなどのネットワーク機器」の構築を「コード化(プログラム化)して自動化」しようという意味です。
更に、インフラの構築をコード化することで「設定を管理する」ことができます。
大抵の企業では、構築当初は「パラメータシート」や「設計書」を作成しますが、その後更新はしません。
→しかしそのままでは将来障害を引き起こす原因になります。
構築をコード化(プログラム化)することによるメリットは
- 構築するサーバーが何台あっても短時間で構築可能
- 人間の手が入らないからミスがでない
- どんな設定をしたのか後から確認が可能
- 共通言語でチーム内での共有が可能
- テストをコード化すれば何台でも何度でもテストが可能
などです。
このようにインフラの構成管理をコード化することで手動での構築に比べて様々なメリットがあります。
そして今注目されている「構成管理ツール」の1つが「Ansible」です。
Ansibleでインフラ構成管理ができる
Ansibleを使えば数千台クラスのサーバーを運用している企業でも「少人数」で「高品質」なインフラ構成管理ができます。
サーバーだけでなく「ファイアウォール」も「ロードバランサ」も「スイッチ」も Ansible で管理できるので、サーバーだけの構成管理ではなく、ネットワークも含めた「インフラの構成管理」ができます。
Ansibleとは?
Ansible は Python 製の「フリー(無料)」ツールです。
Ansible は RedHat 社をスポンサーとするオープンソースのコミュニティ・プロジェクトで開発されています。
Ansible は、IT自動化を実現する一番シンプルなツールで、その目的はインフラの「構成管理」です。
たとえば、朝一に緊急で1000台のサーバーを構築するよう開発側に依頼されたとしても、夕方には1台たりとも漏れなく正しい設定が入った状態で開発に引き渡すことが可能です。
ただ単にOSのみインストールした状態で引き渡すのではなく、DBサーバーにはこのアプリと設定、Webサーバーにはこのアプリと設定、ネットワークの設定はこの設定と言ったように、自動的に個別に設定を入れることができます。
コントロールノードがターゲットノードを管理する構成
構成は下図のように「コントロールノード」と「ターゲットノード」に分かれています。
コントロールノードにAnsibleをインストールして、リモートからターゲットノードを管理します。
Ansibleの利点
Ansibleが優れている点は多々ありますが、主要なメリットを以下に挙げます。
エージェントレスなのでターゲットノードにインストール不要
ターゲットノードにエージェントをインストールする必要がありません。
最低限「Python」が入っている必要がありますが、主要な Linux OS であれば初期段階で Python はインストールされています。
そのため特別な設定は不要で、単純に ssh でログインできればすぐに利用できます。
さらに「WinRM」を利用して Windows サーバーに対しても構成管理ができます。
設定ファイルが分かりやすい
設定ファイルは「yaml(ヤムル)」形式で記述します。
yaml はインデントや「-」で「命令」や「繰り返し」などを表現することができます。
しかも、人間が理解しやすい言語に近い形で命令を書けるので、プログラム初心者でも理解することが容易です。
Ansibleの他にも「Puppet」や「Chef」などインフラ構成管理ツールがありますが、Ansibleはその中でも「可読性」が非常に高いです。
Linux、Windows、FW、ロードバランサなど多数に対応
対象サーバーはLinuxだけではありません。
- Linux
- Windows
- BIGIP
- Docker
- AWS
- IOS
- NetApp
- oVirt
- RHEV
- VMware
- Zabbix
Windowsも仮想基盤もFWもロードバランサもZabbixのようなアプリもモジュールが開発されています。
どのような製品を使ってシステムを構築していたとしても、Ansible だけで構成管理が可能と言ってもいいでしょう。
Ansibleインストール手順
ここからはAnsibleのインストール手順を記載します。
Ansibleを導入する環境
今回 Ansible を導入するサーバーおよび管理されるクライアントは以下の構成です。
Ansible サーバー
OS:CentOS7
Ansible:2.3.0.0
[test@cnt07 ~]$ ansible –version |
クライアント
- さくらVPS 1台(CentOS7) 160.xxx.xxx.115
- VMware vSphere ESXi 6.5 上の仮想マシン CentOS 6.9 192.168.1.11
- VMware vSphere ESXi 6.5 上の仮想マシン CentOS 7.3 192.168.1.10
epelのインストール
Ansibleは「epel」レポジトリからインストールすることができます。
そのため、まずは「epel」レポジトリをインストールします。
# yum install epel-release |
epel をインストールしたら、yum list コマンドでどのバージョンの Ansible がインストールされるのか事前に確認します。
# yum list available | grep ansible ansible.noarch 2.3.0.0-3.el7 epel |
Ansibleのインストール
Ansibleをインストールします。
# yum install ansible |
たったこれだけで Ansible のインストールは完了です。
Ansible の man コマンドの結果
ANSIBLE(1) System administration commands ANSIBLE(1) NAME ターゲットホスト上でタスクを実行すること –
SYNOPSIS
DESCRIPTION Ansibleは、「遠隔のもの」を行うための特別なツール/フレームワーク/ APIです。 これは「シングルタスクプレイブック」を実行できるアドホックコマンドです。 ※Ad hoc とは「特にこのために、その場しのぎに、特別に」というような意味です。
ARGUMENTS インベントリ内のグループ名、インベントリ内のホストまたはコンマで区切られた2つの組み合わせを選択するシェルのようなグロブ。 ※glob「グロブ」とは「クリームなどのかたまり」という意味です。
OPTIONS モジュールに渡す引数。
-b, –become 特権エスカレーション(特定のものはbecome_methodに依存します)を使用してください。これはパスワードの入力を促すものではありません。
-K, –ask-become-pass 特権エスカレーションパスワードを要求します。
-k, –ask-pass 使用されているトランスポートに必要な場合は、接続パスワードを尋ねます。 たとえば、sshを使用し、ssh-agentでキーベースの認証を持たないなどです。
–ask-su-pass - suで使用されるsuのパスワードを求めるプロンプトです。(廃止予定、becomeを使用すること)
–ask-sudo-pass –sudoでパスワードを使用するかどうかを確認するメッセージが表示されます。(廃止予定、becomeを使用すること)
–ask-vault-pass vault passwordのプロンプトを出力します。 ※vault passwordとは、インフラ構成管理の機密性を保持するために、ymlファイルを暗号化する機能です。
-B NUM, –background=NUM バックグラウンドでコマンドを実行し、NUM秒後にタスクを強制終了します。
–become-method=BECOME_METHOD 使用する特権エスカレーション方法(デフォルト= sudo)、有効な選択肢:[sudo | スー| pbrun | pfexec | ドゥーズ| dzdo | ksu]
–become-user=BECOME_USER このユーザーとして操作を実行します(デフォルト= root)。
-C, –check リモートシステムを変更せず、リソースを変更して何が変わったのかを確認してください。 これはすべての可能なリソースタイプをスキャンすることはできず、シミュレーションに過ぎないことに注意してください。
-c CONNECTION, –connection=CONNECTION 使用する接続タイプ。 最も一般的なオプションはparamiko(SSH)、ssh、winrm、localです。 localは、crontabやkickstartsの場合に最も便利です。
-e EXTRA_VARS, –extra-vars=’EXTRA_VARS プレイブックに挿入する余分な変数、key=value key=value形式、または引用符で囲まれたYAML/JSON(ハッシュと配列)。 ファイルから変数をロードするには、@で始まるファイルを指定します(@ vars.ymlなど)。
-f NUM, –forks=NUM いくつ並列して実行するか決めます。NUMは整数として指定され、デフォルトは5です。
-h, –help ヘルプメッセージを表示して終了します。
-i PATH, –inventory=PATH インベントリへのPATH。デフォルトは /etc/ansible/hosts です。 代わりにカンマで区切ったホストのリストや末尾のカンマhostを持つ単一ホストを使用することもできます。
-l SUBSET, –limit=SUBSET さらに、選択したホスト/グループパターンを制限します。 パターンに正規表現があることを示すために、接頭辞として〜を付けることができます。
–list-hosts 一致するホストのリストを出力します。 他には何も実行しません。
-m NAME, –module-name=NAME NAME で指定したモジュールを実行します。
-M DIRECTORY, –module-path=DIRECTORY モジュールをロードするディレクトリ検索パス。 デフォルトは /usr/share/ansible ディレクトリです。 これは ANSIBLE_LIBRARY 環境変数で設定することもできます。
-o, –one-line すべてを1行に出力します。
-P NUM, –poll=NUM NUM秒ごとにバックグラウンドジョブをポーリングします。 -B のオプションが必要です。
–private-key=PRIVATE_KEY_FILE このファイルを使用して接続を認証します。
-S, –su suでオペレーションを実行します。(非推奨、becomeを使用すること)
-R SU_USER, –su-user=SU_USER このユーザーとしてsuを使用して操作を実行します(デフォルト= root)(非推奨、becomeを使用すること)
-s, –sudo
-uで指定されたユーザーとしてコマンドを実行し、rootになるために sudo を実行します(廃止予定、becomeを使用すること)
–sftp-extra-args=’-f …’ 指定された引数を任意のsftpコマンドラインに追加します。
–scp-extra-args=’-l …’ scpコマンドラインに指定した引数を追加します。
–ssh-extra-args=’-R …’ 指定された引数を任意のsshコマンドラインに追加します。
-U SUDO_USERNAME, –sudo-user=SUDO_USERNAME SudoからSUDO_USERNAMEへのデフォルトはrootです。 (廃止、becomeを使用すること)
-t DIRECTORY, –tree=DIRECTORY この出力ディレクトリに内容を保存します。結果は各ホストの後に付けられたファイルに保存されます。
-T SECONDS, –timeout=SECONDS SECONDSでホストと通話しようとするときに使用する接続タイムアウト。
-u USERNAME, –user=USERNAME このUSERNAMEを使用して、現在のユーザーではなくターゲットホストにログインします。
–vault-password-file=VAULT_PASSWORD_FILE vaultで暗号化されたファイルを復号化する際に使用されるvaultのパスワードを含むファイルです。 使用されている場合は、必ずこのファイルを保護しておいてください。 ファイルが実行可能な場合は実行され、標準出力はパスワードとして使用されます。
-v, –verbose Verboseモードでは、成功したアクションからのより多くの出力が表示されます。 より多くの出力を得るために最大3回与えます。
–version プログラムのバージョン番号を表示して終了します。
INVENTORY Ansibleは、潜在的に操作できるホストをインベントリに格納します。 これは、iniのようなファイル、スクリプト、ディレクトリ、またはリストにすることができます。 ini構文は1行に1ホストです。 グループヘッダーは許可され、行を開始する角括弧で囲まれた独自の行に含まれます。 Ranges of hosts are also supported. For more information and additional options, see the documentation on http://docs.ansible.com/. ホストの範囲もサポートされています。 詳細および追加オプションについては、http://docs.ansible.com/ のマニュアルを参照してください。
ENVIRONMENT 以下の環境変数を指定することができます。
ANSIBLE_INVENTORY ― Override the default ansible inventory file デフォルトの不可能なインベントリファイルを上書きします。
ANSIBLE_LIBRARY ― Override the default ansible module library path デフォルトのモジュールライブラリパスを上書きします。
ANSIBLE_CONFIG ― Override the default ansible config file デフォルトの設定可能な設定ファイルを上書きします。
Many more are available for most options in ansible.cfg 多くのオプションは、多くのオプションで利用可能です。
FILES デフォルトのインベントリファイル /usr/share/ansible/ ― Default module library デフォルトのモジュールライブラリ /etc/ansible/ansible.cfg ― Config file, used if present 設定ファイル(存在する場合) ~/.ansible.cfg ― User config file, overrides the default config if present ユーザー設定ファイル、存在する場合はデフォルト設定を上書きする
AUTHOR AnsibleはもともとMichael DeHaanによって書かれました。 貢献者の完全なリストについては、AUTHORSファイルを参照してください。
COPYRIGHT Copyright c 2012、Michael DeHaan Ansibleは、GPLv3ライセンスの条件でリリースされています。
SEE ALSO Extensive documentation is available in the documentation site: http://docs.ansible.com. IRC and mailing list info can be found in file CONTRIBUTING.md, available in: https://github.com/ansible/ansible Ansible 2.3.0.0 04/12/2017 |
Ansibleの設定をする
Ansible を利用して細かくサーバーを設定したり構築したりする手順はのちに詳しく解説をするとして、今回は簡単な Ansible の操作を試してみます。
インベントリ(Inventory)ファイルを作成する
インベントリファイルとは、「ターゲットノードの一覧」と「接続時の設定情報」を記載します。
※inventoryを直訳すると「目録」「一覧」などです。
「接続時の設定情報」は、ターゲットノードの属性によりことなります。
例えば「ローカルサーバー」と「AWS EC2 インスタンス」の接続方法は異なる場合があります。
- ローカルサーバー群 → パスワード認証方式
- AWS EC2 インスタンス群 → 公開鍵認証方式
このような構成の場合にローカルサーバーとAWS EC2 インスタンス群をグループ分けして、グループごとに接続方法を変更することができます。
また、Ansible はインベントリファイルに記載のある(登録されている)ターゲットノードに対してしか処理を実行しません。
その理由は Ansible コマンドを実行すると、一瞬でサーバーの構成を変更してしまうので、ヒューマンエラー防止策としてインベントリファイルに記述したホストのみ実行する仕様になっています。
インベントリファイルのファイル名は特に指定はありません。
「list」では「hosts」でも「list.ini」でも何でも大丈夫です。
今回は、例としてインベントリファイルの名前を「hostlist」にします。
接続時の設定情報を記載する例
また、接続時の設定情報として、インベントリファイルに ssh でログインする際のパスワードも設定しておきます。
[test@cnt07 ansible]$ vi hostlist ※Ansibleで管理するホストのIPアドレスを入力します。
[test@cnt07 ansible]$ cat hostlist
[all:vars] [test@cnt07 ansible]$ |
例えば、
- ローカルサーバー群 → パスワード認証方式
- AWS EC2 インスタンス群 → 公開鍵認証方式
をインベントリファイルに記載すると下記のようになります。
[local] ← localグループのメンバーを定義しています。
[aws] ← aws(AWS EC2 インスタンス)グループのメンバーを定義しています。
[local:vars] ← localグループの接続情報を定義しています。 ansible_ssh_user=ansible_test
[aws:vars] ← aws(AWS EC2 インスタンス)グループの接続情報を定義しています。
[all:vars] ← 共通の(allの)接続情報を定義しています。 |
事前に ansible に関する詳しい知識がなくても初見である程度理解できると思います。
IPアドレスではなくホスト名で管理する
少数台なら IP アドレスでサーバーを管理することは可能ですが、台数が増えると確実にヒューマンエラーを起こします。
例えば、1と7を間違える、111と110を間違えるなど。
そのため「ansible_host」を利用して管理します。
ansible_hostを利用してホスト名を定義することで、「ansible コマンド」や「ansible-playbook」コマンドを実行する時にヒューマンエラーの可能性を減らすことができます。
[local]
[remote]
[aws] |
Ansibleを実行する
ここからは実際に Ansible を実行してみましょう。
最初は複雑に見えるかもしれませんが、1つ1つ実行するうちに Ansible の動作が見えてくると思います。
Ansibleでpingを実行
インベントリファイルを作成したら、動作確認として Ansible で ping を実行してみます。
[test@cnt07 ansible]$ ansible -i hostlist all -m ping |
エラーが出力されました。
ここで注目なのが「test」アカウントで実行しているということです。
Ansibleは「エージェントレス」の構成で、動作的には ssh でターゲットノードにログインしてターゲットノード上で処理が実行されます。
そのため、Ansible サーバー(コントロールノード)上で「test」アカウントで実行するならば、ターゲットノード上にも「test」アカウントが必要になります。
更にroot権限で実行するような処理の場合は、sudo権限も必要になります。
そのため、この場合は
- コントロールノードとターゲットノードでアカウントを合わせる
- sudo権限が必要な場合は実行アカウントにsudoを割り当てる(具体的にはvisudoコマンドで「test ALL=(ALL) NOPASSWD: ALL」を割り当てる)
の準備が必要になります。
更に Ansible を実行してみます。
$ ansible -i hostlist all -m ping ECDSA key fingerprint is dd:71:2c:5a:05:1a:d7:ff:2f:74:87:66:d2:40:e0:32. Are you sure you want to continue connecting (yes/no)? The authenticity of host ‘192.168.1.11 (192.168.1.11)’ can’t be established. → 「Are you sure you want to continue connecting (yes/no)?」のメッセージが表示されているが、ansible の処理が進んでいくため yes を入力することができません。
RSA key fingerprint is 96:19:80:3e:99:f3:c6:42:b3:03:a8:8e:f9:d0:7b:98. Are you sure you want to continue connecting (yes/no)? The authenticity of host ‘192.168.1.10 (192.168.1.10)’ can’t be established.
ECDSA key fingerprint is 37:87:2b:3c:8d:a7:6f:85:60:c6:f4:3a:b9:8a:2e:4b.
160.xxx.xxx.115 | UNREACHABLE! => {
192.168.1.11 | UNREACHABLE! => {
192.168.1.10 | UNREACHABLE! => { |
「Are you sure you want to continue connecting (yes/no)? The authenticity of host ‘xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)’ can’t be established.」という確認ダイアログで引っ掛かっています。
このメッセージを回避する設定を入れます。
(1台1台に対して一度ログインをすれば、もう上記のメッセージは出なくなりますが、数百台レベルのサーバーに対しては非現実的な対応なので設定で回避します)
設定ファイルは「/etc/ansible/ansible.cfg」です。
# vi /etc/ansible/ansible.cfg
# additional paths to search for roles in, colon separated # uncomment this to disable SSH key host checking ↓コメントを外す host_key_checking = False # change the default callback # Determine whether includes in tasks and handlers are “static” by
|
設定ファイルを編集したら再度実行してみます。
$ ansible -i hostlist all -m ping
192.168.1.10 | SUCCESS => {
192.168.1.11 | SUCCESS => { |
今度はうまくいったようです。
うまく Ansible が動かない場合(トラブルシューティング)
Ansible を導入してもうまく動かない、そんな場合は以下を参考にトラブルシューティングを試してみてください。
また、Ansible をインストールしたサーバー側の設定が問題なくても、クライアント側が原因で情報を取得できない時があります。
そもそもクライアントに ping が通らない
参考例として AWS の場合を記載します。
Ansible をインストールしたサーバーからクライアントに ping が通らない場合があります。
例えば、こんな感じで ping 応答が返ってきません。
[test@cnt07 ~]$ ping 54.xxx.xxx.147
|
firewalld や iptables を疑ってみる
pingが失敗する場合は、ファイアウォールでブロックされていないか調べてみましょう。
AWSの「セキュリティグループ」の設定を変更する
AWSの「セキュリティグループ」でブロックされていることもあります。
そのため、自宅の Ansible サーバーからのみ ping を受け付けるように設定します。
以下、設定変更の手順を記載したのでご参考ください。
1.AWSにログインする
AWSの管理コンソールにログインします。
https://console.aws.amazon.com/
2.セキュリティグループを開く
AWS管理コンソールにログインしたら、「サービス」-「EC2」にアクセスします。
左側ペインの「セキュリティグループ」をクリックします。
インスタンスの「説明」タブより対象のセキュリティグループをクリックします。
※ここでは「launch-wizard-2」が対象です。
3.インバウンドの編集を開く
セキュリティグループの画面を開いたら「インバウンド」タブをクリックして「編集」ボタンをクリックします。
「インバウンドのルールの編集」画面が表示されたら、以下のように設定をします。
- タイプ:すべての ICMP – IPv4
- プロトコル:ICMP
- ポート範囲:0 – 65535
- ソース:カスタム 「自宅PCのWAN側のIPアドレス/32」
設定を入れたら「保存」ボタンをクリックします。
4.pingで再度確認
再度 ping で動作確認をします。
[test@cnt07 ~]$ ping 54.xxx.xxx.147 |
クライアントに「python-simplejson」がインストールされていない
Ansibleはエージェントレスですが、最低限クライアントに「python-simplejson」がインストールされていなければいけません。
クライアントに「python-simplejson」をインストールする手順
# yum install python-simplejson |
まとめ
今回は Ansible の導入について基本的な部分を記載しました。
今後、更に Ansible を活用するために、「ansible-playbook」の使い方や設定の詳細について記事を作成する予定です。
Ansible のプレイブック(Playbook)の使い方を詳細に説明しています。
コメント