大規模環境を無停止で操る:Ansible `serial` を用いた「安全かつ情け容赦のない」ローリングアップデート戦略
こんにちは。インフラエンジニアの皆さん。
「Ansibleで全サーバーに設定を適用したら、全台同時にサービスがダウンして冷や汗をかいた」……そんな経験はありませんか?
実は、Ansibleのデフォルト設定は「並列ですべてのホストを一気に叩く」という極めてアグレッシブな仕様です。これは小規模環境なら高速で便利ですが、本番環境では「全滅」を意味します。
今回は、「サービスを止めずに、安全かつ確実にアップデートを完了させる」ための、Ansibleの奥義 `serial` を用いたローリングアップデートの実装術を伝授します。これをマスターすれば、深夜のデプロイで胃を痛めることもなくなりますよ。
—
1. なぜ「serial」が最強の防壁なのか
Ansibleの `serial` パラメータは、Playbookが一度に処理するホストの数を制限します。
- デフォルト: 全ホスト同時並行(危険!)
- serial: 1: 一台ずつ丁寧に処理(最も安全)
- serial: 25%: 全体の4分の1ずつ処理(大規模環境向け)
この仕組みを、「ヘルスチェック」と組み合わせることで、「更新したノードが正しく生きていることを確認してから、次のノードへ進む」という堅牢なデプロイパイプラインが完成します。
—
2. 準備:Ansibleの基礎セットアップ
まずは、環境を整えましょう。まだAnsibleをインストールしていない場合は、コントロールノード(あなたの作業PCや踏み台サーバー)に導入します。
Python環境の準備(仮想環境推奨)
python3 -m venv venv
source venv/bin/activate
インストール
pip install ansible
動作確認:HelloWorldならぬ「HelloNodes」
まずは、全ノードが疎通可能か確認するだけの最小構成です。
inventory.ini
[webservers]
web01 ansible_host=192.168.1.10
web02 ansible_host=192.168.1.11
web03 ansible_host=192.168.1.12
web04 ansible_host=192.168.1.13
test.yml
- name: 疎通確認
hosts: webservers
tasks:
- name: Pingを打つ
ping:
`ansible-playbook -i inventory.ini test.yml` を実行し、すべて `pong` が返ってくれば準備完了です。
—
3. 実践:サービス停止ゼロのローリングアップデート
では、本題です。Webサーバーを1台ずつ切り離して更新し、復帰後にヘルスチェックを行うPlaybookを書きます。
—
- name: Rolling Update Strategy
hosts: webservers
# 一度に処理するホスト数を1台に制限
serial: 1
tasks:
- name: 1. ロードバランサーから切り離し(例)
command: /usr/local/bin/lb_detach.sh {{ inventory_hostname }}
delegate_to: localhost
- name: 2. アプリケーションの更新
yum:
name: my-app
state: latest
- name: 3. ロードバランサーに再投入
command: /usr/local/bin/lb_attach.sh {{ inventory_hostname }}
delegate_to: localhost
- name: 4. ヘルスチェック(重要!)
uri:
url: “http://{{ inventory_hostname }}/health”
status_code: 200
register: result
until: result.status == 200
retries: 5
delay: 10 # 10秒おきに最大5回リトライ
このコードの「現場的」ポイント
1. `serial: 1`: 常に1台のみをメンテナンス対象にします。残りの3台はサービスを継続するため、全体としてのダウンタイムはゼロです。
2. `delegate_to: localhost`: ロードバランサーの操作などは、対象ノードではなく「自分自身(管理サーバー)」から実行させるのが定石です。
3. `until` ループ: 「更新した瞬間にヘルスチェックが通る」とは限りません。プロセス起動のラグを考慮し、成功するまで粘り強く待機させるのがプロの設計です。
—
4. さらなる高みへ:max_fail_percentage
もし、100台のサーバーを更新していて、3台目で失敗したとします。デフォルトではそこで全処理が止まりますが、運用によっては「10%の失敗までは許容してデプロイを続行したい」というケースもあるでしょう。
そんな時は `max_fail_percentage` を併用します。
- hosts: webservers
serial: 20%
max_fail_percentage: 10 # 10%以上のノードで失敗したら即座に停止
—
最後に:自動化は「安心」を買うためのもの
初心者のうちは「全部一気にやってしまえ!」という誘惑に駆られますが、インフラエンジニアの腕の見せ所は、「失敗したときに、いかに被害を最小限に抑えるか」という防衛的な設計にあります。
この `serial` を使ったローリングアップデートは、まさにその第一歩です。最初は怖がらず、まずは2台のサーバーから試してみてください。一つずつ着実に成功を積み重ねる感覚が分かれば、大規模なクラスターも怖くなくなりますよ。
あなたのデプロイが、今日も平穏無事であることを願っています。それでは、良い自動化ライフを!