Ansibleの実行を高速化する方法|ansible.cfgのpipelining・forks・fact cachingチューニング

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > Ansibleの実行を高速化する方法|ansible.cfgのpipelining・forks・fact cachingチューニング
「playbookを実行したら完了まで5分以上かかった。」「管理対象のサーバーが増えるたびに実行時間が比例して伸びている。」

Ansibleのデフォルト設定は「まず動かすこと」を重視した設計になっており、速度の最適化は考慮されていません。5台のサーバーでは許容範囲だった実行時間も、50台・100台と増えると深刻なボトルネックになります。

この記事では、ansible 高速化のカギとなるansible.cfgの3つの設定——forks(並列数)・pipelining(SSHオーバーヘッド削減)・fact caching(Fact収集のキャッシュ化)——を、仕組みから設定手順まで体系的に解説します。「ansible 高速化 ansible.cfg」の設定値で悩んでいる中級者・大規模インフラ管理者の方に向け、現場で効果が確認できた設定を整理しました。

この記事のポイント

・ansible.cfgのforks・pipelining・fact cachingの3設定でAnsibleは劇的に速くなる
・pipeliningはSSH接続のオーバーヘッドを1タスクあたり最大2/3削減できる
・fact cachingはgathering=smartと組み合わせてFact収集を初回のみに絞る
・pipelining有効化時はターゲットホストのrequiretty無効化が必須


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

なぜAnsibleの実行は遅くなるのか——3つのボトルネックを理解する

ansible 高速化を進める前に、「なぜ遅いのか」の構造を理解しておく必要があります。チューニングの効果を正しく評価するためにも、ボトルネックの在り処を把握してから設定変更に入ってください。主なボトルネックは3つです。

1. タスクのたびに発生するSSH接続のオーバーヘッド

AnsibleはデフォルトでタスクごとにSSHセッションを開き、Pythonスクリプトをターゲットホストに転送してから実行します。この「接続→転送→実行→後片付け」というサイクルがタスクごとに繰り返されるため、タスク数が多いPlaybookほどSSHオーバーヘッドが積み重なります。

これを解消するのがpipeliningです。pipeliningを有効にすると、スクリプトの転送ステップを省略し、SSH接続のstdinを通じて直接スクリプトを送り込むようになります。1タスクあたりのSSH接続数が大幅に減り、実行時間の短縮につながります。

2. デフォルトのforks=5による直列に近い実行

Ansibleのデフォルトはforks=5です。これは「最大5台のサーバーに対して同時にタスクを実行する」という設定で、残りのサーバーは順番待ちになります。50台のサーバーなら10バッチに分かれて処理されるため、実行時間は1台の場合の約10倍に近づきます。

これを解消するのがforksの引き上げです。コントロールノードのCPU・メモリ・ネットワーク帯域に余裕がある限り、同時実行数を増やすほど実行時間は短縮されます。

3. Playbookのたびに繰り返されるFact収集

Ansibleはデフォルトで、Playbookの実行開始時にすべての対象ホストからFact(OS情報・IPアドレス・メモリ量等)を収集します。この収集処理は管理台数に比例して時間がかかり、50台では数十秒から数分を消費することがあります。

Factの内容はそう頻繁には変わりません。これを解消するのがfact cachingで、一度収集したFactをローカルに保存して使い回す仕組みです。

ansible.cfgのチューニング設定——forks・pipelining・fact cachingの仕組みと設計方針

3つのボトルネックに対応する設定の仕組みと設計判断を解説します。ansible 高速化の本質は「無駄な待ちをなくすこと」です。

1. forks——並列実行数の上限を引き上げる

ansible 高速化の中で最も即効性が高いのがforksの調整です。設定値はコントロールノードのスペックと管理台数を見て決めます。

設定値の目安:
・コントロールノードが4コア・8GB RAMなら forks = 20 前後から始める
・管理台数が50台未満なら forks = 20 程度で十分
・管理台数が200台以上あるなら forks = 50 ~ 100 も検討する
・あまり大きくしすぎるとコントロールノードのCPU・メモリを使い切り逆効果になる

