Ansibleのトラブルシューティング
齊藤 秀喜(@saito_hideki)
シニアソフトウェアメンテナンスエンジニア(Ansible Automation Platform)
レッドハット株式会社
Version: 2020-07
自己紹介
Troubleshooting, Tips, and Tricks
氏名: 齊藤 秀喜(@saito_hideki)
所属: カスタマーエクスペリエンス&エンゲージメント/レッドハット株式会社
仕事: シニアソフトウェアメンテナンスエンジニア(Ansible Automation Platform)
趣味: Ansibleのトラブルシュート
本セッションは、
Software Design 2020年7月号
に寄稿した連載記事をベースに
しています
2
Troubleshooting, Tips, and Tricks
本セッションでは、Ansibleを利用した自動化を進めるなかで発生するトラブルを解決するため
に必要となるAnsibleの基礎知識と、トラブルシュートの手法について、テクニカルサポートの
現場で培った知見を元に解説します。
❖ 問題を調査するためのアプローチ
❖ 前提知識: Ansibleの仕組みと問題が発生するポイント
❖ 問題を調査するためのテクニック
本セッションでお話すること
3
Troubleshooting, Tips, and Tricks
現在、広く認知されているように、Ansibleはプログラミングやエンジニアリングの経験が少な
い、あるいはそれらを学ぼうとする人にとって、利用しやすいツールであることは間違いありま
せん。
しかし、トラブルシューティングとなると話は別です。Ansible自体のアーキテクチャを理解す
る必要があるのはもちろんのこと、Ansibleを実行するコントロールノードや、自動化の対象と
なるマネージドノード上で稼働しているシステムに対する深い理解も必要となります。
残念ながら、Ansibleのトラブルシューティングは、シンプルでも簡単でもありません。
以降では、AnsibleがPlaybookを実行する仕組みと、コントロールノードやマネージドノード上
で、なぜ、みなさんが書いたPlaybookが想定通りに動作「しなかった」のかを調査するための
ヒントをご紹介します。
はじめに
4
Troubleshooting, Tips, and Tricks
以下のようなことを念頭に置いてトラブルシュートをしています。
1. 正しくトリアージする(緊急度/影響範囲/優先度)
2. 憶測は排除し事実(例えばログファイル)をもとに発生している現象を正しく把握する
3. 問題を再現する TRIED. TESTED. TRUSTED.
4. 想定された動作なのか不具合なのか?
5. 既知の不具合か、未知の問題か?
6. 解決策やワークアラウンドは存在しているのか?
「問題」を調査するためのアプローチ
多くの人は自分に主観に基づいての
現象を報告してきます。
相手の思い込みや自分の憶測を排除
し、事実だけを見つめて問題を適切
にトリアージしましょう。
5
Troubleshooting, Tips, and Tricks
まずは「問題」を「自分以外の誰か」に伝えられるように、以下の5つのポイントを意識して整
理してみてください。
経験上、当事者が他人にうまく伝えられない問題は、おそらく正しく調査・解決できません。
1. 問題の概要をまとめてタイトルをつける
2. どのような問題が発生していますか? 期待される動作はどのようなものですか?
3. どこで問題が発生しますか? どの環境で発生しますか?
4. いつ問題が発生しますか? 頻繁に発生しますか? 繰り返し発生しますか? 特定のタイミングで発生しますか?
5. 問題の緊急度はどれくらいですか? 解決までの期限や業務への影響はありますか?
「問題」を整理する
6
Ansibleのトラブルシューティング
基礎知識
Troubleshooting,Tips,andTricks
7
Troubleshooting, Tips, and Tricks
たとえば、以下のようなPingモジュールを実行するシンプルなPlaybookの実行例
Ansibleの仕組みと問題が発生するポイント(1)
$ cat playbook/ping_test.yml
---
- name: Preflight playbook
hosts: all
gather_facts: true
tasks:
- name: Ping test
ping:
$ ansible-playbook -i hosts ping_test.yml
PLAY [Preflight playbook] *************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [server00]
TASK [Ping test] **********************************************************************************************************
ok: [server00]
PLAY RECAP ****************************************************************************************************************
server00 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
8
Troubleshooting, Tips, and Tricks
Ansibleは、モジュールから生成した実行可能なPythonプログラムを、コントロールノードから
マネージドノードに転送して実行します。
Ansibleの仕組みと問題が発生するポイント(2)
Control Node Managed Node
Module
Python
Program
9
Managed node
Remote tmp directory
Remote tmp directory
Troubleshooting, Tips, and Tricks
Ansibleの仕組みと問題が発生するポイント(3)
Control node
Playbook
Inventory
AnsiballZ_setup.py
AnsiballZ_ping.py
AnsiballZ_setup.py
AnsiballZ_ping.py
Plugin
2)
1)
3)
4-b)
5-b)
4-d)
4-d,e,f)
5-d)
5-d,e,f)
A
C
C
4-a,c,g)
5-a,c,g)
B
B
B
B
10
Troubleshooting, Tips, and Tricks
前出のサンプルPlaybook実行時の処理の流れは以下の通りです。
1) インベントリファイル(./inventories/testing/hosts)をロードする
2) cache/connection/become/shellプラグインをロードする
3) Strategy(デフォルトのlinearストラテジー)にしたがってマネージドノードに対する実行計画を生成
4) Setupモジュールの実行
a) マネージドノード上に一時的なワーキングディレクトリ(remote tmp directory)を作成
b) ANSIBALLZ形式でhost_vars、モジュールオプションパラメータを含めて実行プログラムのアーカイブを作成する =>
AnsiballZ_setup.py
c) マネージドノードのPythonインタプリタのパスをディスカバリ
d) 4.2で生成したAnsiballZ_setup.pyファイルをマネージドノードにsftpで転送
e) SSH経由でマネージドノード上に転送したAnsiballZ_setup.pyを実行
f) Callbackプラグインでモジュールの実行結果を標準出力(JSON形式)で受け取ってストア
g) 4.1で作成したディレクトリ配下を削除
5) Pingモジュールの実行 ※詳細な流れは4-a...4-gと同様 (AnsiballZ_ping.py)
6) PLAY RECAPを出力してPlaybookの実行を終了
Ansibleの仕組みと問題が発生するポイント(4)
11
Troubleshooting, Tips, and Tricks
Playbookを実行する際に発生するポイントは、大きく以下の3箇所に整理できます。
(A) Playbookの実行前処理 
(B) ANSIBALLZファイルの転送処理
(C) ANSIBALLZファイルの実行処理
以降では、テクニカルサポートの現場で得られたノウハウを元に、上記の(A),(B),(C)それそれの
フェーズで発生する問題の調査手法をご紹介します。
Ansibleの仕組みと問題が発生するポイント(5)
12
トラブルシュートをはじめる前に
Troubleshooting,Tips,andTricks
13
Troubleshooting, Tips, and Tricks
❏ Ansibleの実行ログをログファイルに出力する
デフォルト設定では、Ansibleの実行ログは標準出力に出力されます。まずは、このログをログ
ファイルに出力することから始めましょう。
トラブルシュートをはじめる前に...(1)
#~~~ ansible.cfg ~~~
[defaults]
log_path = /var/log/ansible.log
Ansibleの設定ファイル(ansible.cfg)の、log_pathパラメータにログファイルのパスを設定し
ます。
14
Troubleshooting, Tips, and Tricks
❏プラグインやモジュールのログ出力の詳細度(VERBOSITY)を調整する
プラグインやモジュールの実行時に出力されるログの詳細度は5段階で、これを適切に調整する
ことでトラブルシュートに役立つ情報を得ることができます。
トラブルシュートをはじめる前に...(2)
$ ansible-playbook -i hosts main.yml -vvvvv
レベル オプション 効果
1 -v 詳細な実行ログ出力 (設定ファイルのロードバス出力程度 )
2 -vv より詳細な実行ログ
3 -vvv デバッグ出力(バックエンドで実行される sshコマンドの出力)
4 -vvvv コネクションデバッグ出力 (sshコマンドに-vvvオプションが指定され、より詳細なログが得られる )
5 -vvvvv WinRMデバッグ出力(WinRM接続時の詳細ログが得られる ,一部のvalut処理のログも出力される )
15
Troubleshooting, Tips, and Tricks
❏ デバッグモードを有効化する
デバッグモードを有効化することで、プラグインやモジュールだけでなくエンジン部分の挙動を
トレースすることができます。
トラブルシュートをはじめる前に...(3)
a)ansible.cfgの設定で有効化する
#~~~ ansible.cfg ~~~
[defaults]
debug = True
b)コマンド実行時に環境変数として一時的に指定する
$ ANSIBLE_DEBUG=True ansible-playbook -i hosts main.yml
$ ANSIBLE_DEBUG=True ansible-playbook -i hosts main.yml -vvvvv
16
(A) Playbookの実行前処理
Troubleshooting,Tips,andTricks
17
Troubleshooting, Tips, and Tricks
❏ Playbookの構文エラー
Playbook実行前処理で発生するエラーの多くは、PlaybookやInventoryファイルの書式に関す
るものです。以下のような誤った記述のPlaybookを実行しようとした場合に発生します。
Playbook実行前処理 - (A)
---
- hosts: all
gather_facts: false
tasks:
name: Ping test to managed nodes
- shell: hostname
register: result
name: Ping test to managed nodes
- debug:
var: result.stdout
疲れてくると、この手のエラーが
多くなりがちです。
明日の朝頑張ることにして、もう
ビール飲んで寝ちゃいましょう。
18
Troubleshooting, Tips, and Tricks
--syntax-checkオプションで、Playbook実行前にチェックして対応しておきましょう。
Playbook実行前処理 - (A)
$ ansible-playbook -i hosts sample00.yml --syntax-check
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)
Syntax Error while loading YAML.
expected <block end>, but found '-'
The error appears to be in '/Users/hsaito/work/testing/ansible/playbook/error/sample00/main.yml':
line 7, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
name: Ping test to managed nodes
- shell: hostname
^ here
--syntax-checkでPlaybookの
構文エラーを解決したら
ansible-lintによる構文規約の
チェックを行いましょう
19
Troubleshooting, Tips, and Tricks
ansible-playbookコマンドの引数に指定するPlaybook(エントリポイントとなるPlaybook)は、
hostsセクションを含む以下のように、“-”でブロック分割されるリスト構造となっている必要が
あります。サンプルコードのコンテンツの”一部”をコピー&ペーストして使うのであれば書式に
十分注意してください。2つめ以降のhostsの前の”-”をみなさん忘れがちです。
Playbook実行前処理 - (A)
$ ansible-playbook -i hosts sample.yml --list-hosts
#~~~ sample.yml ~~~
---
- hosts: web
...snip...
- hosts: app
...snip...
- hosts: database
...snip...
このケースは、--syntax-checkで
は捕まえられません。
--list-hostsでマネージドノードの
リストを確認しましょう
20
Troubleshooting, Tips, and Tricks
❏ Dynamic Inventoryが正しく動作しない
Ansibleの大きな武器であるDynamic Inventoryですが、AWSやvCenterとの連携に問題があっ
て同期に失敗すると、インベントリ情報が空となったり、想定外のマネージドノードのリストが
作られたり...といった問題が発生します。ansible-inventoryコマンドで確認しましょう。
Playbook実行前処理 - (A)
$ ANSIBLE_DEBUG=True ansible-inventory -i aws_ec2.yml --list
...
{
"_meta": {
"hostvars": {}
},
"all": { # <= AWS上に仮想マシンインスタンスが存在するにもかかわらずallリストが空になっている
"children": [
"ungrouped"
]
}
}
21
Troubleshooting, Tips, and Tricks
Dynamic Inventoryプラグインは、同名の設定ファイル(プラグイン名.(yml|yaml))を実行時に指
定します。リストが空になったり、想定外のマネージドノードをリストアップしてしまうような
ケースは、この設定ファイルに問題がある場合がほとんどです。
前項の例のように、デバッグモード(ANSIBLE_DEBUG=True)でansible-inventoryコマンドを
実行すれば、より詳細なDynamic Inventoryプラグインの挙動を確認できます。
Playbook実行前処理 - (A)
#~~~ aws_ec2.yml ~~~
plugin: aws_ec2
aws_access_key: <認証用アクセスキー>
aws_secret_key: <認証用シークレットキー>
regions:
- ap-northeast-1
filters:
tag:Owner: hsaito
compose:
ansible_host: private_ip_address
このケースでは、tagパラーメータが適切
にインデントされておらず、filtersパラ
メータのチェックに失敗します。
結果としてプラグインが正しく実行され
ず、ノードリストが空となります。
問題を修正したあとで、デバッグログを
改めて見ると「あぁ...」となりますが、正
直ログでの解析は結構むずかしい問題の
1つです。
22
Troubleshooting, Tips, and Tricks
❏ Static Inventoryが正しく動作しない
Static Inventoryも、Dynamic Inventoryと同様にプラグイン経由でロードされます。Dynamic
Inventoryと同様の仕組みですから、動作確認も同様にansible-inventoryコマンドで実施できま
す。
Playbook実行前処理 - (A)
$ ANSIBLE_DEBUG=True ansible-inventory -i hosts --list
...
{
"_meta": {
"hostvars": {}
},
"all": { # <= Inventoryファイルにマネージドノードが記述されているにもかかわらずallリストが空になっている
"children": [
"ungrouped"
]
}
}
23
Troubleshooting, Tips, and Tricks
Static Inventoryの問題は、 Inventoryファイルの記述ミスが原因ですから、問題の調査も
Dynamic Inventoryよりも単純で、デバッグログからも比較的見つけやすいため、積極的に
ANSIBLE_DEBUG=Trueでデバッグログを生成して確認してみましょう。
Playbook実行前処理 - (A)
#~~~ hosts ~~~
[server]
server00
server01
server02
server03
[server:vars]
ansible_user: hsaito # INI形式ではなくYAML形式で書かれている
このケースでは、INIファイルであ
るにもかかわらず、group_varsの
指定がYAML形式になっていま
す。あなたは疲れています。
ビールでも飲んで寝ましょう。
24
Troubleshooting, Tips, and Tricks
Playbook実行前処理 - (A)
$ ansible-config dump --only-changed
DEFAULT_LOG_PATH(/home/hsaito/testing/ansible.cfg) = /home/hsaito/testing/logs/ansible.log
HOST_KEY_CHECKING(/home/hsaito/testing/ansible.cfg) = False
INVENTORY_ENABLED(/home/hsaito/testing/ansible.cfg) = ['aws_ec2']
❏ ansible.cfgの設定ミス
Ansibleの振る舞いは、設定ファイル(ansible.cfg)に記述します。
デフォルト値から意図せず変更されていないかを、トラブルシュートの初期段階で確認しておき
ましょう。
ansible-configコマンドに、dumpサブコマンドを--only-changedオプション付きで指定するこ
とで、デフォルト設定から変更した箇所のみを確認することができます。
設定ファイルのパスと優先度(ANSIBLE_CONFIGが最優先)は以下のリンクにある通りです。
複数のパスにansible.cfgが存在する場合は、最も優先度の高いファイルがロードされ、他の
ファイルはロードされないので注意してください。
https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings
25
Troubleshooting, Tips, and Tricks
Playbook実行前処理 - (A)
$ ansible-config dump --only-changed
DEFAULT_LOG_PATH(/home/hsaito/testin/ansible.cfg) = /home/hsaito/testing/logs/ansible.log
HOST_KEY_CHECKING(/home/hsaito/testing/ansible.cfg) = False
INVENTORY_ENABLED(/home/hsaito/testing/ansible.cfg) = ['aws_ec2']
$ ansible-config dump --only-changed
DEFAULT_LOG_PATH(/home/hsaito/testing/ansible.cfg) = /home/hsaito/testing/logs/ansible.log
HOST_KEY_CHECKING(/home/hsaito/testing/ansible.cfg) = False
INVENTORY_ENABLED(/home/hsaito/testing/ansible.cfg) = ['host_list', 'script', 'auto', 'yaml', 'ini',
'toml', 'aws_ec2']
以下のようにデフォルト値に
追記する形に修正する
このケースでは、aws_ec2をInventory
プラグインとして指定しています。この
設定は、デフォルト設定を上書きして
aws_ec2プラグインのみを有効化するた
め、INI形式やYAML形式で記述された
Static Inventoryファイルを正しくロー
ドできなくなります。
26
Troubleshooting, Tips, and Tricks
Playbook実行前処理 - (A)
.
├── library
│ └── <latest_module>.py # Upstreamから取得した最新版のモジュール
├── module_utils
│ └── <helper_module>.py # モジュールが必要とするヘルパーモジュールがあればココに配置
└── playbook.yml
❏ 最新のモジュールでテストしてみる
モジュールロードパスで最優先されるのは、Playbookディレクトリにある ”library/”
配下のモジュールです。
調査の過程で、モジュールの挙動が怪しく、これが現在は修正されているというようなケースで
は、Upstreamから不具合が修正されたモジュールを取得して動作確認を行うことで、問題の調
査を1歩進めることができるでしょう。
27
Troubleshooting, Tips, and Tricks
まとめ: Playbook実行前処理 - (A)
1. Playbookの構文チェックを実施する:
Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> --syntax-check
2. Playbookの適用対象となるマネージドホストのリストを確認する:
Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> --list-hosts
3. Dynamic Inventoryプラグインが想定通りの設定で機能していることを確認する:
Usage: ANSIBLE_DEBUG=True ansible-inventory -i <INVENTORY_PLUGIN_NAME>.(yml|yaml) --list
4. Static Inventoryファイルが想定通りの設定でロードされていることを確認する:
Usage: ANSIBLE_DEBUG=True ansible-inventory -i <INVENTORY_FILE> --list
5. Ansibleの設定ファイル(ansible.cfg)のパスとデフォルトから変更している設定内容を確認する:
Usage: ansible-config dump --only-changed
本セクションで登場したコマンドと機能は以下の通りです。
28
(B) ANSIBALLZファイルの転送処理
Troubleshooting,Tips,andTricks
29
Troubleshooting, Tips, and Tricks
❏マネージドノードのタイプで違うPlaybookの転送方法
Ansibleがモジュールから生成するANSIBALLZファイルは、操作対象であるマネージドノードの
タイプ毎に異なる方法で、マネージドノードに転送されます。
この転送フェーズが、コントロールノードとマネージドノード間のファーストコンタクトであ
り、接続エラーの多くは、このフェーズで発生します。
尚、3),4)については、通常はコントロールノード上で実行されるため、転送は発生しません。
1) UNIX系
2) Windows
3) ネットワークデバイス
4) IaaSシステム(Amazon EC2/GCP/Azure/vCenter/OpenStack...etcetera)
ANSIBALLZファイルの転送 - (B)
30
Troubleshooting, Tips, and Tricks
1) UNIX系ノードへの転送(デフォルトの挙動)
ANSIBALLZファイルの転送 - (B)
Control Node Managed Node
ANSIBALLZ ANSIBALLZ
A.マネージドノードがsftpを許可し
ている場合はsftpで転送する。
B.sftpを許可していない場合はscp
で転送する。
31
Troubleshooting, Tips, and Tricks
2) Windowsノードへの転送
Windowsノードへの接続するには ansible_connection=winrm を指定します。
ANSIBALLZファイルの転送 - (B)
Control Node Managed Node
ANSIBALLZ ANSIBALLZ
WinRMを利用してhttp/httpsで転送する
参考リンク: https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html#windows-remote-management
32
Troubleshooting, Tips, and Tricks
このフェーズでのトラブルは、SCP/SFTP接続時やWinRM接続時の認証失敗によるものがほとん
どです。まずはログの解析からトラブルシュートをはじめましょう。
ANSIBALLZファイルの転送 - (B)
1) マネージドノードがUNIX系の場合(VERBOSITY:4)
$ ansible-playbook -i hosts sample.yml -vvvv
2) マネージドノードがWindowsの場合(VERBOSITY:5)
$ ansible-playbook -i hosts sample.yml -vvvvv
33
Troubleshooting, Tips, and Tricks
UNIX系のマネージドノードでは、ANSIBALLZファイルの転送にSCP/SFTPを利用します。接続
に失敗するようなケースでは、”-vvvv”オプションを指定してPlaybookを実行することで、バッ
クグラウンドで実行されるssh/scp/sftpコマンドに”-vvv”オプションが指定されます。
UNIX系: ANSIBALLZファイルの転送 - (B)
$ ansible-playbook -i hosts sample01.yml -vvvv
...
TASK [ping]
****************************************************************************************************
*******************************************************************
task path: /home/hsaito/work/testing/codt2020/playbook/sample/sample01.yml:6
<server00> ESTABLISH SSH CONNECTION FOR USER: redhat
<server00> SSH: EXEC sshpass -d11 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o
StrictHostKeyChecking=no -o 'User="redhat"' -o ConnectTimeout=10 ...
...
<server00> SSH: EXEC sshpass -d11 sftp -o BatchMode=no -b - -vvv -C -o ControlMaster=auto -o
ControlPersist=60s -o StrictHostKeyChecking=no -o 'User="redhat"' -o ConnectTimeout=10 -o
ControlPath=/home/hsaito/.ansible/cp/ac861c7aaa '[server00]'
...
34
Troubleshooting, Tips, and Tricks
マネージドノード側のsshdをデバッグオプション付きで起動することで、接続の失敗に関する
詳細なログを、マネージドホスト側でも確認することができます。
authorized_keysの不適切なパーミッション設定など、マネージドホスト側の設定ミスが原因で
失敗しているようなケースでは有効な調査方法です。
UNIX系: ANSIBALLZファイルの転送 - (B)
[RHEL/CentOS]
#/etc/sysconfig/sshd
#---
OPTIONS="-ddd"
#---
大量のログが出力されるため、
デバッグ時に限定して設定・運用
することをおすすめします。
sshdのリスタートも忘れずに!
35
Troubleshooting, Tips, and Tricks
以下のログは、Windowsノードであるにもかかわらず、ansible_connectionパラメータに
winrmが設定されておらず、デフォルトのSCP/SFTPで接続して失敗しています。
Windows: ANSIBALLZファイルの転送 - (B)
TASK [win_ping]
****************************************************************************************************
task path: /home/hsaito/work/testing/ansible/playbook/sample/sample01.yml:6
<win2019-00> ESTABLISH SSH CONNECTION FOR USER: Administrator
<win2019-00> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s)
<win2019-00> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set:
(-o)(User="Administrator")
<win2019-00> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10)
<win2019-00> SSH: PlayContext set ssh_common_args: ()
<win2019-00> SSH: PlayContext set ssh_extra_args: ()
<win2019-00> SSH: found only ControlPersist; added ControlPath:
(-o)(ControlPath=/home/hsaito/.ansible/cp/73ffcfe560)
<win2019-00> SSH: EXEC sshpass -d10 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o
'User="Administrator"' -o ConnectTimeout=10 -o ControlPath=/home/hsaito/.ansible/cp/73ffcfe560
win2019-00 '/bin/sh -c '"'"'echo ~Administrator && sleep 0'"'"''
...snip...
UNIX系以外のマネージドノード
を相手にするときは、それぞれの
通信要件にあわせて
ansible_connectionを適切に設定
しましょう。
36
Troubleshooting, Tips, and Tricks
Windowsノード側では、WinRMの初期設定を適切に実施する必要があります。
公式ドキュメントにしたがって、Windowsノード側でWinRMの初期設定を実施してください。
> https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html
Windows: ANSIBALLZファイルの転送 - (B)
PS C:UsersAdministrator> winrm.cmd get winrm/config
Ansibleで接続できない?
WinRMの初期設定をわすれて
いませんか?もういちど見直
しましょう
37
Troubleshooting, Tips, and Tricks
Windowsノードにログインするためのログイン情報は以下のパラメータで設定します。
Active Directoryを利用している場合は、ansible-playbookコマンドを実行するコントロール
ノード側で、Kerberos認証の設定が必要です。
● ユーザ名(ansible_username)
● パスワード(ansible_password)
Windows: ANSIBALLZファイルの転送 - (B)
$ kinit <USERNAME>@<DOMAIN>
Password for <USERNAME>@<DOMAIN>: ********
$ klist
Ticket cache: KCM:1001
Default principal: <USERNAME>@<DOMAIN>
Valid starting Expires Service principal
06/29/2020 03:21:29 06/29/2020 13:21:29 krbtgt/<DOMAIN>@<DOMAIN>
renew until 07/06/2020 03:21:27
AD認証を利用する場合は、コントロー
ルノードでの設定も必要です。
kinitコマンドによるユーザ認証が正し
く行われるかを確認してください。
38
Troubleshooting, Tips, and Tricks
ping/win_pingモジュールを利用して、マネージドノードとの接続が正しく行われるかを確認す
ることができます。
共通: ANSIBALLZファイルの転送 - (B)
$ ansible centos8-00 -i hosts -m ping -vvvv
$ ansible win2019-00 -i hosts -m win_ping -vvvvv
pingモジュール,win_pingモジュールを
利用して、マネージドノードとの接続を
確認できます。
39
Troubleshooting, Tips, and Tricks
まとめ: ANSIBALLZファイルの転送処理 - (B)
1. コントロールノード - マネージドノード間の接続ログ確認
1a. マネージドノードがUNIX系の場合(VERBOSITY:4)
Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> -vvvv
1b. マネージドノードがWindowsの場合(VERBOSITY:5)
Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> -vvvvv
2. sshdのデバッグログ出力(RHEL/CentOS)
#~~~ /etc/sysconfig/sshd ~~~
OPTIONS="-ddd"
3. WinRM設定の確認
> winrm.cmd get winrm/config
4.コントロールノード - マネージドノード間の接続チェック
Usage: ansible <MANAGED_NODE> -i <INVENTORY> -m ping -vvvv
Usage: ansible <MANAGED_NODE> -i <INVENTORY> -m win_ping -vvvvv
本セクションで登場したコマンドと設定は以下の通りです。
40
(C) ANSIBALLZファイルの実行処理
Troubleshooting,Tips,andTricks
41
Troubleshooting, Tips, and Tricks
❏Playbookの実行ログを確認する
Ansibleはデフォルトの動作ログは、デフォルト設定ではSTDOUTに出力されます。
Ansible Playbookの動作ログファイルを残すというのは問題調査の第一歩です。
ANSIBALLZファイルの実行処理 - (C)
#~~~ ansible.cfg ~~~
[defaults]
log_path = /var/log/ansible.log システム運用では、ターミナルログを常に
取得しておくというのは基本中の基本です
が、コントロールノード側でも取得してお
きましょう。
42
Troubleshooting, Tips, and Tricks
❏Playbookのタスクをステップ実行する(--step)
Playbookのデバッグ時に、各タスクをステップ実行したいようなケースでは--stepオプション
を指定してください。中止(n)、実行(y)、以降のタスクをインタラクションなしで実行(c)の中か
ら選択してタスクを実行します。
ANSIBALLZファイルの実行処理 - (C)
$ ansible-playbook -i hosts sample.yml --step
PLAY [all] ***************************************************
Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue:
後述するPlaybook Debuggerを使ってしま
うので、正直あまり登場機会はありません
が、タスクの実行前にマネージドノード側
で特定の条件を作り出したいよなケースで
は有効です
43
Troubleshooting, Tips, and Tricks
❏Playbookを特定のタスクから実行する(--start-at-task)
ある特定のタスクの調査のために、前段のタスクを飛ばして特定のタスクからPlaybookを実行
したいようなケースで利用します。
ANSIBALLZファイルの実行処理 - (C)
$ ansible-playbook -i hosts sample.yml -l --start-at-task "task B"
PLAY [all]
***********************************************************************************************
TASK [Gathering Facts]
***********************************************************************************************
ok: [centos8.test.fgrep.org]
TASK [task B]
***********************************************************************************************
ok: [centos8.test.fgrep.org]
...
タスクのnameセクションに設定したタ
スク名を指定して、そのタスクから
Playbookを実行します。
Gather Factsはスキップしません。
44
Troubleshooting, Tips, and Tricks
❏モジュールが必要とするライブラリやコマンドがインストールされていることを確認する
Ansibleのモジュールは数多くありますが、利用に際しては必ずドキュメントを読みましょう。
特にRequirementsには、モジュールが動作するのに必要なライブラリやコマンドの情報が書か
れています。
ANSIBALLZファイルの実行処理 - (C)
例: gitモジュール
Requirements
The below requirements are needed on the host that executes this module.
●git>=1.7.1 (the command line tool) これらは、
「ANSIBALLZファイルを実行するノード」
にインストールする必要があります!
45
Troubleshooting, Tips, and Tricks
❏gather_subsetで収集する情報を調整する
“gather_facts: true”では、マネージドノードのハードウェア情報を含めたさまざまな情報を収
集して、ansible_factsに格納し、後段のタスクから利用できるようにします。
たとえば、ディスクなどのデバイスが、device busyで無応答となってしまうような状態だと、
この”Gathering Facts”タスクがスタックして無応答となります。
gather_subsetで、取得する情報量を調整することで、このような無応答状態を抑止できる可能
性があります。
ANSIBALLZファイルの実行処理 - (C)
---
- hosts: all
gather_facts: true
gather_subset:
- min
...
その情報、本当に必要ですか?
利用しない情報なら gather_subset を調整
して収集しないようにしましょう。
> setupモジュール(https://docs.ansible.com/ansible/latest/modules/setup_module.html)
46
Troubleshooting, Tips, and Tricks
❏ライブラリパスに余計なファイルは配置しない
ansibleのモジュールパスにAnsibleのモジュールと同名のPythonプログラム(例えばsetup.py)
を配置してはいけません。
ANSIBALLZファイルの実行処理 - (C)
$ tree sample04
sample
|-- library
| `-- setup.py
`-- sample.yml
$ ansible-playbook -i hosts sample/sample.yml
...
TASK [Gathering Facts]
*********************************************************************************************
fatal: [centos8.test.fgrep.org]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup":
{"failed": true, "module_stderr": "Shared connection to centos8.test.fgrep.org closed.rn", "module_stdout":
"/usr/bin/env: ‘python’: No such file or directoryrn", "msg": "MODULE FAILUREnSee stdout/stderr for the
exact error", "rc": 127}}, "msg": "The following modules failed to execute: setupn"}
うっかり *PythonSDK のようなソースコードを、
モジュールパスに展開していしまうと...
Ansibleはそれに含まれるsetup.pyを、自身の
setupモジュールと誤認識して利用しようとします
47
Troubleshooting, Tips, and Tricks
❏変数の値をチェックする
モジュールの引数や、テンプレートモジュールで置換する変数に想定した値が設定されていない
ようなケースでは、debugモジュールを利用して変数の値を確認することができます。
ANSIBALLZファイルの実行処理 - (C)
...
vars:
home_dir: '{{ lookup("env", "HOME") }}'
tasks:
- debug:
var: home_dir
...
このケースではHOMEをHOGEのようにtypo
しても文法上はエラーとならず、home_dirは
空となります。
debugモジュールで値をチェックしましょ
う。変数のチェックにはmsgよりもvarがおす
すめです。
48
Troubleshooting, Tips, and Tricks
❏Playbook Debuggerを利用する
タスクの条件分岐(when句)が適切に行われないようなケースでは、-vvvのように詳細レベルを
上げても、ANSIBLE_DEBUG=Trueでデバッグモードを有効化しても、判断条件を確認すること
はできません。このような問題の調査には、Playbook Debuggerが有効です。
ANSIBALLZファイルの実行処理 - (C)
---
- hosts: all
debugger: never
tasks:
- stat:
path: /etc/hosts
when:
- foo == "FOO"
- bar == "BAR"
debugger: on_skipped
Playbookのデバッグで消耗せずに済むの
で、Playbook Debuggerは非常におすすめ
のツールです。
以降で少し詳しく使い方を紹介します
49
Troubleshooting, Tips, and Tricks
Playbook Debuggerの利用方法は難しくありません。
たとえば前出のPlaybookであれば、skip時にPlaybook Debuggerが起動してコマンド入力待ち
となります。
ANSIBALLZファイルの実行処理 - (C)
ansible-playbook -i hosts -e "foo=FOO,bar=BAR" sample.yml -v
PLAY [all]
*********************************************************************************************
TASK [Gathering Facts]
*********************************************************************************************
ok: [centos8.test.fgrep.org]
TASK [stat]
********************************************************************************************
skipping: [centos8.test.fgrep.org] => {"changed": false, "skip_reason": "Conditional result was
False"}
[centos8.test.fgrep.org] TASK: stat (debug)>
50
Troubleshooting, Tips, and Tricks
以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。
https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands
ANSIBALLZファイルの実行処理 - (C)
1.タスクを実行したマネージドホストを表示する
> p host
centos8.test.fgrep.org
2.タスク名を表示する
> p task
debug
3.タスクの実行結果を表示する
> p result._result
{'_ansible_no_log': False,
'changed': False,
'skip_reason': 'Conditional result was False',
'skipped': True}
51
Troubleshooting, Tips, and Tricks
以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。
https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands
ANSIBALLZファイルの実行処理 - (C)
4.タスクから参照できる全変数を表示する
> p task_vars
...Taskレベルで利用せきる全ての変数とその値が表示されます...
5.タスクから参照できる特定の変数を表示する
> p task_vars['foo']
'FOO,bar=BAR'
> p task_vars['bar']
***KeyError:KeyError('bar')
この例では、-eオプションの指定を誤って
fooに想定外の値が設定され、barが未設定
の状態となっているのがわかります。
52
Troubleshooting, Tips, and Tricks
以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。
https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands
ANSIBALLZファイルの実行処理 - (C)
6.タスクで実行しているモジュールのパラメータを表示する
> p task.args
{'path': '/etc/hosts'}
7.タスクが参照している特定の変数を再設定する
> task_vars['foo'] = 'FOO'
> task_vars['bar'] = 'BAR'
> p task_vars['foo'],task_vars['bar']
('FOO', 'BAR')
8.再設定した変数やパラメータでタスクを更新する
> u
53
Troubleshooting, Tips, and Tricks
以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。
https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands
ANSIBALLZファイルの実行処理 - (C)
9.タスクで実行しているモジュールの特定のパラメータを表示する
> p task.args['path']
'/etc/hosts'
10.タスクで実行しているモジュールの特定のパラメータの値を変更する(‘u’で更新する変更前の値に戻ってしまうので注意)
> task.args['path'] = '/etc/hostname'
> p task.args['path']
'/etc/hostname''
11.タスクを再実行する
> r
task.args[‘パラメータ名’]で、モジュールの
パラメータを更新後に”更新(u)してはいけま
せん。task_varsの変更と更新(u)は、10.よ
りも前にじ実施しておいてください
54
Troubleshooting, Tips, and Tricks
❏Playbookのパフォーマンスを計測する(1)
Playbookの実行完了までに長時間かかるので少しでも短縮したい...といった、パフォーマンス
に関する問題では、どのタスクでどの程度の時間がかかっているのかを計測して、改善の必要な
タスクを洗い出すのが最初の一歩となります。
Callback Pluginを利用して、Playbookの実行時間を計測しましょう。
ANSIBALLZファイルの実行処理 - (C)
プラグイン名 機能
timer Playbook全体の実行時間を計測する
profile_tasks タスク毎に実行時間を計測して長時間のタスクから順に表示
profile_roles ロール毎に実行時間を計測して長時間のロールから順に表示
55
Troubleshooting, Tips, and Tricks
有効にしたいCallback Pluginを、設定ファイル(ansible.cfg)のcallback_whitelistに列挙しま
す。以下のように利用したいプラグイン名を複数指定することがデキます。
ANSIBALLZファイルの実行処理 - (C)
#--- ansible.cfg ---
[defaults]
callback_whitelist = timer, profile_tasks, profile_roles
コールバックプラグインの詳細は、以下のドキュメントを御覧ください
https://docs.ansible.com/ansible/latest/plugins/callback.html
56
Troubleshooting, Tips, and Tricks
ANSIBALLZファイルの実行処理 - (C)
1.timerプラグインの出力例
Playbook run took 0 days, 0 hours, 1 minutes, 39 seconds
2.profile_tasksプラグインの出力例
Tuesday 30 June 2020 11:49:28 +0000 (0:00:20.122) 0:01:39.841 **********
===============================================================================
roleC : taskC1 --------------------------------------------------------- 61.00s
roleC : taskC2 --------------------------------------------------------- 20.12s
roleC : taskC0 --------------------------------------------------------- 11.16s
Gathering Facts --------------------------------------------------------- 2.40s
roleA : taskA0 ---------------------------------------------------------- 1.50s
roleB : taskB1 ---------------------------------------------------------- 1.07s
roleA : taskA1 ---------------------------------------------------------- 1.01s
roleB : taskB0 ---------------------------------------------------------- 1.00s
roleB : taskB2 ---------------------------------------------------------- 0.23s
roleA : taskA2 ---------------------------------------------------------- 0.19s
実行に数時間かかるようなタスクも時々
みかけます。
そのようなタスクは、もうその存在自体
を見直したほうが良いです。
57
Troubleshooting, Tips, and Tricks
ANSIBALLZファイルの実行処理 - (C)
3.profile_rolesプラグインの出力例
Tuesday 30 June 2020 11:53:39 +0000 (0:00:20.105) 0:01:39.558 **********
===============================================================================
roleC ------------------------------------------------------------------ 92.00s
gather_facts ------------------------------------------------------------ 3.05s
roleB ------------------------------------------------------------------- 2.33s
roleA ------------------------------------------------------------------- 2.08s
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
total ------------------------------------------------------------------ 99.46s
58
Troubleshooting, Tips, and Tricks
❏マネージドノードのANSIBALLZファイルを手動実行する
特定のタスクの実行失敗を追跡するときに、調査の過程で、実際にマネージドノード上でどのよ
うな処理が行われているのかを確認したくなることもあるでしょう。
通常、ANSIBALLZファイルは実行後処理で削除されますが、トラブルシュートのためにこれを
「削除せずに残す」ことができます。
ANSIBALLZファイルの実行処理 - (C)
$ ANSIBLE_KEEP_REMOTE_FILES=True ansible-playbook -i hosts sample.yml
59
Troubleshooting, Tips, and Tricks
環境変数ANSIBLE_KEEP_REMOTE_FILESをTrueにしてPlaybookを実行すると、タスクが実行
するANSIBALLZファイルをマネージドノード上で確認できます。
ANSIBALLZファイルの実行処理 - (C)
60
マネージドノード:
$ tree $HOME/.ansible/tmp/
/home/redhat/.ansible/tmp/
├── ansible-tmp-1595466930.0629175-62756-226010998879142
│ └── AnsiballZ_setup.py
└── ansible-tmp-1595466931.465439-62773-144981049406523
└── AnsiballZ_ping.py
# Playbook: sample.yml
---
- hosts: all
gather_facts: true
vars:
message: "Hello, Ansible!"
tasks:
- debug:
msg: "{{ message }}"
- ping:
ansible_remote_tmpディレクトリの配下
(通常は$HOME/.ansible/tmp/)
にANSIBALLZファイルが転送されているこ
とを確認できます。
Troubleshooting, Tips, and Tricks
例えば、Playbookで”gather_facts: true”を指定することによって実行されるsetupモジュール
から生成されたANSIBALLZファイル(AnsiballZ_setup.py)は、マネージドノード上で以下のよ
うに実行を確認できます。
ANSIBALLZファイルの実行処理 - (C)
マネージドノード:
$ $HOME/.ansible/tmp/ansible-tmp-<実行時のタイムスタンプから自動生成>/AnsiballZ_setup.py | jq .
61
Troubleshooting, Tips, and Tricks
ANSIBALLZファイルのペイロードはZIP圧縮されています。
デバッグ時には、ANSIBALLZファイルにexplodeサブコマンドを指定して実行します。すると
モジュールの引数や実行されるPythonコードがdebug_dir配下に展開されます。
これがANSIBALLZファイルの実体です。
ANSIBALLZファイルの実行処理 - (C)
マネージドノード:
$ cd $HOME/.ansible/tmp/ansible-tmp-<実行時のタイムスタンプから自動生成>
$ ./AnsiballZ_setup.py explode
$ debug_dir/
├── ansible/
│ ├── modules/ ...(1)
│ └── module_utils/ ...(2)
└── args … (3)
62
debug_dirディレクトリの配下に、ANSIBALLZファイル
のペイロードが展開されます。
(1)modules配下にAnsibleモジュールの実体
(2)module_utils配下にヘルパーモジュール群
(3)argsファイルにモジュールのパラメータ群
といった構成で配置されます
linkedin.com/company/red-hat
youtube.com/user/RedHatVideos
facebook.com/redhatinc
twitter.com/RedHat
Happy Automation!
63

Ansible troubleshooting 101_202007

  • 1.
  • 2.
    自己紹介 Troubleshooting, Tips, andTricks 氏名: 齊藤 秀喜(@saito_hideki) 所属: カスタマーエクスペリエンス&エンゲージメント/レッドハット株式会社 仕事: シニアソフトウェアメンテナンスエンジニア(Ansible Automation Platform) 趣味: Ansibleのトラブルシュート 本セッションは、 Software Design 2020年7月号 に寄稿した連載記事をベースに しています 2
  • 3.
    Troubleshooting, Tips, andTricks 本セッションでは、Ansibleを利用した自動化を進めるなかで発生するトラブルを解決するため に必要となるAnsibleの基礎知識と、トラブルシュートの手法について、テクニカルサポートの 現場で培った知見を元に解説します。 ❖ 問題を調査するためのアプローチ ❖ 前提知識: Ansibleの仕組みと問題が発生するポイント ❖ 問題を調査するためのテクニック 本セッションでお話すること 3
  • 4.
    Troubleshooting, Tips, andTricks 現在、広く認知されているように、Ansibleはプログラミングやエンジニアリングの経験が少な い、あるいはそれらを学ぼうとする人にとって、利用しやすいツールであることは間違いありま せん。 しかし、トラブルシューティングとなると話は別です。Ansible自体のアーキテクチャを理解す る必要があるのはもちろんのこと、Ansibleを実行するコントロールノードや、自動化の対象と なるマネージドノード上で稼働しているシステムに対する深い理解も必要となります。 残念ながら、Ansibleのトラブルシューティングは、シンプルでも簡単でもありません。 以降では、AnsibleがPlaybookを実行する仕組みと、コントロールノードやマネージドノード上 で、なぜ、みなさんが書いたPlaybookが想定通りに動作「しなかった」のかを調査するための ヒントをご紹介します。 はじめに 4
  • 5.
    Troubleshooting, Tips, andTricks 以下のようなことを念頭に置いてトラブルシュートをしています。 1. 正しくトリアージする(緊急度/影響範囲/優先度) 2. 憶測は排除し事実(例えばログファイル)をもとに発生している現象を正しく把握する 3. 問題を再現する TRIED. TESTED. TRUSTED. 4. 想定された動作なのか不具合なのか? 5. 既知の不具合か、未知の問題か? 6. 解決策やワークアラウンドは存在しているのか? 「問題」を調査するためのアプローチ 多くの人は自分に主観に基づいての 現象を報告してきます。 相手の思い込みや自分の憶測を排除 し、事実だけを見つめて問題を適切 にトリアージしましょう。 5
  • 6.
    Troubleshooting, Tips, andTricks まずは「問題」を「自分以外の誰か」に伝えられるように、以下の5つのポイントを意識して整 理してみてください。 経験上、当事者が他人にうまく伝えられない問題は、おそらく正しく調査・解決できません。 1. 問題の概要をまとめてタイトルをつける 2. どのような問題が発生していますか? 期待される動作はどのようなものですか? 3. どこで問題が発生しますか? どの環境で発生しますか? 4. いつ問題が発生しますか? 頻繁に発生しますか? 繰り返し発生しますか? 特定のタイミングで発生しますか? 5. 問題の緊急度はどれくらいですか? 解決までの期限や業務への影響はありますか? 「問題」を整理する 6
  • 7.
  • 8.
    Troubleshooting, Tips, andTricks たとえば、以下のようなPingモジュールを実行するシンプルなPlaybookの実行例 Ansibleの仕組みと問題が発生するポイント(1) $ cat playbook/ping_test.yml --- - name: Preflight playbook hosts: all gather_facts: true tasks: - name: Ping test ping: $ ansible-playbook -i hosts ping_test.yml PLAY [Preflight playbook] ************************************************************************************************* TASK [Gathering Facts] **************************************************************************************************** ok: [server00] TASK [Ping test] ********************************************************************************************************** ok: [server00] PLAY RECAP **************************************************************************************************************** server00 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 8
  • 9.
    Troubleshooting, Tips, andTricks Ansibleは、モジュールから生成した実行可能なPythonプログラムを、コントロールノードから マネージドノードに転送して実行します。 Ansibleの仕組みと問題が発生するポイント(2) Control Node Managed Node Module Python Program 9
  • 10.
    Managed node Remote tmpdirectory Remote tmp directory Troubleshooting, Tips, and Tricks Ansibleの仕組みと問題が発生するポイント(3) Control node Playbook Inventory AnsiballZ_setup.py AnsiballZ_ping.py AnsiballZ_setup.py AnsiballZ_ping.py Plugin 2) 1) 3) 4-b) 5-b) 4-d) 4-d,e,f) 5-d) 5-d,e,f) A C C 4-a,c,g) 5-a,c,g) B B B B 10
  • 11.
    Troubleshooting, Tips, andTricks 前出のサンプルPlaybook実行時の処理の流れは以下の通りです。 1) インベントリファイル(./inventories/testing/hosts)をロードする 2) cache/connection/become/shellプラグインをロードする 3) Strategy(デフォルトのlinearストラテジー)にしたがってマネージドノードに対する実行計画を生成 4) Setupモジュールの実行 a) マネージドノード上に一時的なワーキングディレクトリ(remote tmp directory)を作成 b) ANSIBALLZ形式でhost_vars、モジュールオプションパラメータを含めて実行プログラムのアーカイブを作成する => AnsiballZ_setup.py c) マネージドノードのPythonインタプリタのパスをディスカバリ d) 4.2で生成したAnsiballZ_setup.pyファイルをマネージドノードにsftpで転送 e) SSH経由でマネージドノード上に転送したAnsiballZ_setup.pyを実行 f) Callbackプラグインでモジュールの実行結果を標準出力(JSON形式)で受け取ってストア g) 4.1で作成したディレクトリ配下を削除 5) Pingモジュールの実行 ※詳細な流れは4-a...4-gと同様 (AnsiballZ_ping.py) 6) PLAY RECAPを出力してPlaybookの実行を終了 Ansibleの仕組みと問題が発生するポイント(4) 11
  • 12.
    Troubleshooting, Tips, andTricks Playbookを実行する際に発生するポイントは、大きく以下の3箇所に整理できます。 (A) Playbookの実行前処理  (B) ANSIBALLZファイルの転送処理 (C) ANSIBALLZファイルの実行処理 以降では、テクニカルサポートの現場で得られたノウハウを元に、上記の(A),(B),(C)それそれの フェーズで発生する問題の調査手法をご紹介します。 Ansibleの仕組みと問題が発生するポイント(5) 12
  • 13.
  • 14.
    Troubleshooting, Tips, andTricks ❏ Ansibleの実行ログをログファイルに出力する デフォルト設定では、Ansibleの実行ログは標準出力に出力されます。まずは、このログをログ ファイルに出力することから始めましょう。 トラブルシュートをはじめる前に...(1) #~~~ ansible.cfg ~~~ [defaults] log_path = /var/log/ansible.log Ansibleの設定ファイル(ansible.cfg)の、log_pathパラメータにログファイルのパスを設定し ます。 14
  • 15.
    Troubleshooting, Tips, andTricks ❏プラグインやモジュールのログ出力の詳細度(VERBOSITY)を調整する プラグインやモジュールの実行時に出力されるログの詳細度は5段階で、これを適切に調整する ことでトラブルシュートに役立つ情報を得ることができます。 トラブルシュートをはじめる前に...(2) $ ansible-playbook -i hosts main.yml -vvvvv レベル オプション 効果 1 -v 詳細な実行ログ出力 (設定ファイルのロードバス出力程度 ) 2 -vv より詳細な実行ログ 3 -vvv デバッグ出力(バックエンドで実行される sshコマンドの出力) 4 -vvvv コネクションデバッグ出力 (sshコマンドに-vvvオプションが指定され、より詳細なログが得られる ) 5 -vvvvv WinRMデバッグ出力(WinRM接続時の詳細ログが得られる ,一部のvalut処理のログも出力される ) 15
  • 16.
    Troubleshooting, Tips, andTricks ❏ デバッグモードを有効化する デバッグモードを有効化することで、プラグインやモジュールだけでなくエンジン部分の挙動を トレースすることができます。 トラブルシュートをはじめる前に...(3) a)ansible.cfgの設定で有効化する #~~~ ansible.cfg ~~~ [defaults] debug = True b)コマンド実行時に環境変数として一時的に指定する $ ANSIBLE_DEBUG=True ansible-playbook -i hosts main.yml $ ANSIBLE_DEBUG=True ansible-playbook -i hosts main.yml -vvvvv 16
  • 17.
  • 18.
    Troubleshooting, Tips, andTricks ❏ Playbookの構文エラー Playbook実行前処理で発生するエラーの多くは、PlaybookやInventoryファイルの書式に関す るものです。以下のような誤った記述のPlaybookを実行しようとした場合に発生します。 Playbook実行前処理 - (A) --- - hosts: all gather_facts: false tasks: name: Ping test to managed nodes - shell: hostname register: result name: Ping test to managed nodes - debug: var: result.stdout 疲れてくると、この手のエラーが 多くなりがちです。 明日の朝頑張ることにして、もう ビール飲んで寝ちゃいましょう。 18
  • 19.
    Troubleshooting, Tips, andTricks --syntax-checkオプションで、Playbook実行前にチェックして対応しておきましょう。 Playbook実行前処理 - (A) $ ansible-playbook -i hosts sample00.yml --syntax-check ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each: JSON: Expecting value: line 1 column 1 (char 0) Syntax Error while loading YAML. expected <block end>, but found '-' The error appears to be in '/Users/hsaito/work/testing/ansible/playbook/error/sample00/main.yml': line 7, column 3, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: name: Ping test to managed nodes - shell: hostname ^ here --syntax-checkでPlaybookの 構文エラーを解決したら ansible-lintによる構文規約の チェックを行いましょう 19
  • 20.
    Troubleshooting, Tips, andTricks ansible-playbookコマンドの引数に指定するPlaybook(エントリポイントとなるPlaybook)は、 hostsセクションを含む以下のように、“-”でブロック分割されるリスト構造となっている必要が あります。サンプルコードのコンテンツの”一部”をコピー&ペーストして使うのであれば書式に 十分注意してください。2つめ以降のhostsの前の”-”をみなさん忘れがちです。 Playbook実行前処理 - (A) $ ansible-playbook -i hosts sample.yml --list-hosts #~~~ sample.yml ~~~ --- - hosts: web ...snip... - hosts: app ...snip... - hosts: database ...snip... このケースは、--syntax-checkで は捕まえられません。 --list-hostsでマネージドノードの リストを確認しましょう 20
  • 21.
    Troubleshooting, Tips, andTricks ❏ Dynamic Inventoryが正しく動作しない Ansibleの大きな武器であるDynamic Inventoryですが、AWSやvCenterとの連携に問題があっ て同期に失敗すると、インベントリ情報が空となったり、想定外のマネージドノードのリストが 作られたり...といった問題が発生します。ansible-inventoryコマンドで確認しましょう。 Playbook実行前処理 - (A) $ ANSIBLE_DEBUG=True ansible-inventory -i aws_ec2.yml --list ... { "_meta": { "hostvars": {} }, "all": { # <= AWS上に仮想マシンインスタンスが存在するにもかかわらずallリストが空になっている "children": [ "ungrouped" ] } } 21
  • 22.
    Troubleshooting, Tips, andTricks Dynamic Inventoryプラグインは、同名の設定ファイル(プラグイン名.(yml|yaml))を実行時に指 定します。リストが空になったり、想定外のマネージドノードをリストアップしてしまうような ケースは、この設定ファイルに問題がある場合がほとんどです。 前項の例のように、デバッグモード(ANSIBLE_DEBUG=True)でansible-inventoryコマンドを 実行すれば、より詳細なDynamic Inventoryプラグインの挙動を確認できます。 Playbook実行前処理 - (A) #~~~ aws_ec2.yml ~~~ plugin: aws_ec2 aws_access_key: <認証用アクセスキー> aws_secret_key: <認証用シークレットキー> regions: - ap-northeast-1 filters: tag:Owner: hsaito compose: ansible_host: private_ip_address このケースでは、tagパラーメータが適切 にインデントされておらず、filtersパラ メータのチェックに失敗します。 結果としてプラグインが正しく実行され ず、ノードリストが空となります。 問題を修正したあとで、デバッグログを 改めて見ると「あぁ...」となりますが、正 直ログでの解析は結構むずかしい問題の 1つです。 22
  • 23.
    Troubleshooting, Tips, andTricks ❏ Static Inventoryが正しく動作しない Static Inventoryも、Dynamic Inventoryと同様にプラグイン経由でロードされます。Dynamic Inventoryと同様の仕組みですから、動作確認も同様にansible-inventoryコマンドで実施できま す。 Playbook実行前処理 - (A) $ ANSIBLE_DEBUG=True ansible-inventory -i hosts --list ... { "_meta": { "hostvars": {} }, "all": { # <= Inventoryファイルにマネージドノードが記述されているにもかかわらずallリストが空になっている "children": [ "ungrouped" ] } } 23
  • 24.
    Troubleshooting, Tips, andTricks Static Inventoryの問題は、 Inventoryファイルの記述ミスが原因ですから、問題の調査も Dynamic Inventoryよりも単純で、デバッグログからも比較的見つけやすいため、積極的に ANSIBLE_DEBUG=Trueでデバッグログを生成して確認してみましょう。 Playbook実行前処理 - (A) #~~~ hosts ~~~ [server] server00 server01 server02 server03 [server:vars] ansible_user: hsaito # INI形式ではなくYAML形式で書かれている このケースでは、INIファイルであ るにもかかわらず、group_varsの 指定がYAML形式になっていま す。あなたは疲れています。 ビールでも飲んで寝ましょう。 24
  • 25.
    Troubleshooting, Tips, andTricks Playbook実行前処理 - (A) $ ansible-config dump --only-changed DEFAULT_LOG_PATH(/home/hsaito/testing/ansible.cfg) = /home/hsaito/testing/logs/ansible.log HOST_KEY_CHECKING(/home/hsaito/testing/ansible.cfg) = False INVENTORY_ENABLED(/home/hsaito/testing/ansible.cfg) = ['aws_ec2'] ❏ ansible.cfgの設定ミス Ansibleの振る舞いは、設定ファイル(ansible.cfg)に記述します。 デフォルト値から意図せず変更されていないかを、トラブルシュートの初期段階で確認しておき ましょう。 ansible-configコマンドに、dumpサブコマンドを--only-changedオプション付きで指定するこ とで、デフォルト設定から変更した箇所のみを確認することができます。 設定ファイルのパスと優先度(ANSIBLE_CONFIGが最優先)は以下のリンクにある通りです。 複数のパスにansible.cfgが存在する場合は、最も優先度の高いファイルがロードされ、他の ファイルはロードされないので注意してください。 https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings 25
  • 26.
    Troubleshooting, Tips, andTricks Playbook実行前処理 - (A) $ ansible-config dump --only-changed DEFAULT_LOG_PATH(/home/hsaito/testin/ansible.cfg) = /home/hsaito/testing/logs/ansible.log HOST_KEY_CHECKING(/home/hsaito/testing/ansible.cfg) = False INVENTORY_ENABLED(/home/hsaito/testing/ansible.cfg) = ['aws_ec2'] $ ansible-config dump --only-changed DEFAULT_LOG_PATH(/home/hsaito/testing/ansible.cfg) = /home/hsaito/testing/logs/ansible.log HOST_KEY_CHECKING(/home/hsaito/testing/ansible.cfg) = False INVENTORY_ENABLED(/home/hsaito/testing/ansible.cfg) = ['host_list', 'script', 'auto', 'yaml', 'ini', 'toml', 'aws_ec2'] 以下のようにデフォルト値に 追記する形に修正する このケースでは、aws_ec2をInventory プラグインとして指定しています。この 設定は、デフォルト設定を上書きして aws_ec2プラグインのみを有効化するた め、INI形式やYAML形式で記述された Static Inventoryファイルを正しくロー ドできなくなります。 26
  • 27.
    Troubleshooting, Tips, andTricks Playbook実行前処理 - (A) . ├── library │ └── <latest_module>.py # Upstreamから取得した最新版のモジュール ├── module_utils │ └── <helper_module>.py # モジュールが必要とするヘルパーモジュールがあればココに配置 └── playbook.yml ❏ 最新のモジュールでテストしてみる モジュールロードパスで最優先されるのは、Playbookディレクトリにある ”library/” 配下のモジュールです。 調査の過程で、モジュールの挙動が怪しく、これが現在は修正されているというようなケースで は、Upstreamから不具合が修正されたモジュールを取得して動作確認を行うことで、問題の調 査を1歩進めることができるでしょう。 27
  • 28.
    Troubleshooting, Tips, andTricks まとめ: Playbook実行前処理 - (A) 1. Playbookの構文チェックを実施する: Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> --syntax-check 2. Playbookの適用対象となるマネージドホストのリストを確認する: Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> --list-hosts 3. Dynamic Inventoryプラグインが想定通りの設定で機能していることを確認する: Usage: ANSIBLE_DEBUG=True ansible-inventory -i <INVENTORY_PLUGIN_NAME>.(yml|yaml) --list 4. Static Inventoryファイルが想定通りの設定でロードされていることを確認する: Usage: ANSIBLE_DEBUG=True ansible-inventory -i <INVENTORY_FILE> --list 5. Ansibleの設定ファイル(ansible.cfg)のパスとデフォルトから変更している設定内容を確認する: Usage: ansible-config dump --only-changed 本セクションで登場したコマンドと機能は以下の通りです。 28
  • 29.
  • 30.
    Troubleshooting, Tips, andTricks ❏マネージドノードのタイプで違うPlaybookの転送方法 Ansibleがモジュールから生成するANSIBALLZファイルは、操作対象であるマネージドノードの タイプ毎に異なる方法で、マネージドノードに転送されます。 この転送フェーズが、コントロールノードとマネージドノード間のファーストコンタクトであ り、接続エラーの多くは、このフェーズで発生します。 尚、3),4)については、通常はコントロールノード上で実行されるため、転送は発生しません。 1) UNIX系 2) Windows 3) ネットワークデバイス 4) IaaSシステム(Amazon EC2/GCP/Azure/vCenter/OpenStack...etcetera) ANSIBALLZファイルの転送 - (B) 30
  • 31.
    Troubleshooting, Tips, andTricks 1) UNIX系ノードへの転送(デフォルトの挙動) ANSIBALLZファイルの転送 - (B) Control Node Managed Node ANSIBALLZ ANSIBALLZ A.マネージドノードがsftpを許可し ている場合はsftpで転送する。 B.sftpを許可していない場合はscp で転送する。 31
  • 32.
    Troubleshooting, Tips, andTricks 2) Windowsノードへの転送 Windowsノードへの接続するには ansible_connection=winrm を指定します。 ANSIBALLZファイルの転送 - (B) Control Node Managed Node ANSIBALLZ ANSIBALLZ WinRMを利用してhttp/httpsで転送する 参考リンク: https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html#windows-remote-management 32
  • 33.
    Troubleshooting, Tips, andTricks このフェーズでのトラブルは、SCP/SFTP接続時やWinRM接続時の認証失敗によるものがほとん どです。まずはログの解析からトラブルシュートをはじめましょう。 ANSIBALLZファイルの転送 - (B) 1) マネージドノードがUNIX系の場合(VERBOSITY:4) $ ansible-playbook -i hosts sample.yml -vvvv 2) マネージドノードがWindowsの場合(VERBOSITY:5) $ ansible-playbook -i hosts sample.yml -vvvvv 33
  • 34.
    Troubleshooting, Tips, andTricks UNIX系のマネージドノードでは、ANSIBALLZファイルの転送にSCP/SFTPを利用します。接続 に失敗するようなケースでは、”-vvvv”オプションを指定してPlaybookを実行することで、バッ クグラウンドで実行されるssh/scp/sftpコマンドに”-vvv”オプションが指定されます。 UNIX系: ANSIBALLZファイルの転送 - (B) $ ansible-playbook -i hosts sample01.yml -vvvv ... TASK [ping] **************************************************************************************************** ******************************************************************* task path: /home/hsaito/work/testing/codt2020/playbook/sample/sample01.yml:6 <server00> ESTABLISH SSH CONNECTION FOR USER: redhat <server00> SSH: EXEC sshpass -d11 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'User="redhat"' -o ConnectTimeout=10 ... ... <server00> SSH: EXEC sshpass -d11 sftp -o BatchMode=no -b - -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'User="redhat"' -o ConnectTimeout=10 -o ControlPath=/home/hsaito/.ansible/cp/ac861c7aaa '[server00]' ... 34
  • 35.
    Troubleshooting, Tips, andTricks マネージドノード側のsshdをデバッグオプション付きで起動することで、接続の失敗に関する 詳細なログを、マネージドホスト側でも確認することができます。 authorized_keysの不適切なパーミッション設定など、マネージドホスト側の設定ミスが原因で 失敗しているようなケースでは有効な調査方法です。 UNIX系: ANSIBALLZファイルの転送 - (B) [RHEL/CentOS] #/etc/sysconfig/sshd #--- OPTIONS="-ddd" #--- 大量のログが出力されるため、 デバッグ時に限定して設定・運用 することをおすすめします。 sshdのリスタートも忘れずに! 35
  • 36.
    Troubleshooting, Tips, andTricks 以下のログは、Windowsノードであるにもかかわらず、ansible_connectionパラメータに winrmが設定されておらず、デフォルトのSCP/SFTPで接続して失敗しています。 Windows: ANSIBALLZファイルの転送 - (B) TASK [win_ping] **************************************************************************************************** task path: /home/hsaito/work/testing/ansible/playbook/sample/sample01.yml:6 <win2019-00> ESTABLISH SSH CONNECTION FOR USER: Administrator <win2019-00> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s) <win2019-00> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set: (-o)(User="Administrator") <win2019-00> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10) <win2019-00> SSH: PlayContext set ssh_common_args: () <win2019-00> SSH: PlayContext set ssh_extra_args: () <win2019-00> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath=/home/hsaito/.ansible/cp/73ffcfe560) <win2019-00> SSH: EXEC sshpass -d10 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="Administrator"' -o ConnectTimeout=10 -o ControlPath=/home/hsaito/.ansible/cp/73ffcfe560 win2019-00 '/bin/sh -c '"'"'echo ~Administrator && sleep 0'"'"'' ...snip... UNIX系以外のマネージドノード を相手にするときは、それぞれの 通信要件にあわせて ansible_connectionを適切に設定 しましょう。 36
  • 37.
    Troubleshooting, Tips, andTricks Windowsノード側では、WinRMの初期設定を適切に実施する必要があります。 公式ドキュメントにしたがって、Windowsノード側でWinRMの初期設定を実施してください。 > https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html Windows: ANSIBALLZファイルの転送 - (B) PS C:UsersAdministrator> winrm.cmd get winrm/config Ansibleで接続できない? WinRMの初期設定をわすれて いませんか?もういちど見直 しましょう 37
  • 38.
    Troubleshooting, Tips, andTricks Windowsノードにログインするためのログイン情報は以下のパラメータで設定します。 Active Directoryを利用している場合は、ansible-playbookコマンドを実行するコントロール ノード側で、Kerberos認証の設定が必要です。 ● ユーザ名(ansible_username) ● パスワード(ansible_password) Windows: ANSIBALLZファイルの転送 - (B) $ kinit <USERNAME>@<DOMAIN> Password for <USERNAME>@<DOMAIN>: ******** $ klist Ticket cache: KCM:1001 Default principal: <USERNAME>@<DOMAIN> Valid starting Expires Service principal 06/29/2020 03:21:29 06/29/2020 13:21:29 krbtgt/<DOMAIN>@<DOMAIN> renew until 07/06/2020 03:21:27 AD認証を利用する場合は、コントロー ルノードでの設定も必要です。 kinitコマンドによるユーザ認証が正し く行われるかを確認してください。 38
  • 39.
    Troubleshooting, Tips, andTricks ping/win_pingモジュールを利用して、マネージドノードとの接続が正しく行われるかを確認す ることができます。 共通: ANSIBALLZファイルの転送 - (B) $ ansible centos8-00 -i hosts -m ping -vvvv $ ansible win2019-00 -i hosts -m win_ping -vvvvv pingモジュール,win_pingモジュールを 利用して、マネージドノードとの接続を 確認できます。 39
  • 40.
    Troubleshooting, Tips, andTricks まとめ: ANSIBALLZファイルの転送処理 - (B) 1. コントロールノード - マネージドノード間の接続ログ確認 1a. マネージドノードがUNIX系の場合(VERBOSITY:4) Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> -vvvv 1b. マネージドノードがWindowsの場合(VERBOSITY:5) Usage: ansible-playbook -i <INVENTORY> <PLAYBOOK> -vvvvv 2. sshdのデバッグログ出力(RHEL/CentOS) #~~~ /etc/sysconfig/sshd ~~~ OPTIONS="-ddd" 3. WinRM設定の確認 > winrm.cmd get winrm/config 4.コントロールノード - マネージドノード間の接続チェック Usage: ansible <MANAGED_NODE> -i <INVENTORY> -m ping -vvvv Usage: ansible <MANAGED_NODE> -i <INVENTORY> -m win_ping -vvvvv 本セクションで登場したコマンドと設定は以下の通りです。 40
  • 41.
  • 42.
    Troubleshooting, Tips, andTricks ❏Playbookの実行ログを確認する Ansibleはデフォルトの動作ログは、デフォルト設定ではSTDOUTに出力されます。 Ansible Playbookの動作ログファイルを残すというのは問題調査の第一歩です。 ANSIBALLZファイルの実行処理 - (C) #~~~ ansible.cfg ~~~ [defaults] log_path = /var/log/ansible.log システム運用では、ターミナルログを常に 取得しておくというのは基本中の基本です が、コントロールノード側でも取得してお きましょう。 42
  • 43.
    Troubleshooting, Tips, andTricks ❏Playbookのタスクをステップ実行する(--step) Playbookのデバッグ時に、各タスクをステップ実行したいようなケースでは--stepオプション を指定してください。中止(n)、実行(y)、以降のタスクをインタラクションなしで実行(c)の中か ら選択してタスクを実行します。 ANSIBALLZファイルの実行処理 - (C) $ ansible-playbook -i hosts sample.yml --step PLAY [all] *************************************************** Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: 後述するPlaybook Debuggerを使ってしま うので、正直あまり登場機会はありません が、タスクの実行前にマネージドノード側 で特定の条件を作り出したいよなケースで は有効です 43
  • 44.
    Troubleshooting, Tips, andTricks ❏Playbookを特定のタスクから実行する(--start-at-task) ある特定のタスクの調査のために、前段のタスクを飛ばして特定のタスクからPlaybookを実行 したいようなケースで利用します。 ANSIBALLZファイルの実行処理 - (C) $ ansible-playbook -i hosts sample.yml -l --start-at-task "task B" PLAY [all] *********************************************************************************************** TASK [Gathering Facts] *********************************************************************************************** ok: [centos8.test.fgrep.org] TASK [task B] *********************************************************************************************** ok: [centos8.test.fgrep.org] ... タスクのnameセクションに設定したタ スク名を指定して、そのタスクから Playbookを実行します。 Gather Factsはスキップしません。 44
  • 45.
    Troubleshooting, Tips, andTricks ❏モジュールが必要とするライブラリやコマンドがインストールされていることを確認する Ansibleのモジュールは数多くありますが、利用に際しては必ずドキュメントを読みましょう。 特にRequirementsには、モジュールが動作するのに必要なライブラリやコマンドの情報が書か れています。 ANSIBALLZファイルの実行処理 - (C) 例: gitモジュール Requirements The below requirements are needed on the host that executes this module. ●git>=1.7.1 (the command line tool) これらは、 「ANSIBALLZファイルを実行するノード」 にインストールする必要があります! 45
  • 46.
    Troubleshooting, Tips, andTricks ❏gather_subsetで収集する情報を調整する “gather_facts: true”では、マネージドノードのハードウェア情報を含めたさまざまな情報を収 集して、ansible_factsに格納し、後段のタスクから利用できるようにします。 たとえば、ディスクなどのデバイスが、device busyで無応答となってしまうような状態だと、 この”Gathering Facts”タスクがスタックして無応答となります。 gather_subsetで、取得する情報量を調整することで、このような無応答状態を抑止できる可能 性があります。 ANSIBALLZファイルの実行処理 - (C) --- - hosts: all gather_facts: true gather_subset: - min ... その情報、本当に必要ですか? 利用しない情報なら gather_subset を調整 して収集しないようにしましょう。 > setupモジュール(https://docs.ansible.com/ansible/latest/modules/setup_module.html) 46
  • 47.
    Troubleshooting, Tips, andTricks ❏ライブラリパスに余計なファイルは配置しない ansibleのモジュールパスにAnsibleのモジュールと同名のPythonプログラム(例えばsetup.py) を配置してはいけません。 ANSIBALLZファイルの実行処理 - (C) $ tree sample04 sample |-- library | `-- setup.py `-- sample.yml $ ansible-playbook -i hosts sample/sample.yml ... TASK [Gathering Facts] ********************************************************************************************* fatal: [centos8.test.fgrep.org]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup": {"failed": true, "module_stderr": "Shared connection to centos8.test.fgrep.org closed.rn", "module_stdout": "/usr/bin/env: ‘python’: No such file or directoryrn", "msg": "MODULE FAILUREnSee stdout/stderr for the exact error", "rc": 127}}, "msg": "The following modules failed to execute: setupn"} うっかり *PythonSDK のようなソースコードを、 モジュールパスに展開していしまうと... Ansibleはそれに含まれるsetup.pyを、自身の setupモジュールと誤認識して利用しようとします 47
  • 48.
    Troubleshooting, Tips, andTricks ❏変数の値をチェックする モジュールの引数や、テンプレートモジュールで置換する変数に想定した値が設定されていない ようなケースでは、debugモジュールを利用して変数の値を確認することができます。 ANSIBALLZファイルの実行処理 - (C) ... vars: home_dir: '{{ lookup("env", "HOME") }}' tasks: - debug: var: home_dir ... このケースではHOMEをHOGEのようにtypo しても文法上はエラーとならず、home_dirは 空となります。 debugモジュールで値をチェックしましょ う。変数のチェックにはmsgよりもvarがおす すめです。 48
  • 49.
    Troubleshooting, Tips, andTricks ❏Playbook Debuggerを利用する タスクの条件分岐(when句)が適切に行われないようなケースでは、-vvvのように詳細レベルを 上げても、ANSIBLE_DEBUG=Trueでデバッグモードを有効化しても、判断条件を確認すること はできません。このような問題の調査には、Playbook Debuggerが有効です。 ANSIBALLZファイルの実行処理 - (C) --- - hosts: all debugger: never tasks: - stat: path: /etc/hosts when: - foo == "FOO" - bar == "BAR" debugger: on_skipped Playbookのデバッグで消耗せずに済むの で、Playbook Debuggerは非常におすすめ のツールです。 以降で少し詳しく使い方を紹介します 49
  • 50.
    Troubleshooting, Tips, andTricks Playbook Debuggerの利用方法は難しくありません。 たとえば前出のPlaybookであれば、skip時にPlaybook Debuggerが起動してコマンド入力待ち となります。 ANSIBALLZファイルの実行処理 - (C) ansible-playbook -i hosts -e "foo=FOO,bar=BAR" sample.yml -v PLAY [all] ********************************************************************************************* TASK [Gathering Facts] ********************************************************************************************* ok: [centos8.test.fgrep.org] TASK [stat] ******************************************************************************************** skipping: [centos8.test.fgrep.org] => {"changed": false, "skip_reason": "Conditional result was False"} [centos8.test.fgrep.org] TASK: stat (debug)> 50
  • 51.
    Troubleshooting, Tips, andTricks 以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。 https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands ANSIBALLZファイルの実行処理 - (C) 1.タスクを実行したマネージドホストを表示する > p host centos8.test.fgrep.org 2.タスク名を表示する > p task debug 3.タスクの実行結果を表示する > p result._result {'_ansible_no_log': False, 'changed': False, 'skip_reason': 'Conditional result was False', 'skipped': True} 51
  • 52.
    Troubleshooting, Tips, andTricks 以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。 https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands ANSIBALLZファイルの実行処理 - (C) 4.タスクから参照できる全変数を表示する > p task_vars ...Taskレベルで利用せきる全ての変数とその値が表示されます... 5.タスクから参照できる特定の変数を表示する > p task_vars['foo'] 'FOO,bar=BAR' > p task_vars['bar'] ***KeyError:KeyError('bar') この例では、-eオプションの指定を誤って fooに想定外の値が設定され、barが未設定 の状態となっているのがわかります。 52
  • 53.
    Troubleshooting, Tips, andTricks 以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。 https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands ANSIBALLZファイルの実行処理 - (C) 6.タスクで実行しているモジュールのパラメータを表示する > p task.args {'path': '/etc/hosts'} 7.タスクが参照している特定の変数を再設定する > task_vars['foo'] = 'FOO' > task_vars['bar'] = 'BAR' > p task_vars['foo'],task_vars['bar'] ('FOO', 'BAR') 8.再設定した変数やパラメータでタスクを更新する > u 53
  • 54.
    Troubleshooting, Tips, andTricks 以下のリンクにPlaybook Debuggerのコマンド一覧が記載されています。 https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html#available-commands ANSIBALLZファイルの実行処理 - (C) 9.タスクで実行しているモジュールの特定のパラメータを表示する > p task.args['path'] '/etc/hosts' 10.タスクで実行しているモジュールの特定のパラメータの値を変更する(‘u’で更新する変更前の値に戻ってしまうので注意) > task.args['path'] = '/etc/hostname' > p task.args['path'] '/etc/hostname'' 11.タスクを再実行する > r task.args[‘パラメータ名’]で、モジュールの パラメータを更新後に”更新(u)してはいけま せん。task_varsの変更と更新(u)は、10.よ りも前にじ実施しておいてください 54
  • 55.
    Troubleshooting, Tips, andTricks ❏Playbookのパフォーマンスを計測する(1) Playbookの実行完了までに長時間かかるので少しでも短縮したい...といった、パフォーマンス に関する問題では、どのタスクでどの程度の時間がかかっているのかを計測して、改善の必要な タスクを洗い出すのが最初の一歩となります。 Callback Pluginを利用して、Playbookの実行時間を計測しましょう。 ANSIBALLZファイルの実行処理 - (C) プラグイン名 機能 timer Playbook全体の実行時間を計測する profile_tasks タスク毎に実行時間を計測して長時間のタスクから順に表示 profile_roles ロール毎に実行時間を計測して長時間のロールから順に表示 55
  • 56.
    Troubleshooting, Tips, andTricks 有効にしたいCallback Pluginを、設定ファイル(ansible.cfg)のcallback_whitelistに列挙しま す。以下のように利用したいプラグイン名を複数指定することがデキます。 ANSIBALLZファイルの実行処理 - (C) #--- ansible.cfg --- [defaults] callback_whitelist = timer, profile_tasks, profile_roles コールバックプラグインの詳細は、以下のドキュメントを御覧ください https://docs.ansible.com/ansible/latest/plugins/callback.html 56
  • 57.
    Troubleshooting, Tips, andTricks ANSIBALLZファイルの実行処理 - (C) 1.timerプラグインの出力例 Playbook run took 0 days, 0 hours, 1 minutes, 39 seconds 2.profile_tasksプラグインの出力例 Tuesday 30 June 2020 11:49:28 +0000 (0:00:20.122) 0:01:39.841 ********** =============================================================================== roleC : taskC1 --------------------------------------------------------- 61.00s roleC : taskC2 --------------------------------------------------------- 20.12s roleC : taskC0 --------------------------------------------------------- 11.16s Gathering Facts --------------------------------------------------------- 2.40s roleA : taskA0 ---------------------------------------------------------- 1.50s roleB : taskB1 ---------------------------------------------------------- 1.07s roleA : taskA1 ---------------------------------------------------------- 1.01s roleB : taskB0 ---------------------------------------------------------- 1.00s roleB : taskB2 ---------------------------------------------------------- 0.23s roleA : taskA2 ---------------------------------------------------------- 0.19s 実行に数時間かかるようなタスクも時々 みかけます。 そのようなタスクは、もうその存在自体 を見直したほうが良いです。 57
  • 58.
    Troubleshooting, Tips, andTricks ANSIBALLZファイルの実行処理 - (C) 3.profile_rolesプラグインの出力例 Tuesday 30 June 2020 11:53:39 +0000 (0:00:20.105) 0:01:39.558 ********** =============================================================================== roleC ------------------------------------------------------------------ 92.00s gather_facts ------------------------------------------------------------ 3.05s roleB ------------------------------------------------------------------- 2.33s roleA ------------------------------------------------------------------- 2.08s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ total ------------------------------------------------------------------ 99.46s 58
  • 59.
    Troubleshooting, Tips, andTricks ❏マネージドノードのANSIBALLZファイルを手動実行する 特定のタスクの実行失敗を追跡するときに、調査の過程で、実際にマネージドノード上でどのよ うな処理が行われているのかを確認したくなることもあるでしょう。 通常、ANSIBALLZファイルは実行後処理で削除されますが、トラブルシュートのためにこれを 「削除せずに残す」ことができます。 ANSIBALLZファイルの実行処理 - (C) $ ANSIBLE_KEEP_REMOTE_FILES=True ansible-playbook -i hosts sample.yml 59
  • 60.
    Troubleshooting, Tips, andTricks 環境変数ANSIBLE_KEEP_REMOTE_FILESをTrueにしてPlaybookを実行すると、タスクが実行 するANSIBALLZファイルをマネージドノード上で確認できます。 ANSIBALLZファイルの実行処理 - (C) 60 マネージドノード: $ tree $HOME/.ansible/tmp/ /home/redhat/.ansible/tmp/ ├── ansible-tmp-1595466930.0629175-62756-226010998879142 │ └── AnsiballZ_setup.py └── ansible-tmp-1595466931.465439-62773-144981049406523 └── AnsiballZ_ping.py # Playbook: sample.yml --- - hosts: all gather_facts: true vars: message: "Hello, Ansible!" tasks: - debug: msg: "{{ message }}" - ping: ansible_remote_tmpディレクトリの配下 (通常は$HOME/.ansible/tmp/) にANSIBALLZファイルが転送されているこ とを確認できます。
  • 61.
    Troubleshooting, Tips, andTricks 例えば、Playbookで”gather_facts: true”を指定することによって実行されるsetupモジュール から生成されたANSIBALLZファイル(AnsiballZ_setup.py)は、マネージドノード上で以下のよ うに実行を確認できます。 ANSIBALLZファイルの実行処理 - (C) マネージドノード: $ $HOME/.ansible/tmp/ansible-tmp-<実行時のタイムスタンプから自動生成>/AnsiballZ_setup.py | jq . 61
  • 62.
    Troubleshooting, Tips, andTricks ANSIBALLZファイルのペイロードはZIP圧縮されています。 デバッグ時には、ANSIBALLZファイルにexplodeサブコマンドを指定して実行します。すると モジュールの引数や実行されるPythonコードがdebug_dir配下に展開されます。 これがANSIBALLZファイルの実体です。 ANSIBALLZファイルの実行処理 - (C) マネージドノード: $ cd $HOME/.ansible/tmp/ansible-tmp-<実行時のタイムスタンプから自動生成> $ ./AnsiballZ_setup.py explode $ debug_dir/ ├── ansible/ │ ├── modules/ ...(1) │ └── module_utils/ ...(2) └── args … (3) 62 debug_dirディレクトリの配下に、ANSIBALLZファイル のペイロードが展開されます。 (1)modules配下にAnsibleモジュールの実体 (2)module_utils配下にヘルパーモジュール群 (3)argsファイルにモジュールのパラメータ群 といった構成で配置されます
  • 63.