SlideShare a Scribd company logo
Cloud Operator Days Tokyo 2021
Ansibleのトラブルシューティング 2021
~トラブルシュートに役立つテクニック ~
齊藤 秀喜(@saito_hideki)
シニアソフトウェアメンテナンスエンジニア(Ansible Automation Platform)
レッドハット株式会社
自己紹介
氏名: 齊藤 秀喜(Twitter: @saito_hideki)
所属: カスタマーエクスペリエンス&エンゲージメント/レッドハット株式会社
仕事: シニアソフトウェアメンテナンスエンジニア(Ansible Automation Platform)
趣味: Ansibleのトラブルシュート(最近ちょっと飽きてきた)
本セッションは、
Cloud Operator Days 2020 のトラブル
シューティングセッションの続編です。
2020年版はコチラから
-> https://bit.ly/2SNZhHz
2
Cloud Operator Days Tokyo 2021
Cloud Operator Days Tokyo 2021
Cloud Operator Days 2020年の同セッションの続編として、今回は、Ansibleが標準で提供す
るさまざまなデバッグ機能にフォーカスします。
CLI、インベントリ、モジュール、プラグインといった、各コンポーネントの問題を調査するた
めに役立つAnsibleのデバッグ機能の仕組みと、その使い所をご紹介します。
本セッションの手法を実施するにあたっては、Pythonのコードリーディング技術が必要となり
ますが、それほど高度なリーディングは必要ありませんので絶望せずにお付き合いください。
❖ アーキテクチャとコンポーネント(ふりかえり)
❖ トラブルシューティングの準備
❖ CLI/インベントリ/プラグインの調査
❖ モジュールの調査
注)Playbookの「記述ミス」や「書き方」の問題で想定通りに動作しないようなケースの調査方法については、
2020年のセッションで紹介していますので、そちらをご覧ください。
本セッションでお話すること
3
Ansibleのアーキテクチャとコンポーネント
Ansibleのトラブルシューティング
4
Cloud Operator Days Tokyo 2021
Ansibleのアーキテクチャとコンポーネント
5
ANSIBLE AUTOMATION ENGINE
CMDB
USERS
INVENTORY
HOSTS
NETWORK
DEVICES
PLUGINS
CLI
MODULES
ANSIBLE
PLAYBOOK
PUBLIC / PRIVATE
CLOUD
PUBLIC / PRIVATE
CLOUD
Cloud Operator Days Tokyo 2021
Ansibleを構成するコンポーネントとデバッグ手法
6
# コンポーネント 役割 調査に利用するデバッグ機能
[1] CLI ansible-playbookなどのコマンドラインツール群。
* ANSIBLE_DEBUG=True
* --verbose
[2] INVENTORY インベントリファイル自体やローダー。
* ANSIBLE_DEBUG=True
* --verbose
[3] PLUGIN
フィルタやコールバックなどのプラグインプログラム群。
最近のバージョンではダイナミックインベントリもプラグイン化
されている。
* ANSIBLE_DEBUG=True
* --verbose
[4] MODULE Playbookからタスクとして実行するプログラム群。 * ANSIBLE_KEEP_REMOTE_FILES=True
[5] PLAYBOOK 自動化するオペレーションを記述した定義ファイル群。
* debugモジュール, register機能
* --syntax-check, --list-tasks, --list-tags
Ansibleトラブルシューティングの準備
Ansibleのトラブルシューティング
7
Cloud Operator Days Tokyo 2021
問題の調査に着手するにあたって、まずは「システム環境」を可能な限り正しく把握する必要が
あります。
まずは、以下の必須情報を確認しましょう。
❏ コントロールノードの情報
❏ OS情報
❏ Pythonインタプリタのバージョン
❏ Ansibleのバージョン
❏ Collectionsのバージョン
❏ HWあるいはVMのスペック
❏ マネージドノード
❏ マネージドノードの種類(ベアメタルサーバ、ネットワークデバイスなど)
❏ OS情報
❏ HWあるいはVMのスペック
❏ Pythonインタプリタのバージョン(ベアメタルサーバやVMインスタンスの場合)
基礎知識 (1/2)
8
Cloud Operator Days Tokyo 2021
問題発生当時点の鮮度の高い情報も収集しておきます。
❏ コントロールノードの環境情報
❏ OSログファイル(RHEL系であればsosreportで一気に収集してしまう手もあり)
❏ Ansibleの実行ログ(ansible.cfgでログ出力設定 - 2020年のセッション参照)
❏ pip等でインストールしたPythonモジュールのバージョンとリスト
❏ マネージドノードの環境情報
❏ OSログファイル
❏ pip等でインストールしたPythonモジュールのバージョンとリスト
❏ 直接タスク実行プロセスにstraceコマンドでアタッチして状況を確認
❏ ネットワークの情報
❏ コントロールノードとマネージドノードの間にFirewall、ロードバランサ、Proxyな
どが存在していないか?
❏ DNS、LDAP、SAML、NFS等のネットワークサービスを利用していないか?
基礎知識 (2/2)
9
Cloud Operator Days Tokyo 2021
以降では、Ansibleのデバッグを行なうにあたって、Ansibleのソースコードと、ここで作成する
仮想環境を利用して、デバッグメッセージを仕込みつつ検証を行います。
はじめに、アップストリームのソースコードをgit cloneしてデバッグ環境を準備します。
デバッグ環境を準備する(1/4)
10
#例: 問題の発生している環境がAnsible 2.11.1である場合
$ mkdir -p $HOME/testing/src/
$ cd $HOME/testing/src/
$ git clone https://github.com/ansible/ansible.git
$ cd ansible
$ git checkout -b v2.11.1 refs/tags/v2.11.1
$ git log -n 1
commit f468ec7087d57b21acf2a0545075192a9cceacb5 (HEAD -> v2.11.1, tag: v2.11.1)
Author: Rick Elrod <rick@elrod.me>
Date: Mon May 24 14:50:49 2021 -0500
New release v2.11.1
Cloud Operator Days Tokyo 2021
続いて、virtualenvを利用して検証用の仮想環境を作成します。
デバッグ環境を準備する(2/4)
11
$ git status
On branch v2.11.1
nothing to commit, working tree clean
$ python3 -m venv venv
$ source venv/bin/activate
(venv)$ pip install -r requirements.txt
(venv)$ source hacking/env-setup
running egg_info
...中略...
PYTHONPATH=/home/hsaito/testing/src/ansible/lib
MANPATH=/home/hsaito/testing/src/ansible/docs/man:/usr/local/share/man:/usr/share/man
Remember, you may wish to specify your host file with -i
Done!
$
Cloud Operator Days Tokyo 2021
仮想環境の設定が完了すると、AnsibleのソースコードをベースとしたAnsible CLIが利用できる
ようになります。
デバッグ環境を準備する(3/4)
12
$ ansible --version
ansible [core 2.11.1] (v2.11.1 f468ec7087) last updated 2021/06/29 22:18:01 (GMT +900)
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/hsaito/.ansible/plugins/modules',
'/usr/share/ansible/plugins/modules']
ansible python module location = /home/hsaito/testing/src/ansible/lib/ansible
ansible collection location = /home/hsaito/.ansible/collections:/usr/share/ansible/collections
executable location = /home/hsaito/testing/src/ansible/bin/ansible
python version = 3.9.5 (default, May 14 2021, 00:00:00) [GCC 11.1.1 20210428 (Red Hat 11.1.1-1)]
jinja version = 3.0.1
libyaml = True
$
Cloud Operator Days Tokyo 2021
Collectionsを利用している場合は、ansible.cfgの設定を変更した後、ansible-galaxyコマンド
を利用して検証用のパスにCollectionsをインストールします。
デバッグ環境を準備する(4/4)
13
#例: ansible.posix collection version 1.1.0を検証する場合
(venv)$ cd $HOME/testing
(venv)$ cat ansible.cfg
[defaults]
host_key_checking=false
collections_paths=/home/hsaito/testing/
(venv)$ ansible-galaxy collection install ansible.posix:==1.1.0
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.ansible.com/download/ansible-posix-1.1.0.tar.gz to
/home/hsaito/.ansible/tmp/ansible-local-874935yx3lua4t/tmpy9eqjh2q/ansible-posix-1.1.0-ks7_q87w
Installing 'ansible.posix:1.1.0' to '/home/hsaito/testing/ansible_collections/ansible/posix'
ansible.posix:1.1.0 was installed successfully
$
Cloud Operator Days Tokyo 2021
Ansibleはシンプルなコマンドラインツールです。Pythonのvirtualenvを利用すれば、本番環境
に影響を与えることなく、比較的容易に検証環境を作成することができます。
1. 必要な情報を適切な範囲とタイミングで収集する
a. 問題を正しく把握するために、情報収集は適切に行いましょう。
b. トラブルシューティングで利用する情報は鮮度が命です。
c. 調査範囲は適宜見直しましょう。
2. コストのかからない専用の検証環境を準備して再現検証を行なう
a. ソースコードベースのAnsible実行環境を準備しましょう。
b. 1.で収集した情報を元にして、同一バージョンで検証しましょう。
c. 本番環境が利用しているサービスもエミュレートできるよう準備しましょう。
専用環境で安全な検証を!
14
CLI/インベントリ/プラグインの調査
Ansibleのトラブルシューティング
15
Cloud Operator Days Tokyo 2021
CLI/インベントリ/プラグインの調査
16
ANSIBLE AUTOMATION ENGINE
CMDB
USERS
INVENTORY
HOSTS
NETWORK
DEVICES
PLUGINS
CLI
MODULES
ANSIBLE
PLAYBOOK
PUBLIC / PRIVATE
CLOUD
PUBLIC / PRIVATE
CLOUD
Cloud Operator Days Tokyo 2021
VERBOSEモードとDEBUGモードは、有効化すると「デバッグメッセージを出力」します。
VERBOSEモードとDEBUGモードのおさらい(1/5)
17
#ファイル名: ansible/lib/ansible/utils/display.py
class Display(with_metaclass(Singleton, object)):
...
def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False, newline=True):
""" Display a message to the user
Note: msg *must* be a unicode string to prevent UnicodeError tracebacks.
"""
...
if not log_only:
...
msg2 = to_bytes(msg2, encoding=self._output_encoding(stderr=stderr))
...
if not stderr:
fileobj = sys.stdout
else:
fileobj = sys.stderr
fileobj.write(msg2)
Cloud Operator Days Tokyo 2021
VERBOSEモードの呼び出し部分は、caplevel(0:-v〜6:-vvvvvvが異なるだけで共通。
VERBOSEモードとDEBUGモードのおさらい(2/5)
18
#ファイル名: ansible/lib/ansible/utils/display.py
class Display(with_metaclass(Singleton, object)):
...
def v(self, msg, host=None):
return self.verbose(msg, host=host, caplevel=0)
def vv(self, msg, host=None):
return self.verbose(msg, host=host, caplevel=1)
def vvv(self, msg, host=None):
return self.verbose(msg, host=host, caplevel=2)
def vvvv(self, msg, host=None):
return self.verbose(msg, host=host, caplevel=3)
def vvvvv(self, msg, host=None):
return self.verbose(msg, host=host, caplevel=4)
def vvvvvv(self, msg, host=None):
return self.verbose(msg, host=host, caplevel=5)
Cloud Operator Days Tokyo 2021
VERBOSEモードの実体は、このようなロジックになっています。
コマンドラインオプションで指定されたキャプチャレベル以下のデバッグメッセージは、全て出力さ
れます。(-vvvであれば -v, -vv, -vvv レベルのメッセージを全て含みます )
VERBOSEモードとDEBUGモードのおさらい(3/5)
19
#ファイル名: ansible/lib/ansible/utils/display.py
class Display(with_metaclass(Singleton, object)):
...
def verbose(self, msg, host=None, caplevel=2):
to_stderr = C.VERBOSE_TO_STDERR
if self.verbosity > caplevel:
if host is None:
self.display(msg, color=C.COLOR_VERBOSE, stderr=to_stderr)
else:
self.display("<%s> %s" % (host, msg), color=C.COLOR_VERBOSE, stderr=to_stderr)
Cloud Operator Days Tokyo 2021
DEBUGモードのロジックは、ANSIBLE_DEBUG=Trueが設定された場合のみ実行されます。
このdebug()以外でも、一部のコードの中で内部の変数値を出力するといった出力処理を実行し
ています。
デフォルトでもデバッグ出力のロジックは呼び出されますが、無視されています。
VERBOSEモードとDEBUGモードのおさらい(4/5)
20
#ファイル名: ansible/lib/ansible/utils/display.py
class Display(with_metaclass(Singleton, object)):
...
def debug(self, msg, host=None):
if C.DEFAULT_DEBUG:
if host is None:
self.display("%6d %0.5f: %s" % (os.getpid(), time.time(), msg), color=C.COLOR_DEBUG)
else:
self.display("%6d %0.5f [%s]: %s" % (os.getpid(), time.time(), host, msg), color=C.COLOR_DEBUG)
Cloud Operator Days Tokyo 2021
以下に、VERBOSEモードとDEBUGモードの基礎知識をまとめます。
● 基本的な振舞いとして出力メッセージが増えます。ほぼそれだけです。
● 一部のプラグイン(sshコネクションプラグインくらい)では、バックグラウンドプロセス
に、より多くの情報を出力させるためのオプションが付加されます。
● VERBOSEモードとDEBUGモードはDisplayクラスを利用してメッセージを出力します。
● VERBOSEモードは、レベルに応じて display.v()~vvvvvv() で指定されたメッセージを出力
します。
● DEBUGモードは display.debug() で指定されたメッセージを出力します。
● 利用者はCLIやプラグインコード内にdisplay.debug()などを記述することで、独自のデ
バッグメッセージを出力できます。
● DIsplayクラスはモジュールからは利用できません。つまりモジュールのデバッグには効果
がありません。
VERBOSEモードとDEBUGモードのおさらい(5/5)
21
Cloud Operator Days Tokyo 2021
実際に、デバッグ用に独自に定義したメッセージを出力してみましょう。
以下の例では、VERBOSEモードでキャプチャレベル:1(-v)が指定された場合に、コントロール
ノードのPYTHONPATHを出力します。
CLIにデバッグ用メッセージを仕込む(1/2)
22
#ファイル名: ansible/lib/ansible/cli/__init__.py
(venv)$ git diff
diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py
index 112d892da4..397838ad6c 100644
--- a/lib/ansible/cli/__init__.py
+++ b/lib/ansible/cli/__init__.py
@@ -86,6 +86,8 @@ class CLI(with_metaclass(ABCMeta, object)):
display.v(u"Using %s as config file" % to_text(C.CONFIG_FILE))
else:
display.v(u"No config file found; using defaults")
+ # Display PYTHONPATH of the control node
+ display.v(u"Using %s as PYTHONPATH" % to_text(os.environ['PYTHONPATH']))
# warn about deprecated config options
for deprecated in C.config.DEPRECATED:
Cloud Operator Days Tokyo 2021
ansibleコマンドや、ansible-playbookコマンドなどのCLIを-vオプション付きで実行すると、
CLIを実行したコントロールノードのPYTHONPATHがメッセージとして出力されます。
CLIにデバッグ用メッセージを仕込む(2/2)
23
(env)$ ansible server00 -i inventory/inventory -m ping -v
Using /home/hsaito/testing/ansible.cfg as config file
Using /home/hsaito/testing/src/ansible/lib as PYTHONPATH
server00 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
Cloud Operator Days Tokyo 2021
現在のAnsibleは、インベントリもプラグイン化されています。
デバッグメッセージを出力させることで、以下のような重複エントリによるhostvarsの上書き
を発見しやすくなります。
プラグインにデバッグ用メッセージを仕込む(1/2)
24
#ファイル名: test_inventory
[linux]
server00 owner=foo
server01 owner=foo
server02 owner=foo
server01 owner=bar # 重複
server03 owner=foo
server04 owner=foo
[windows]
server10 owner=bar
server11 owner=bar
server12 owner=bar
#ファイル名: ansible/lib/ansible/plugins/inventory/__init__.py
(venv)$ git diff -U1
diff --git a/lib/ansible/plugins/inventory/__init__.py
b/lib/ansible/plugins/inventory/__init__.py
index 4ce924f577..1959a39c35 100644
--- a/lib/ansible/plugins/inventory/__init__.py
+++ b/lib/ansible/plugins/inventory/__init__.py
@@ -30,3 +30,3 @@ from ansible.plugins import AnsiblePlugin
from ansible.plugins.cache import CachePluginAdjudicator as CacheObject
-from ansible.module_utils._text import to_bytes, to_native
+from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils.common._collections_compat import Mapping
@@ -211,2 +211,3 @@ class BaseInventoryPlugin(AnsiblePlugin):
self.inventory.set_variable(host, k, variables[k])
+ self.display.v(to_text("host:%s group:%s vars:%s" % (host, group, variables)))
Cloud Operator Days Tokyo 2021
実行結果は以下の通り。server01が重複してlinuxグループに登録され、onwerがbarに上書き
されたことが確認できます。
プラグインにデバッグ用メッセージを仕込む(2/2)
25
#ファイル名: ansible.cfg
[defaults]
host_key_checking=false
collections_paths=/home/hsaito/testing/
stdout_callback=oneline
#ファイル名: example.yml
---
- hosts: all
gather_facts: false
tasks:
- debug:
var: owner
(venv)$ $ ansible-playbook -i inventory/test_inventory playbook/example.yml -v
Using /home/hsaito/testing/ansible.cfg as config file
host:server00 group:linux vars:{'owner': 'foo'}
host:server01 group:linux vars:{'owner': 'foo'} # 1回目 ownerに”foo”が設定された
host:server02 group:linux vars:{'owner': 'foo'}
host:server01 group:linux vars:{'owner': 'bar'} # 2回目 ownerが”bar”で上書きされた
host:server03 group:linux vars:{'owner': 'foo'}
host:server04 group:linux vars:{'owner': 'foo'}
host:server10 group:windows vars:{'owner': 'bar'}
host:server11 group:windows vars:{'owner': 'bar'}
host:server12 group:windows vars:{'owner': 'bar'}
server00 | SUCCESS => { "changed": false, "owner": "foo"}
server01 | SUCCESS => { "changed": false, "owner": "bar"}
server02 | SUCCESS => { "changed": false, "owner": "foo"}
server03 | SUCCESS => { "changed": false, "owner": "foo"}
server04 | SUCCESS => { "changed": false, "owner": "foo"}
server10 | SUCCESS => { "changed": false, "owner": "bar"}
server11 | SUCCESS => { "changed": false, "owner": "bar"}
server12 | SUCCESS => { "changed": false, "owner": "bar"}
Cloud Operator Days Tokyo 2021
VERBOSEモードとDEBUGモードは、仕掛けられたポイントでデバッグに利用できるメッセージ
を出力します。
この機能を、みなさんが遭遇している問題にあわせて、AnsibleのCLIやプラグインに仕込むこ
とで、より効果的に活用することができます。
VERBOSEモードとDEBUGモードの活用
26
モジュールの調査
Ansibleのトラブルシューティング
27
Cloud Operator Days Tokyo 2021
モジュールの調査
28
ANSIBLE AUTOMATION ENGINE
CMDB
USERS
INVENTORY
HOSTS
NETWORK
DEVICES
PLUGINS
CLI
MODULES
ANSIBLE
PLAYBOOK
PUBLIC / PRIVATE
CLOUD
PUBLIC / PRIVATE
CLOUD
Ansibleは、モジュールから生成したPythonプログラムをマネージドノードに転送します。
次に、転送したPythonプログラムを指定されたユーザ権限で実行し、実行完了時にそれを削除
します。
そのため、ユーザは、実際にどのようなPythonプログラムがマネージドノード上で実行された
のかを確認することができません。
Cloud Operator Days Tokyo 2021
ANSIBLE_KEEP_REMOTE_FILES=Trueのおさらい(1/4)
29
ANSIBLE AUTOMATION ENGINE MANAGED NODE
モジュール
実行プログラム
実行プログラム
実行プログラム
[1]転送
[2]実行
[3]削除
環境変数ANSIBLE_KEEP_REMOTE_FILESがTrueにセットされた状態でAnsibleのCLIを実行す
ると、Pythonの実行プログラムを削除するプロセスがスキップされます。
Cloud Operator Days Tokyo 2021
ANSIBLE_KEEP_REMOTE_FILES=Trueのおさらい(2/4)
30
ANSIBLE AUTOMATION ENGINE MANAGED NODE
モジュール
実行プログラム
実行プログラム
[1]転送
[2]実行
$ ANSIBLE_KEEP_REMOTE_FILES=True ansible-playbook -i inventory site.yml
Cloud Operator Days Tokyo 2021
マネージドノードにログインすると、ansible_userとして指定されたユーザの$HOME/.ansible
配下のディレクトリに実行プログラムが配置されているの確認できます。
AnsiballZ_<モジュール名>.py が実行プログラムの実体(※1)です。
この実行プログラムの実行時に出力されるJSON形式のデータ(※2)を、Ansibleはコールバック
プラグイン経由で取得して、Playbookの実行結果として出力します。
ANSIBLE_KEEP_REMOTE_FILES=Trueのおさらい(3/4)
31
#例: statモジュールの実行
$ cd $HOME/.ansible/tmp/
$ tree .
.
└── ansible-tmp-1624940851.0492067-1062358-106611949642545
└── AnsiballZ_stat.py
$ cd ansible-tmp-1624940851.0492067-1062358-106611949642545/
$ ./AnsiballZ_stat.py ※1
{"changed": false, ... , "checksum_algorithm": "sha1"}}} ※2
Cloud Operator Days Tokyo 2021
ANSIBLE_KEEP_REMOTE_FILESを有効化すると、マネージドノード上で実行される操作を実際
に確認することができます。使用上の注意点としては以下の通りです。
● ansible.cfgにkeep_remote_files=trueを設定することで、デフォルトで「残す」設定も可
能だが、掃除の手間を考えるとANSIBLE_KEEP_REMOTE_FILESを必要に応じて環境変数で
設定したほうが無難です。
● Ansibleのモジュールは、単独で動作するものは以外に少ない(例 copyモジュールはstatモ
ジュールを内部利用している)ため、モジュール間の依存関係も知ることができます。
● copyモジュールのように、ファイルを転送してから実行するようなモジュールでは、実際
に転送されたファイルは一時ファイルとして作成され、ANSIBLE_KEEP_REMOTE_FILESが
Trueであっても削除されてしまうので、問題の再現には工夫が必要。
● 最後にデバッグに利用した実行ファイルの削除を忘れずに手動で実施してください。
ANSIBLE_KEEP_REMOTE_FILES=Trueのおさらい(4/4)
32
Cloud Operator Days Tokyo 2021
ANSIBLE_KEEP_REMOTE_FILES=Trueを利用すれば、Ansibleがマネージドノードに対して行
なう操作を、実行プログラムの挙動から確認することができます。
また、この実行プログラムは、展開して内容を改変して実行することもできます。
ANSIBLE_KEEP_REMOTE_FILESを利用したデバッグ(1/3)
33
#例: example.yml
---
- hosts: all
gather_facts: false
tasks:
- stat:
path: /etc/hosts
$ ./AnsiballZ_stat.py explode #実行プログラムをdebug_dirに展開する
Module expanded into:
/home/redhat/.ansible/tmp/ansible-tmp-1624940851.0492067-1062358-106611949642545/debug_dir
$ tree debug_dir
debug_dir/
├── ansible/* # モジュールと依存しているライブラリ群が配置されている
└── args # モジュールのパラメータや実行環境の設定が記載されたJSONファイル
Cloud Operator Days Tokyo 2021
ANSIBLE_KEEP_REMOTE_FILES=Trueを利用すれば、Ansibleがマネージドノードに対して行
なう操作を、実行プログラムの挙動から確認することができます。
また、この実行プログラムは、展開して内容を改変して実行することもできます。
ANSIBLE_KEEP_REMOTE_FILESを利用したデバッグ(2/3)
34
#例: debug_dir/args
#修正前
{
"ANSIBLE_MODULE_ARGS": {
"path": "/etc/hosts",
...
}
#修正後
{
"ANSIBLE_MODULE_ARGS": {
"path": "/home/redhat/.bashrc",
...
}
#例: モジュールパラメータの改変とテスト
$ ./AnsiballZ_stat.py execute | jq
{
"changed": false,
"stat": {
"exists": true,
"path": "/home/redhat/.bashrc",
"mode": "0644",
...
"invocation": {
"module_args": {
"path": "/home/redhat/.bashrc",
...
}
Cloud Operator Days Tokyo 2021
展開したプログラムは、Ansibleのcallback pluginの仕様にあわせる必要がないため、Pythonの
デバッガを利用したり、print()を利用してデバッグメッセージを出力させたりといった、通常
のPythonプログラムをデバッグするための手法を利用できます。
ANSIBLE_KEEP_REMOTE_FILESを利用したデバッグ(3/3)
35
$ diff -U 1 debug_dir/ansible/modules/stat.py.org debug_dir/ansible/modules/stat.py
--- debug_dir/ansible/modules/stat.py.org 2021-06-29 07:06:55.548000000 +0000
+++ debug_dir/ansible/modules/stat.py 2021-06-29 07:11:12.036000000 +0000
@@ -466,2 +466,3 @@
+ import pdb; pdb.set_trace()
# main stat data
$ ./AnsiballZ_stat.py execute
> /home/redhat/.ansible/tmp/ansible-tmp-1624940851.0492067-1062358-106611949642545/debug_dir/ansible/modules/stat.py(456)main()
-> path = module.params.get('path')
(Pdb) p path
'/home/redhat/.bashrc'
(Pdb)
Cloud Operator Days Tokyo 2021
マネージドノードに対して直接ログインできないようなケースでは、モジュールの戻り値の中に
デバッグメッセージを含めるのが、おそらく唯一のリアルタイムデバッグ方法です。
ここでは、Playbookのタスク実行時に[WARNING]としてデバッグメッセージを出力する方法を
紹介します。
warningsパラメータを利用したデバッグ(1/3)
36
#例: uriモジュールが“Name or service not known”で失敗するがマネージドノードにはログインが禁止されている
(venv)$ ansible-playbook -i inventory/inventory playbook/example07.yml
PLAY [all] *********************************************************************************************************************
TASK [uri] *********************************************************************************************************************
fatal: [server00]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": false,
"content": "", "elapsed": 0, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error [Errno -2] Name or service not
known>", "redirected": false, "status": -1, "url": "http://tower38.example.com/api/v2/ping/"}
PLAY RECAP *********************************************************************************************************************
server00 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Cloud Operator Days Tokyo 2021
名前解決の問題ではないことは確実。そこでPlaybook実行時のserver00のproxy設定を確認し
たい。モジュールが返す辞書型の変数(uriモジュールではuresp)にwarningsパラメータを追加し
てデバッグメッセージを設定します。
warningsパラメータを利用したデバッグ(2/3)
37
#ファイル名: ansible/lib/ansible/modules/uri.py b/lib/ansible/modules/uri.py
(venv)$ $ git diff -U1
diff --git a/lib/ansible/modules/uri.py b/lib/ansible/modules/uri.py
index c21c45f213..949130c1e8 100644
--- a/lib/ansible/modules/uri.py
+++ b/lib/ansible/modules/uri.py
@@ -625,2 +625,8 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout, c
def main():
+ env_system_proxy = list()
+ try:
+ env_system_proxy.append('HTTPS_PROXY=%s' % os.environ['HTTPS_PROXY'])
+ env_system_proxy.append('HTTP_PROXY=%s' % os.environ['HTTP_PROXY'])
+ except KeyError:
+ pass
argument_spec = url_argument_spec()
@@ -781,2 +787,3 @@ def main():
uresp['msg'] = 'Status code was %s and not %s: %s' % (resp['status'], status_code, uresp.get('msg', ''))
+ uresp['warnings'] = 'System proxy settings: %s' % env_system_proxy
if return_content:
Cloud Operator Days Tokyo 2021
マネージドノードのProxy設定がWARNINGメッセージとして出力されます。
このように、モジュールの戻り値の辞書に “warnings” パラメータを挿入することで、
Playbookタスク実行時の出力情報にデバッグメッセージを仕込むことができます。
warningsパラメータを利用したデバッグ(3/3)
38
(venv)$ ansible-playbook -i inventory/inventory playbook/exampl.yml
PLAY [all] *********************************************************************************************************************
TASK [uri] *********************************************************************************************************************
[WARNING]: System proxy settings: ['HTTPS_PROXY=http://proxy.example.com:8080', 'HTTP_PROXY=http://proxy.example.com:8080']
fatal: [server00]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": false,
"content": "", "elapsed": 0, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error [Errno -2] Name or service not
known>", "redirected": false, "status": -1, "url": "http://tower38.example.com/api/v2/ping/"}
PLAY RECAP *********************************************************************************************************************
server00
Cloud Operator Days Tokyo 2021
モジュールのデバッグは、非常に手間がかかります。
マネージドノード上での動作を追いかけるには、ANSIBLE_KEEP_REMOTE_FILESを活用して、
実際に実行されているコードをベースにデバッグを進めてください。
Warningメッセージは、マネージドノードにログインしての調査が難しいようなケースで、問題
の箇所を特定するのに有効な機能です。
問題の調査に行き詰まっているようであれば、是非活用してみてください。
ANSIBLE_KEEP_REMOTE_FILESとwarningメッセージの活用
39
まとめ
Ansibleのトラブルシューティング
40
Cloud Operator Days Tokyo 2021
本セッションでは、一般に紹介されている方法では調査しきれないような、Ansibleのトラブル
を調査するための方法をいくつかご紹介しました。
デバッグメッセージを仕込むポイントは、エラーメッセージやトレースバックをヒントにして
ソースコードの中で当たりをつけましょう。
次に、そのポイントに適切なデバッグメッセージを仕込んで原因を調査してみてください。
今回ご紹介した手法が、みなさんがAnsibleの問題を調査する際の助けとなれば幸いです :)
まとめ
41
linkedin.com/company/red-hat
youtube.com/user/RedHatVideos
facebook.com/redhatinc
twitter.com/RedHat
Happy Automation!
ご視聴ありがとうございました :)
42

More Related Content

PDF
[OpenStack Days Korea 2016] Track1 - All flash CEPH 구성 및 최적화
PDF
Amazon RDSを参考にしたとりまチューニング
PDF
バッチ処理にバインド変数はもうやめません? ~|バッチ処理の突発遅延を題材にして考えてみる~
PDF
Open Liberty: オープンソースになったWebSphere Liberty
PDF
ICA および RDP 比較ベンチマークテスト 結果報告書
PDF
Sql server よく聞く設定とその効果
PDF
SQL Server チューニング基礎
PDF
Ansibleで始めるインフラ構築自動化
[OpenStack Days Korea 2016] Track1 - All flash CEPH 구성 및 최적화
Amazon RDSを参考にしたとりまチューニング
バッチ処理にバインド変数はもうやめません? ~|バッチ処理の突発遅延を題材にして考えてみる~
Open Liberty: オープンソースになったWebSphere Liberty
ICA および RDP 比較ベンチマークテスト 結果報告書
Sql server よく聞く設定とその効果
SQL Server チューニング基礎
Ansibleで始めるインフラ構築自動化

What's hot (20)

PDF
[Cloud OnAir] Google Cloud における RDBMS の運用パターン 2020年11月19日 放送
PDF
vSphere 7 へのアップグレードについて
PPTX
Sql server のバックアップとリストアの基礎
PDF
PDF
10分で分かるLinuxブロックレイヤ
PDF
待ち事象から考える、Sql server の改善ポイント
PDF
Sql server 構築 運用 tips
PPTX
Sql server 運用 101
PDF
SQLアンチパターン - ジェイウォーク
PPTX
ここからはじめる SQL Server の状態取得
PDF
さいきんの InnoDB Adaptive Flushing (仮)
PDF
Maven基礎
PPT
インフラエンジニアのためのcassandra入門
PDF
基本に戻ってInnoDBの話をします
PDF
Wireguard 実践入門
PDF
片手間MySQLチューニング戦略
PDF
Azure Functions 2.0 Deep Dive - デベロッパーのための最新開発ガイド
PDF
オープンソースで提供される第二のJVM:OpenJ9 VMとIBM Javaについて
[Cloud OnAir] Google Cloud における RDBMS の運用パターン 2020年11月19日 放送
vSphere 7 へのアップグレードについて
Sql server のバックアップとリストアの基礎
10分で分かるLinuxブロックレイヤ
待ち事象から考える、Sql server の改善ポイント
Sql server 構築 運用 tips
Sql server 運用 101
SQLアンチパターン - ジェイウォーク
ここからはじめる SQL Server の状態取得
さいきんの InnoDB Adaptive Flushing (仮)
Maven基礎
インフラエンジニアのためのcassandra入門
基本に戻ってInnoDBの話をします
Wireguard 実践入門
片手間MySQLチューニング戦略
Azure Functions 2.0 Deep Dive - デベロッパーのための最新開発ガイド
オープンソースで提供される第二のJVM:OpenJ9 VMとIBM Javaについて
Ad

Similar to Ansible troubleshooting 101_2021 (20)

PDF
Ansible troubleshooting 101_202007
PDF
Ansible handson
PDF
Ansible 2.8 アップデート情報 -機能追加と注意点-
PDF
これからはじめるAnsible - Ansible Night Tokyo 2024
PDF
OpenStack & Ansible で実現する自動化
PDF
Ansibleを失敗しながら学ぶ その1
PDF
Ansible 2.0 のサマライズとこれから
PPTX
Ansible ではじめるインフラのコード化入門
PDF
実環境での運用自動化とその管理方法 - OpenStack Days 2017 講演資料
PDF
Ansible Fest 2020 技術トピックまとめ
PDF
Ansible quickstart
PDF
Deep Dive into Modules
PDF
Ansible とネットワーク自動化の概要(SmartCS と Ansible の連携による自動化の可能性を体験!)
PPTX
1day cloud on_your_lab
PDF
ACI + Ansible
PDF
Okinawa Open Days 2015 Handson - Ansible
PDF
Ansible 2.10 と Collection
PDF
入門Ansible
PDF
AlaxalA & hitachi's presentation at Ansible Night in Osaka on 28th Nov. 2018
PDF
Open Stack Day - Ansibleによる環境構築の自動化
Ansible troubleshooting 101_202007
Ansible handson
Ansible 2.8 アップデート情報 -機能追加と注意点-
これからはじめるAnsible - Ansible Night Tokyo 2024
OpenStack & Ansible で実現する自動化
Ansibleを失敗しながら学ぶ その1
Ansible 2.0 のサマライズとこれから
Ansible ではじめるインフラのコード化入門
実環境での運用自動化とその管理方法 - OpenStack Days 2017 講演資料
Ansible Fest 2020 技術トピックまとめ
Ansible quickstart
Deep Dive into Modules
Ansible とネットワーク自動化の概要(SmartCS と Ansible の連携による自動化の可能性を体験!)
1day cloud on_your_lab
ACI + Ansible
Okinawa Open Days 2015 Handson - Ansible
Ansible 2.10 と Collection
入門Ansible
AlaxalA & hitachi's presentation at Ansible Night in Osaka on 28th Nov. 2018
Open Stack Day - Ansibleによる環境構築の自動化
Ad

More from Hideki Saito (20)

PDF
Ansible automationplatform product updates 2021
PDF
Getting Started - Ansible Galaxy NG
PDF
How to contribute code to ansible awx
PDF
Update: Ansible Tower 3.6.0
PDF
OpenStackSDK with Ansible
PDF
How to contribute AWX
PDF
Ansible Tower on OpenShift
PDF
IT Automation with OpenStack and Ansible/AWX
PDF
IT Automation with OpenStack and Ansible/AWX
PDF
Ansible with AWX
PDF
Ansible101
PDF
Ansible handson ood2016
PDF
OpenStack Now!
PDF
OpenStack Osloを使おう - cliff編
PDF
Ansible2とOpenStackの関係
PDF
OpenStack with SR-IOV
PDF
Ansible meetuptokyo 2015 Dynamic Inventory
PDF
OpenStack Summitの歩き方
PDF
OpenStack Summit 2015 Vancouver Report
PDF
Osdt2015 saito
Ansible automationplatform product updates 2021
Getting Started - Ansible Galaxy NG
How to contribute code to ansible awx
Update: Ansible Tower 3.6.0
OpenStackSDK with Ansible
How to contribute AWX
Ansible Tower on OpenShift
IT Automation with OpenStack and Ansible/AWX
IT Automation with OpenStack and Ansible/AWX
Ansible with AWX
Ansible101
Ansible handson ood2016
OpenStack Now!
OpenStack Osloを使おう - cliff編
Ansible2とOpenStackの関係
OpenStack with SR-IOV
Ansible meetuptokyo 2015 Dynamic Inventory
OpenStack Summitの歩き方
OpenStack Summit 2015 Vancouver Report
Osdt2015 saito

Ansible troubleshooting 101_2021

  • 1. Cloud Operator Days Tokyo 2021 Ansibleのトラブルシューティング 2021 ~トラブルシュートに役立つテクニック ~ 齊藤 秀喜(@saito_hideki) シニアソフトウェアメンテナンスエンジニア(Ansible Automation Platform) レッドハット株式会社
  • 2. 自己紹介 氏名: 齊藤 秀喜(Twitter: @saito_hideki) 所属: カスタマーエクスペリエンス&エンゲージメント/レッドハット株式会社 仕事: シニアソフトウェアメンテナンスエンジニア(Ansible Automation Platform) 趣味: Ansibleのトラブルシュート(最近ちょっと飽きてきた) 本セッションは、 Cloud Operator Days 2020 のトラブル シューティングセッションの続編です。 2020年版はコチラから -> https://bit.ly/2SNZhHz 2 Cloud Operator Days Tokyo 2021
  • 3. Cloud Operator Days Tokyo 2021 Cloud Operator Days 2020年の同セッションの続編として、今回は、Ansibleが標準で提供す るさまざまなデバッグ機能にフォーカスします。 CLI、インベントリ、モジュール、プラグインといった、各コンポーネントの問題を調査するた めに役立つAnsibleのデバッグ機能の仕組みと、その使い所をご紹介します。 本セッションの手法を実施するにあたっては、Pythonのコードリーディング技術が必要となり ますが、それほど高度なリーディングは必要ありませんので絶望せずにお付き合いください。 ❖ アーキテクチャとコンポーネント(ふりかえり) ❖ トラブルシューティングの準備 ❖ CLI/インベントリ/プラグインの調査 ❖ モジュールの調査 注)Playbookの「記述ミス」や「書き方」の問題で想定通りに動作しないようなケースの調査方法については、 2020年のセッションで紹介していますので、そちらをご覧ください。 本セッションでお話すること 3
  • 5. Cloud Operator Days Tokyo 2021 Ansibleのアーキテクチャとコンポーネント 5 ANSIBLE AUTOMATION ENGINE CMDB USERS INVENTORY HOSTS NETWORK DEVICES PLUGINS CLI MODULES ANSIBLE PLAYBOOK PUBLIC / PRIVATE CLOUD PUBLIC / PRIVATE CLOUD
  • 6. Cloud Operator Days Tokyo 2021 Ansibleを構成するコンポーネントとデバッグ手法 6 # コンポーネント 役割 調査に利用するデバッグ機能 [1] CLI ansible-playbookなどのコマンドラインツール群。 * ANSIBLE_DEBUG=True * --verbose [2] INVENTORY インベントリファイル自体やローダー。 * ANSIBLE_DEBUG=True * --verbose [3] PLUGIN フィルタやコールバックなどのプラグインプログラム群。 最近のバージョンではダイナミックインベントリもプラグイン化 されている。 * ANSIBLE_DEBUG=True * --verbose [4] MODULE Playbookからタスクとして実行するプログラム群。 * ANSIBLE_KEEP_REMOTE_FILES=True [5] PLAYBOOK 自動化するオペレーションを記述した定義ファイル群。 * debugモジュール, register機能 * --syntax-check, --list-tasks, --list-tags
  • 8. Cloud Operator Days Tokyo 2021 問題の調査に着手するにあたって、まずは「システム環境」を可能な限り正しく把握する必要が あります。 まずは、以下の必須情報を確認しましょう。 ❏ コントロールノードの情報 ❏ OS情報 ❏ Pythonインタプリタのバージョン ❏ Ansibleのバージョン ❏ Collectionsのバージョン ❏ HWあるいはVMのスペック ❏ マネージドノード ❏ マネージドノードの種類(ベアメタルサーバ、ネットワークデバイスなど) ❏ OS情報 ❏ HWあるいはVMのスペック ❏ Pythonインタプリタのバージョン(ベアメタルサーバやVMインスタンスの場合) 基礎知識 (1/2) 8
  • 9. Cloud Operator Days Tokyo 2021 問題発生当時点の鮮度の高い情報も収集しておきます。 ❏ コントロールノードの環境情報 ❏ OSログファイル(RHEL系であればsosreportで一気に収集してしまう手もあり) ❏ Ansibleの実行ログ(ansible.cfgでログ出力設定 - 2020年のセッション参照) ❏ pip等でインストールしたPythonモジュールのバージョンとリスト ❏ マネージドノードの環境情報 ❏ OSログファイル ❏ pip等でインストールしたPythonモジュールのバージョンとリスト ❏ 直接タスク実行プロセスにstraceコマンドでアタッチして状況を確認 ❏ ネットワークの情報 ❏ コントロールノードとマネージドノードの間にFirewall、ロードバランサ、Proxyな どが存在していないか? ❏ DNS、LDAP、SAML、NFS等のネットワークサービスを利用していないか? 基礎知識 (2/2) 9
  • 10. Cloud Operator Days Tokyo 2021 以降では、Ansibleのデバッグを行なうにあたって、Ansibleのソースコードと、ここで作成する 仮想環境を利用して、デバッグメッセージを仕込みつつ検証を行います。 はじめに、アップストリームのソースコードをgit cloneしてデバッグ環境を準備します。 デバッグ環境を準備する(1/4) 10 #例: 問題の発生している環境がAnsible 2.11.1である場合 $ mkdir -p $HOME/testing/src/ $ cd $HOME/testing/src/ $ git clone https://github.com/ansible/ansible.git $ cd ansible $ git checkout -b v2.11.1 refs/tags/v2.11.1 $ git log -n 1 commit f468ec7087d57b21acf2a0545075192a9cceacb5 (HEAD -> v2.11.1, tag: v2.11.1) Author: Rick Elrod <rick@elrod.me> Date: Mon May 24 14:50:49 2021 -0500 New release v2.11.1
  • 11. Cloud Operator Days Tokyo 2021 続いて、virtualenvを利用して検証用の仮想環境を作成します。 デバッグ環境を準備する(2/4) 11 $ git status On branch v2.11.1 nothing to commit, working tree clean $ python3 -m venv venv $ source venv/bin/activate (venv)$ pip install -r requirements.txt (venv)$ source hacking/env-setup running egg_info ...中略... PYTHONPATH=/home/hsaito/testing/src/ansible/lib MANPATH=/home/hsaito/testing/src/ansible/docs/man:/usr/local/share/man:/usr/share/man Remember, you may wish to specify your host file with -i Done! $
  • 12. Cloud Operator Days Tokyo 2021 仮想環境の設定が完了すると、AnsibleのソースコードをベースとしたAnsible CLIが利用できる ようになります。 デバッグ環境を準備する(3/4) 12 $ ansible --version ansible [core 2.11.1] (v2.11.1 f468ec7087) last updated 2021/06/29 22:18:01 (GMT +900) config file = /etc/ansible/ansible.cfg configured module search path = ['/home/hsaito/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/hsaito/testing/src/ansible/lib/ansible ansible collection location = /home/hsaito/.ansible/collections:/usr/share/ansible/collections executable location = /home/hsaito/testing/src/ansible/bin/ansible python version = 3.9.5 (default, May 14 2021, 00:00:00) [GCC 11.1.1 20210428 (Red Hat 11.1.1-1)] jinja version = 3.0.1 libyaml = True $
  • 13. Cloud Operator Days Tokyo 2021 Collectionsを利用している場合は、ansible.cfgの設定を変更した後、ansible-galaxyコマンド を利用して検証用のパスにCollectionsをインストールします。 デバッグ環境を準備する(4/4) 13 #例: ansible.posix collection version 1.1.0を検証する場合 (venv)$ cd $HOME/testing (venv)$ cat ansible.cfg [defaults] host_key_checking=false collections_paths=/home/hsaito/testing/ (venv)$ ansible-galaxy collection install ansible.posix:==1.1.0 Starting galaxy collection install process Process install dependency map Starting collection install process Downloading https://galaxy.ansible.com/download/ansible-posix-1.1.0.tar.gz to /home/hsaito/.ansible/tmp/ansible-local-874935yx3lua4t/tmpy9eqjh2q/ansible-posix-1.1.0-ks7_q87w Installing 'ansible.posix:1.1.0' to '/home/hsaito/testing/ansible_collections/ansible/posix' ansible.posix:1.1.0 was installed successfully $
  • 14. Cloud Operator Days Tokyo 2021 Ansibleはシンプルなコマンドラインツールです。Pythonのvirtualenvを利用すれば、本番環境 に影響を与えることなく、比較的容易に検証環境を作成することができます。 1. 必要な情報を適切な範囲とタイミングで収集する a. 問題を正しく把握するために、情報収集は適切に行いましょう。 b. トラブルシューティングで利用する情報は鮮度が命です。 c. 調査範囲は適宜見直しましょう。 2. コストのかからない専用の検証環境を準備して再現検証を行なう a. ソースコードベースのAnsible実行環境を準備しましょう。 b. 1.で収集した情報を元にして、同一バージョンで検証しましょう。 c. 本番環境が利用しているサービスもエミュレートできるよう準備しましょう。 専用環境で安全な検証を! 14
  • 16. Cloud Operator Days Tokyo 2021 CLI/インベントリ/プラグインの調査 16 ANSIBLE AUTOMATION ENGINE CMDB USERS INVENTORY HOSTS NETWORK DEVICES PLUGINS CLI MODULES ANSIBLE PLAYBOOK PUBLIC / PRIVATE CLOUD PUBLIC / PRIVATE CLOUD
  • 17. Cloud Operator Days Tokyo 2021 VERBOSEモードとDEBUGモードは、有効化すると「デバッグメッセージを出力」します。 VERBOSEモードとDEBUGモードのおさらい(1/5) 17 #ファイル名: ansible/lib/ansible/utils/display.py class Display(with_metaclass(Singleton, object)): ... def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False, newline=True): """ Display a message to the user Note: msg *must* be a unicode string to prevent UnicodeError tracebacks. """ ... if not log_only: ... msg2 = to_bytes(msg2, encoding=self._output_encoding(stderr=stderr)) ... if not stderr: fileobj = sys.stdout else: fileobj = sys.stderr fileobj.write(msg2)
  • 18. Cloud Operator Days Tokyo 2021 VERBOSEモードの呼び出し部分は、caplevel(0:-v〜6:-vvvvvvが異なるだけで共通。 VERBOSEモードとDEBUGモードのおさらい(2/5) 18 #ファイル名: ansible/lib/ansible/utils/display.py class Display(with_metaclass(Singleton, object)): ... def v(self, msg, host=None): return self.verbose(msg, host=host, caplevel=0) def vv(self, msg, host=None): return self.verbose(msg, host=host, caplevel=1) def vvv(self, msg, host=None): return self.verbose(msg, host=host, caplevel=2) def vvvv(self, msg, host=None): return self.verbose(msg, host=host, caplevel=3) def vvvvv(self, msg, host=None): return self.verbose(msg, host=host, caplevel=4) def vvvvvv(self, msg, host=None): return self.verbose(msg, host=host, caplevel=5)
  • 19. Cloud Operator Days Tokyo 2021 VERBOSEモードの実体は、このようなロジックになっています。 コマンドラインオプションで指定されたキャプチャレベル以下のデバッグメッセージは、全て出力さ れます。(-vvvであれば -v, -vv, -vvv レベルのメッセージを全て含みます ) VERBOSEモードとDEBUGモードのおさらい(3/5) 19 #ファイル名: ansible/lib/ansible/utils/display.py class Display(with_metaclass(Singleton, object)): ... def verbose(self, msg, host=None, caplevel=2): to_stderr = C.VERBOSE_TO_STDERR if self.verbosity > caplevel: if host is None: self.display(msg, color=C.COLOR_VERBOSE, stderr=to_stderr) else: self.display("<%s> %s" % (host, msg), color=C.COLOR_VERBOSE, stderr=to_stderr)
  • 20. Cloud Operator Days Tokyo 2021 DEBUGモードのロジックは、ANSIBLE_DEBUG=Trueが設定された場合のみ実行されます。 このdebug()以外でも、一部のコードの中で内部の変数値を出力するといった出力処理を実行し ています。 デフォルトでもデバッグ出力のロジックは呼び出されますが、無視されています。 VERBOSEモードとDEBUGモードのおさらい(4/5) 20 #ファイル名: ansible/lib/ansible/utils/display.py class Display(with_metaclass(Singleton, object)): ... def debug(self, msg, host=None): if C.DEFAULT_DEBUG: if host is None: self.display("%6d %0.5f: %s" % (os.getpid(), time.time(), msg), color=C.COLOR_DEBUG) else: self.display("%6d %0.5f [%s]: %s" % (os.getpid(), time.time(), host, msg), color=C.COLOR_DEBUG)
  • 21. Cloud Operator Days Tokyo 2021 以下に、VERBOSEモードとDEBUGモードの基礎知識をまとめます。 ● 基本的な振舞いとして出力メッセージが増えます。ほぼそれだけです。 ● 一部のプラグイン(sshコネクションプラグインくらい)では、バックグラウンドプロセス に、より多くの情報を出力させるためのオプションが付加されます。 ● VERBOSEモードとDEBUGモードはDisplayクラスを利用してメッセージを出力します。 ● VERBOSEモードは、レベルに応じて display.v()~vvvvvv() で指定されたメッセージを出力 します。 ● DEBUGモードは display.debug() で指定されたメッセージを出力します。 ● 利用者はCLIやプラグインコード内にdisplay.debug()などを記述することで、独自のデ バッグメッセージを出力できます。 ● DIsplayクラスはモジュールからは利用できません。つまりモジュールのデバッグには効果 がありません。 VERBOSEモードとDEBUGモードのおさらい(5/5) 21
  • 22. Cloud Operator Days Tokyo 2021 実際に、デバッグ用に独自に定義したメッセージを出力してみましょう。 以下の例では、VERBOSEモードでキャプチャレベル:1(-v)が指定された場合に、コントロール ノードのPYTHONPATHを出力します。 CLIにデバッグ用メッセージを仕込む(1/2) 22 #ファイル名: ansible/lib/ansible/cli/__init__.py (venv)$ git diff diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py index 112d892da4..397838ad6c 100644 --- a/lib/ansible/cli/__init__.py +++ b/lib/ansible/cli/__init__.py @@ -86,6 +86,8 @@ class CLI(with_metaclass(ABCMeta, object)): display.v(u"Using %s as config file" % to_text(C.CONFIG_FILE)) else: display.v(u"No config file found; using defaults") + # Display PYTHONPATH of the control node + display.v(u"Using %s as PYTHONPATH" % to_text(os.environ['PYTHONPATH'])) # warn about deprecated config options for deprecated in C.config.DEPRECATED:
  • 23. Cloud Operator Days Tokyo 2021 ansibleコマンドや、ansible-playbookコマンドなどのCLIを-vオプション付きで実行すると、 CLIを実行したコントロールノードのPYTHONPATHがメッセージとして出力されます。 CLIにデバッグ用メッセージを仕込む(2/2) 23 (env)$ ansible server00 -i inventory/inventory -m ping -v Using /home/hsaito/testing/ansible.cfg as config file Using /home/hsaito/testing/src/ansible/lib as PYTHONPATH server00 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "ping": "pong" }
  • 24. Cloud Operator Days Tokyo 2021 現在のAnsibleは、インベントリもプラグイン化されています。 デバッグメッセージを出力させることで、以下のような重複エントリによるhostvarsの上書き を発見しやすくなります。 プラグインにデバッグ用メッセージを仕込む(1/2) 24 #ファイル名: test_inventory [linux] server00 owner=foo server01 owner=foo server02 owner=foo server01 owner=bar # 重複 server03 owner=foo server04 owner=foo [windows] server10 owner=bar server11 owner=bar server12 owner=bar #ファイル名: ansible/lib/ansible/plugins/inventory/__init__.py (venv)$ git diff -U1 diff --git a/lib/ansible/plugins/inventory/__init__.py b/lib/ansible/plugins/inventory/__init__.py index 4ce924f577..1959a39c35 100644 --- a/lib/ansible/plugins/inventory/__init__.py +++ b/lib/ansible/plugins/inventory/__init__.py @@ -30,3 +30,3 @@ from ansible.plugins import AnsiblePlugin from ansible.plugins.cache import CachePluginAdjudicator as CacheObject -from ansible.module_utils._text import to_bytes, to_native +from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.module_utils.common._collections_compat import Mapping @@ -211,2 +211,3 @@ class BaseInventoryPlugin(AnsiblePlugin): self.inventory.set_variable(host, k, variables[k]) + self.display.v(to_text("host:%s group:%s vars:%s" % (host, group, variables)))
  • 25. Cloud Operator Days Tokyo 2021 実行結果は以下の通り。server01が重複してlinuxグループに登録され、onwerがbarに上書き されたことが確認できます。 プラグインにデバッグ用メッセージを仕込む(2/2) 25 #ファイル名: ansible.cfg [defaults] host_key_checking=false collections_paths=/home/hsaito/testing/ stdout_callback=oneline #ファイル名: example.yml --- - hosts: all gather_facts: false tasks: - debug: var: owner (venv)$ $ ansible-playbook -i inventory/test_inventory playbook/example.yml -v Using /home/hsaito/testing/ansible.cfg as config file host:server00 group:linux vars:{'owner': 'foo'} host:server01 group:linux vars:{'owner': 'foo'} # 1回目 ownerに”foo”が設定された host:server02 group:linux vars:{'owner': 'foo'} host:server01 group:linux vars:{'owner': 'bar'} # 2回目 ownerが”bar”で上書きされた host:server03 group:linux vars:{'owner': 'foo'} host:server04 group:linux vars:{'owner': 'foo'} host:server10 group:windows vars:{'owner': 'bar'} host:server11 group:windows vars:{'owner': 'bar'} host:server12 group:windows vars:{'owner': 'bar'} server00 | SUCCESS => { "changed": false, "owner": "foo"} server01 | SUCCESS => { "changed": false, "owner": "bar"} server02 | SUCCESS => { "changed": false, "owner": "foo"} server03 | SUCCESS => { "changed": false, "owner": "foo"} server04 | SUCCESS => { "changed": false, "owner": "foo"} server10 | SUCCESS => { "changed": false, "owner": "bar"} server11 | SUCCESS => { "changed": false, "owner": "bar"} server12 | SUCCESS => { "changed": false, "owner": "bar"}
  • 26. Cloud Operator Days Tokyo 2021 VERBOSEモードとDEBUGモードは、仕掛けられたポイントでデバッグに利用できるメッセージ を出力します。 この機能を、みなさんが遭遇している問題にあわせて、AnsibleのCLIやプラグインに仕込むこ とで、より効果的に活用することができます。 VERBOSEモードとDEBUGモードの活用 26
  • 28. Cloud Operator Days Tokyo 2021 モジュールの調査 28 ANSIBLE AUTOMATION ENGINE CMDB USERS INVENTORY HOSTS NETWORK DEVICES PLUGINS CLI MODULES ANSIBLE PLAYBOOK PUBLIC / PRIVATE CLOUD PUBLIC / PRIVATE CLOUD
  • 30. 環境変数ANSIBLE_KEEP_REMOTE_FILESがTrueにセットされた状態でAnsibleのCLIを実行す ると、Pythonの実行プログラムを削除するプロセスがスキップされます。 Cloud Operator Days Tokyo 2021 ANSIBLE_KEEP_REMOTE_FILES=Trueのおさらい(2/4) 30 ANSIBLE AUTOMATION ENGINE MANAGED NODE モジュール 実行プログラム 実行プログラム [1]転送 [2]実行 $ ANSIBLE_KEEP_REMOTE_FILES=True ansible-playbook -i inventory site.yml
  • 31. Cloud Operator Days Tokyo 2021 マネージドノードにログインすると、ansible_userとして指定されたユーザの$HOME/.ansible 配下のディレクトリに実行プログラムが配置されているの確認できます。 AnsiballZ_<モジュール名>.py が実行プログラムの実体(※1)です。 この実行プログラムの実行時に出力されるJSON形式のデータ(※2)を、Ansibleはコールバック プラグイン経由で取得して、Playbookの実行結果として出力します。 ANSIBLE_KEEP_REMOTE_FILES=Trueのおさらい(3/4) 31 #例: statモジュールの実行 $ cd $HOME/.ansible/tmp/ $ tree . . └── ansible-tmp-1624940851.0492067-1062358-106611949642545 └── AnsiballZ_stat.py $ cd ansible-tmp-1624940851.0492067-1062358-106611949642545/ $ ./AnsiballZ_stat.py ※1 {"changed": false, ... , "checksum_algorithm": "sha1"}}} ※2
  • 32. Cloud Operator Days Tokyo 2021 ANSIBLE_KEEP_REMOTE_FILESを有効化すると、マネージドノード上で実行される操作を実際 に確認することができます。使用上の注意点としては以下の通りです。 ● ansible.cfgにkeep_remote_files=trueを設定することで、デフォルトで「残す」設定も可 能だが、掃除の手間を考えるとANSIBLE_KEEP_REMOTE_FILESを必要に応じて環境変数で 設定したほうが無難です。 ● Ansibleのモジュールは、単独で動作するものは以外に少ない(例 copyモジュールはstatモ ジュールを内部利用している)ため、モジュール間の依存関係も知ることができます。 ● copyモジュールのように、ファイルを転送してから実行するようなモジュールでは、実際 に転送されたファイルは一時ファイルとして作成され、ANSIBLE_KEEP_REMOTE_FILESが Trueであっても削除されてしまうので、問題の再現には工夫が必要。 ● 最後にデバッグに利用した実行ファイルの削除を忘れずに手動で実施してください。 ANSIBLE_KEEP_REMOTE_FILES=Trueのおさらい(4/4) 32
  • 33. Cloud Operator Days Tokyo 2021 ANSIBLE_KEEP_REMOTE_FILES=Trueを利用すれば、Ansibleがマネージドノードに対して行 なう操作を、実行プログラムの挙動から確認することができます。 また、この実行プログラムは、展開して内容を改変して実行することもできます。 ANSIBLE_KEEP_REMOTE_FILESを利用したデバッグ(1/3) 33 #例: example.yml --- - hosts: all gather_facts: false tasks: - stat: path: /etc/hosts $ ./AnsiballZ_stat.py explode #実行プログラムをdebug_dirに展開する Module expanded into: /home/redhat/.ansible/tmp/ansible-tmp-1624940851.0492067-1062358-106611949642545/debug_dir $ tree debug_dir debug_dir/ ├── ansible/* # モジュールと依存しているライブラリ群が配置されている └── args # モジュールのパラメータや実行環境の設定が記載されたJSONファイル
  • 34. Cloud Operator Days Tokyo 2021 ANSIBLE_KEEP_REMOTE_FILES=Trueを利用すれば、Ansibleがマネージドノードに対して行 なう操作を、実行プログラムの挙動から確認することができます。 また、この実行プログラムは、展開して内容を改変して実行することもできます。 ANSIBLE_KEEP_REMOTE_FILESを利用したデバッグ(2/3) 34 #例: debug_dir/args #修正前 { "ANSIBLE_MODULE_ARGS": { "path": "/etc/hosts", ... } #修正後 { "ANSIBLE_MODULE_ARGS": { "path": "/home/redhat/.bashrc", ... } #例: モジュールパラメータの改変とテスト $ ./AnsiballZ_stat.py execute | jq { "changed": false, "stat": { "exists": true, "path": "/home/redhat/.bashrc", "mode": "0644", ... "invocation": { "module_args": { "path": "/home/redhat/.bashrc", ... }
  • 35. Cloud Operator Days Tokyo 2021 展開したプログラムは、Ansibleのcallback pluginの仕様にあわせる必要がないため、Pythonの デバッガを利用したり、print()を利用してデバッグメッセージを出力させたりといった、通常 のPythonプログラムをデバッグするための手法を利用できます。 ANSIBLE_KEEP_REMOTE_FILESを利用したデバッグ(3/3) 35 $ diff -U 1 debug_dir/ansible/modules/stat.py.org debug_dir/ansible/modules/stat.py --- debug_dir/ansible/modules/stat.py.org 2021-06-29 07:06:55.548000000 +0000 +++ debug_dir/ansible/modules/stat.py 2021-06-29 07:11:12.036000000 +0000 @@ -466,2 +466,3 @@ + import pdb; pdb.set_trace() # main stat data $ ./AnsiballZ_stat.py execute > /home/redhat/.ansible/tmp/ansible-tmp-1624940851.0492067-1062358-106611949642545/debug_dir/ansible/modules/stat.py(456)main() -> path = module.params.get('path') (Pdb) p path '/home/redhat/.bashrc' (Pdb)
  • 36. Cloud Operator Days Tokyo 2021 マネージドノードに対して直接ログインできないようなケースでは、モジュールの戻り値の中に デバッグメッセージを含めるのが、おそらく唯一のリアルタイムデバッグ方法です。 ここでは、Playbookのタスク実行時に[WARNING]としてデバッグメッセージを出力する方法を 紹介します。 warningsパラメータを利用したデバッグ(1/3) 36 #例: uriモジュールが“Name or service not known”で失敗するがマネージドノードにはログインが禁止されている (venv)$ ansible-playbook -i inventory/inventory playbook/example07.yml PLAY [all] ********************************************************************************************************************* TASK [uri] ********************************************************************************************************************* fatal: [server00]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": false, "content": "", "elapsed": 0, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error [Errno -2] Name or service not known>", "redirected": false, "status": -1, "url": "http://tower38.example.com/api/v2/ping/"} PLAY RECAP ********************************************************************************************************************* server00 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
  • 37. Cloud Operator Days Tokyo 2021 名前解決の問題ではないことは確実。そこでPlaybook実行時のserver00のproxy設定を確認し たい。モジュールが返す辞書型の変数(uriモジュールではuresp)にwarningsパラメータを追加し てデバッグメッセージを設定します。 warningsパラメータを利用したデバッグ(2/3) 37 #ファイル名: ansible/lib/ansible/modules/uri.py b/lib/ansible/modules/uri.py (venv)$ $ git diff -U1 diff --git a/lib/ansible/modules/uri.py b/lib/ansible/modules/uri.py index c21c45f213..949130c1e8 100644 --- a/lib/ansible/modules/uri.py +++ b/lib/ansible/modules/uri.py @@ -625,2 +625,8 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout, c def main(): + env_system_proxy = list() + try: + env_system_proxy.append('HTTPS_PROXY=%s' % os.environ['HTTPS_PROXY']) + env_system_proxy.append('HTTP_PROXY=%s' % os.environ['HTTP_PROXY']) + except KeyError: + pass argument_spec = url_argument_spec() @@ -781,2 +787,3 @@ def main(): uresp['msg'] = 'Status code was %s and not %s: %s' % (resp['status'], status_code, uresp.get('msg', '')) + uresp['warnings'] = 'System proxy settings: %s' % env_system_proxy if return_content:
  • 38. Cloud Operator Days Tokyo 2021 マネージドノードのProxy設定がWARNINGメッセージとして出力されます。 このように、モジュールの戻り値の辞書に “warnings” パラメータを挿入することで、 Playbookタスク実行時の出力情報にデバッグメッセージを仕込むことができます。 warningsパラメータを利用したデバッグ(3/3) 38 (venv)$ ansible-playbook -i inventory/inventory playbook/exampl.yml PLAY [all] ********************************************************************************************************************* TASK [uri] ********************************************************************************************************************* [WARNING]: System proxy settings: ['HTTPS_PROXY=http://proxy.example.com:8080', 'HTTP_PROXY=http://proxy.example.com:8080'] fatal: [server00]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": false, "content": "", "elapsed": 0, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error [Errno -2] Name or service not known>", "redirected": false, "status": -1, "url": "http://tower38.example.com/api/v2/ping/"} PLAY RECAP ********************************************************************************************************************* server00
  • 39. Cloud Operator Days Tokyo 2021 モジュールのデバッグは、非常に手間がかかります。 マネージドノード上での動作を追いかけるには、ANSIBLE_KEEP_REMOTE_FILESを活用して、 実際に実行されているコードをベースにデバッグを進めてください。 Warningメッセージは、マネージドノードにログインしての調査が難しいようなケースで、問題 の箇所を特定するのに有効な機能です。 問題の調査に行き詰まっているようであれば、是非活用してみてください。 ANSIBLE_KEEP_REMOTE_FILESとwarningメッセージの活用 39
  • 41. Cloud Operator Days Tokyo 2021 本セッションでは、一般に紹介されている方法では調査しきれないような、Ansibleのトラブル を調査するための方法をいくつかご紹介しました。 デバッグメッセージを仕込むポイントは、エラーメッセージやトレースバックをヒントにして ソースコードの中で当たりをつけましょう。 次に、そのポイントに適切なデバッグメッセージを仕込んで原因を調査してみてください。 今回ご紹介した手法が、みなさんがAnsibleの問題を調査する際の助けとなれば幸いです :) まとめ 41