forksの効果は管理台数に比例します。5台なら大差ありませんが、50台では大きな差が出ます。チューニング後は必ずコントロールノードのCPU・メモリ使用率を確認してください。

2. pipelining——SSH接続数をタスクごとに削減する

pipeliningの仕組みを理解するために、デフォルト時とpipelining有効時の動作を比較します。

デフォルト(pipelining=False)の動作:
・SSH接続を開く
・Pythonスクリプトをターゲットホストのtmpディレクトリに書き込む
・別のSSH接続でそのスクリプトを実行する
・後片付け(tmpファイルの削除)のSSH接続を開く

pipelining=Trueの動作:
・SSH接続を1つ開く
・スクリプトをstdinで直接送り込んで実行する

1タスクあたりのSSH接続数が大幅に削減されるため、タスク数が多いPlaybookほど効果が大きくなります。20タスクのPlaybookを50台に適用するケースでは、pipeliningだけで実行時間が半分以下になることも珍しくありません。

3. fact caching——Fact収集の結果をキャッシュして使い回す

fact cachingは、gatheringの設定と組み合わせて機能します。ansible.cfgのgatheringパラメータには3つのモードがあります。

gatheringの3つのモード:
implicit(デフォルト): Playbookを実行するたびに毎回Factを収集する
smart: キャッシュがあればFact収集をスキップ、なければ収集してキャッシュに保存する
explicit: gather_factsを明示的に記述しない限り収集しない

fact cachingを有効にする際は gathering = smart が最も扱いやすいモードです。初回は通常どおり収集してキャッシュに保存し、次回以降はキャッシュが有効期限内であれば収集をスキップします。

キャッシュの保存先(fact_caching)には以下の選択肢があります。

jsonfile: ローカルディレクトリにJSONファイルとして保存。導入が最も簡単
yaml: YAMLファイルとして保存。内容が人の目で確認しやすい
redis: Redisに保存。複数のコントロールノードでFactを共有したい場合に有効
memcached: Memcachedに保存。Redisなしで手軽にInMemoryキャッシュを使う選択肢

単一のコントロールノードで運用している小規模環境ならjsonfileで十分です。

ansible.cfgへの設定追加手順

実際にansible.cfgに設定を追加する手順を解説します。

1. ansible.cfgの場所と優先順位を確認する

Ansibleはansible.cfgを以下の順番で探し、最初に見つかったものを使用します。

・環境変数 ANSIBLE_CONFIG(最優先)
・カレントディレクトリの ansible.cfg(Playbookと同じディレクトリ)
・ホームディレクトリの ~/.ansible.cfg
・システム全体の /etc/ansible/ansible.cfg(最低優先)

Playbookをプロジェクト単位で管理している場合は、Playbookと同じディレクトリにansible.cfgを置くのがおすすめです。プロジェクト固有の設定をシステム全体に影響させずに管理できます。現在どのansible.cfgが使われているかを確認するには次のコマンドを使います。

# 使用中のansible.cfgを確認する ansible --version | grep config # 出力例: # config file = /home/admin/playbooks/ansible.cfg

2. ansible.cfgに3つのチューニング設定を追加する

以下がforks・pipelining・fact cachingを一括で設定したansible.cfgの例です。

# ansible.cfg(Playbookと同じディレクトリに配置) [defaults] # 並列実行数(デフォルト5→20に引き上げ) forks = 20 # SSHオーバーヘッドを削減するpipelining pipelining = True # Fact収集のキャッシュ設定 gathering = smart fact_caching = jsonfile fact_caching_connection = /tmp/ansible_facts_cache fact_caching_timeout = 86400 [ssh_connection] # SSH接続を使い回してオーバーヘッドをさらに削減 ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no

各パラメータの意味:
forks = 20: 最大20台に対して同時にタスクを実行する
pipelining = True: スクリプトをstdinで送り込みSSH接続数を削減する
gathering = smart: キャッシュがあればFact収集をスキップする
fact_caching = jsonfile: FactをローカルのJSONファイルに保存する
fact_caching_connection: キャッシュファイルの保存ディレクトリ(自動作成される)
fact_caching_timeout = 86400: キャッシュの有効期限(秒)。86400秒 = 24時間
ControlMaster=auto / ControlPersist=60s: SSH接続を60秒間使い回して接続コストを削減

3. 設定前後の実行時間を計測して効果を確認する

timeコマンドをPlaybook実行に組み合わせると、設定変更の効果を数字で把握できます。50台のサーバーに8タスクを流す構成での実測例です。

設定前(forks=5、pipelining=False、fact caching無効):

$ time ansible-playbook -i inventory/production site.yml PLAY [web servers] ************************************************************ TASK [Gathering Facts] ******************************************************** ok: [192.168.10.11] ok: [192.168.10.12] (...50台分...) PLAY RECAP ******************************************************************** 192.168.10.11 : ok=8 changed=3 unreachable=0 failed=0 skipped=0 192.168.10.12 : ok=8 changed=3 unreachable=0 failed=0 skipped=0 (...50台分...) real 8m43.221s user 0m12.304s sys 0m2.891s

設定後(forks=20、pipelining=True、fact caching有効・2回目以降):

$ time ansible-playbook -i inventory/production site.yml PLAY [web servers] ************************************************************ TASK [Gathering Facts] ******************************************************** ok: [192.168.10.11] ok: [192.168.10.12] (...50台分、キャッシュから読み込み...) PLAY RECAP ******************************************************************** 192.168.10.11 : ok=8 changed=3 unreachable=0 failed=0 skipped=0 192.168.10.12 : ok=8 changed=3 unreachable=0 failed=0 skipped=0 (...50台分...) real 1m47.583s user 0m14.112s sys 0m3.022s

同じPlaybookを50台に実行した場合、約8分43秒が約1分47秒まで短縮されました。どの設定がどれだけ効いているかを個別に検証したい場合は、1設定ずつ変更しながら計測するのが確実です。

pipelining・forks・fact cachingを組み合わせたansible.cfgのチューニングは、一度覚えてしまえばすべてのプロジェクトで使える手法です。Ansibleの実践スキルを体系的に学びたい方は、Ansible実践ハンズオンの詳細もご覧ください。100台規模のサーバー管理を想定した演習を通じて、チューニングを含むAnsibleの運用設計が身につきます。

pipelining有効化時の注意点——requirettyとsudoの関係

pipelining = Trueに設定すると、接続先ホストでsudoを使用しているタスクが失敗するケースがあります。原因はsudoersのrequiretty設定です。

多くのLinuxディストリビューションのsudoers設定にはrequirettyが有効になっており、「sudoを実行するにはターミナルが必要」という制約が課せられています。pipeliningはSSHの疑似ターミナル(PTY)を使わないため、requirettyが有効なままだとsudo実行時にエラーが発生します。

エラーの症状:

TASK [install nginx] ********************************************************** fatal: [192.168.10.11]: FAILED! => { "msg": "sudo: sorry, you must have a tty to run sudo" }

対処:ターゲットホストのsudoersにrequirettyを無効化する行を追加する

# ターゲットホストで visudo を実行して以下を追加 # /etc/sudoers または /etc/sudoers.d/ansible に記述する Defaults !requiretty # または特定のAnsible実行ユーザーのみ無効化する場合: Defaults:ansible !requiretty

変更の適用はvisudoコマンドで行うこと。visudoには構文チェック機能があり、誤った設定によるsudoロックアウトを防止できます。

なお、RHEL 9 / Rocky Linux 9ではデフォルトでrequirettyは無効になっています。Ubuntu 22.04 LTS以降も同様です。ターゲットホストのディストリビューションを確認し、requirettyが有効な場合のみこの手順を適用してください。

追加できるansible 高速化の設定——profile_tasks・gather_subset・strategy free

forks・pipelining・fact caching以外にも、実行時間の短縮や計測に役立つansible.cfgのオプションを紹介します。

1. callbacks_enabled = profile_tasksでタスク別の時間を可視化する

どのタスクが時間を消費しているかを特定するには、profile_tasksコールバックが有効です。

# ansible.cfg [defaults] callbacks_enabled = profile_tasks

Playbook実行後にタスク別の実行時間が表示され、ボトルネックタスクの特定に役立ちます。チューニングの計測期間中は有効にしておき、本番運用では必要に応じて外すのが実用的な使い方です。

2. gather_subsetで必要なFactだけ収集する

fact cachingを使わない場合でも、収集するFactの種類を絞ることで収集時間を短縮できます。

# ansible.cfg [defaults] gather_subset = !all,network,hardware # または各Playbookに直接指定する場合 - hosts: all gather_subset: - "!all" - "network"

「!all」で全Fact収集を無効にしてから、必要なサブセット(network・hardware等)だけ指定する書き方が扱いやすいです。Playbookの中でどのFactを参照しているかを先に確認してから絞り込んでください。

3. strategy = freeで全ホストの足並みを揃えない

デフォルトのstrategy(linear)では、全ホストが同じタスクを完了してから次のタスクに進みます。strategy = freeにすると、処理が速いホストはどんどん先のタスクに進めるため、全体の実行時間が短縮されます。

# ansible.cfg [defaults] strategy = free

ただし、後続タスクが前のタスクの結果に依存している構成では誤動作の原因になります。依存関係のないシンプルなPlaybookにのみ適用してください。

トラブルシュート——チューニング後に起きやすい問題と対処

1. fact cachingを有効にしたらFact情報が古いまま使われた

症状:IPアドレス変更後も古いFact(ansible_default_ipv4.address等)が使われてしまう
原因:fact_caching_timeoutが切れる前にホストのFact情報が変わった
対処:キャッシュを手動でクリアしてから再実行する

# fact_caching_connection で指定したディレクトリを削除して再収集させる rm -rf /tmp/ansible_facts_cache/* # または特定ホストのキャッシュのみ削除する場合 rm -f /tmp/ansible_facts_cache/192.168.10.11

インフラ変更(IPアドレス変更・NIC追加等)を実施した後は、fact_caching_timeoutを待たずにキャッシュを手動でクリアする運用を習慣にするとトラブルを防げます。

2. pipelining有効後にSSH接続エラーが増えた

症状:pipelining = Trueにしてから特定のタスクがunreachableになる
原因:ssh_args のControlMasterが既存の壊れたSSH接続を使い回してしまっている
対処:既存のSSH接続を削除してから再実行する

# SSHコントロールソケットをすべて削除する find ~/.ansible/cp -type s -exec rm -f {} \; # 次回Playbook実行時に新しいSSH接続が確立される

3. forksを増やしたらコントロールノードが高負荷になった

症状:forks=50にしたらコントロールノードのCPU使用率が90%を超えてPlaybookが遅くなった
原因:コントロールノードの処理能力を超えたforks数を設定した
対処:forks値を段階的に下げてコントロールノードのCPU・メモリが50%前後に収まる値を探す

forks値の調整時はhtopやvmstatで実行中のコントロールノードのリソース使用状況を監視しながら決めるのが確実です。理論値より実測値を優先してください。

本記事のまとめ

Ansibleのansible.cfgチューニングのポイントをまとめます。

設定項目 役割 推奨設定の目安
forks 並列実行するホスト数の上限 20前後から始め、コントロールノードのCPU負荷を見ながら調整
pipelining SSH接続数を削減してタスク実行を高速化 True(ターゲットホストのrequiretty無効化を確認すること)
gathering Fact収集の頻度制御 smart(fact caching有効時)
fact_caching Factを保存してFact収集をスキップ jsonfile(単一コントロールノードなら十分)
fact_caching_timeout Factキャッシュの有効期限(秒) 86400(24時間)が実用的
ControlMaster / ControlPersist SSH接続を使い回してオーバーヘッドを削減 ControlMaster=auto、ControlPersist=60s
callbacks_enabled タスク別の実行時間を可視化 profile_tasks(チューニング計測時に有効化)
ansible 高速化はansible.cfgの数行の変更から始まります。forks・pipelining・fact cachingの3つを組み合わせるだけで、50台規模の環境なら実行時間を数分の一に短縮できます。チューニング前後の実行時間を必ず計測し、設定の効果を数字で確認しながら進めてください。

Ansibleのパフォーマンスチューニングを含む実践スキルを体系的に身につけたい方は、ぜひ詳細をご覧ください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。