OllamaをAnsibleで複数Linuxサーバーに一括デプロイする方法|Playbookで本番クラスターを統一管理する手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)ローカルLLM > OllamaをAnsibleで複数Linuxサーバーに一括デプロイする方法|Playbookで本番クラスターを統一管理する手順
「Ollamaを社内の複数台サーバーに展開したが、タイミングがずれてバージョンが揃わない状態になってしまった」
「新しいモデルを追加するたびに全台へSSHログインして同じコマンドを打ち込む手作業が積み重なり、ミスが出始めた」
そんな悩みを持つインフラエンジニアは多い。Ollamaは1台のセットアップには十分使いやすいが、2台・3台と増えると構成のばらつきや作業ミスが避けられなくなってくる。Ansibleを活用すれば、Playbook1本で全サーバーへ同じ手順を冪等(べきとう)に実行でき、構成のばらつきを根本からなくせる。この記事では、AnsibleでOllamaを複数のLinuxサーバーに一括デプロイする手順を、inventoryファイルの作成からOllamaのインストール・systemdサービス設定の配布・モデルの自動取得まで、ステップ別に解説する。

この記事のポイント

・ansible-playbookコマンド一発でOllamaを全サーバーに一括インストールできる
・ollama pullをAnsibleタスク化することで指定モデルを全台に自動展開できる
・--limitや--tagsオプションで特定ホストや特定タスクだけを安全に再実行できる
・Playbookをidempotent設計にすることで何度実行しても副作用が発生しない


OllamaをAnsibleで複数Linuxサーバーに一括デプロイする方法|Playbookで本番クラスターを統一管理する手順

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

AnsibleでOllamaを複数台管理する利点

ローカルLLMをチームで活用する場面では、負荷分散や冗長化のために複数台のサーバーにOllamaを展開するケースが増えてくる。手作業でのセットアップは最初の1台こそ問題ないが、台数が増えると構成のばらつきが蓄積していく。

現場で聞いた話だと、5台のUbuntuサーバーへ手作業でOllamaを展開したインフラチームが、インストールタイミングのずれでバージョンが2種類混在する状態になってしまったという。モデルの推論結果が台によって微妙に異なり、原因特定に丸1日を要したとのことだった。

Ansibleを使えばこの問題をPlaybook1本で解決できる。最大の強みは冪等性(idempotency)だ。Playbookを何度実行しても同じ最終状態が保証される。サーバーを追加したときも、inventoryに1行追記すれば次のPlaybook実行で自動的に同一構成になる。社内でChatGPTが制限されていてローカルLLMを複数部署向けに展開する場合(社内でChatGPTが使えないときの代替手段参照)、複数台を一貫して管理できるAnsibleの価値はさらに高まる。

前提環境の確認とSSHの設定

AnsibleはコントロールノードからSSHで対象サーバーを操作する構成だ。事前に環境を整えておこう。

1. コントロールノードの要件

Ansibleを実行するコントロールノードに必要な環境:
・Ubuntu 22.04 以降(または RHEL/AlmaLinux 8 以降)
・Python 3.8 以降
・Ansible 2.15 以降(pip install ansible でインストール)

2. 管理対象サーバーの要件

Ollamaをデプロイする先のサーバーに必要な環境:
・Ubuntu 22.04 または 24.04 LTS(本記事の対象)
・Python 3(Ansibleモジュールの実行に必要)
・SSHサーバー稼働済み
・コントロールノードからのSSH鍵認証設定済み

3. SSH鍵認証の設定

SSH鍵認証がまだの場合は、コントロールノードから以下を実行してパスワードなしで接続できるようにする。

# コントロールノードで実行 $ ssh-keygen -t ed25519 -f ~/.ssh/ansible_key -N "" $ ssh-copy-id -i ~/.ssh/ansible_key.pub ubuntu@192.168.1.101 $ ssh-copy-id -i ~/.ssh/ansible_key.pub ubuntu@192.168.1.102 $ ssh-copy-id -i ~/.ssh/ansible_key.pub ubuntu@192.168.1.103 # 接続確認 $ ssh -i ~/.ssh/ansible_key ubuntu@192.168.1.101 hostname server-01

パスワードなしでhostnameが返れば接続確認は完了だ。Ollamaを単体サーバーに手動で構築する基本手順を確認したい場合は、Ubuntu ServerでローカルLLMを構築する完全ガイドを先に読んでほしい。Playbookで自動化する手順は、この手動手順をそのまま自動化したものだ。

inventoryファイルを作成する

inventoryファイルでAnsibleがどのサーバーを対象にするかを定義する。今回は`~/ansible/ollama/`を作業ディレクトリにする。

# ~/ansible/ollama/inventory.ini [ollama_servers] server-01 ansible_host=192.168.1.101 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/ansible_key server-02 ansible_host=192.168.1.102 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/ansible_key server-03 ansible_host=192.168.1.103 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/ansible_key [ollama_servers:vars] ansible_python_interpreter=/usr/bin/python3

`[ollama_servers]`がサーバーグループ名だ。`[ollama_servers:vars]`でPythonインタープリタのパスを明示すると、Ubuntu 22.04/24.04での自動検出に頼らず安定して動作する。

inventoryが正しく認識されているかをpingモジュールで確認する。

$ ansible -i inventory.ini all -m ping server-01 | SUCCESS => { "changed": false, "ping": "pong" } server-02 | SUCCESS => { "changed": false, "ping": "pong" } server-03 | SUCCESS => { "changed": false, "ping": "pong" }

3台すべてから`pong`が返れば疎通確認は完了だ。

OllamaのインストールPlaybookを実装する

Playbookファイル`ollama-deploy.yml`を作成する。Ollamaの公式インストーラは`curl -fsSL https://ollama.com/install.sh | sh`だが、シェルスクリプトをパイプで直接実行するとPlaybookを再実行するたびにインストーラが走ってしまいidempotencyが崩れる。そこでバイナリの存在確認をしてから条件付きで実行する設計にする。

# ~/ansible/ollama/ollama-deploy.yml --- - name: Deploy Ollama to all LLM servers hosts: ollama_servers become: true vars: ollama_user: ollama ollama_models: - mistral - llama3.3:8b-instruct-q4_0 tasks: - name: Check if ollama binary exists stat: path: /usr/local/bin/ollama register: ollama_bin - name: Install Ollama via official installer shell: curl -fsSL https://ollama.com/install.sh | sh when: not ollama_bin.stat.exists args: executable: /bin/bash - name: Ensure ollama service is enabled and started systemd: name: ollama enabled: true state: started - name: Wait for Ollama API to be ready uri: url: http://localhost:11434/api/tags status_code: 200 retries: 15 delay: 6 register: api_check until: api_check.status == 200

`stat`モジュールで`/usr/local/bin/ollama`の有無を確認し、`when: not ollama_bin.stat.exists`の条件で初回のみインストーラを実行する。これでPlaybookを再実行しても二重インストールされない。

`uri`モジュールでAPIが応答するまで最大90秒待機する設定にしている(retries: 15、delay: 6秒 = 最大90秒)。インストーラ実行直後はsystemdが起動するまで数秒かかるため、この待機処理が重要だ。

systemdサービス設定をPlaybookで配布する

Ollamaの公式インストーラはsystemdユニットを自動生成するが、チーム環境では追加設定が必要なことが多い。たとえばリッスンアドレスを0.0.0.0に変更して社内LAN全体から使えるようにしたり、並列処理数を増やしたりするケースが典型的だ。

こういった設定は`/etc/systemd/system/ollama.service.d/override.conf`に上書き記述するのが定石で、この配布もPlaybookに組み込める。

# ollama-deploy.yml への追記(tasksセクション内) - name: Create systemd override directory for ollama file: path: /etc/systemd/system/ollama.service.d state: directory mode: '0755' - name: Deploy systemd override.conf copy: dest: /etc/systemd/system/ollama.service.d/override.conf content: | [Service] Environment="OLLAMA_HOST=0.0.0.0:11434" Environment="OLLAMA_NUM_PARALLEL=4" Environment="OLLAMA_KEEP_ALIVE=30m" mode: '0644' notify: Reload and restart ollama handlers: - name: Reload and restart ollama systemd: name: ollama daemon_reload: true state: restarted

`notify`と`handlers`を組み合わせると、`override.conf`の内容が変わったときだけ`ollama`サービスが再起動され、変更がない場合は何もしない。ファイルを変えずに再実行すれば「ok」でスキップされる。

サーバーごとにVRAMやCPUコア数が異なる場合は、`host_vars/server-01.yml`に`ollama_num_parallel: 2`のような変数を書き、`templates/override.conf.j2`でJinja2展開する方法を選ぶとよい。

モデルの一括取得タスクを追加する

OllamaはAPIが稼働していないと`ollama pull`が実行できない。前のステップで`uri`モジュールによる起動待機を入れた理由はここにある。`vars`で定義したモデルリストをloopで回してモデルを取得するタスクを追加する。

# ollama-deploy.yml への追記(api_check待機タスクの直後に追加) - name: Pull specified Ollama models command: ollama pull {{ item }} loop: "{{ ollama_models }}" become: true become_user: "{{ ollama_user }}" register: pull_result changed_when: "'pulling manifest' in pull_result.stdout" timeout: 600

`vars.ollama_models`リストにモデルを追記すれば、次のPlaybook実行で全台に自動展開できる。`timeout: 600`(10分)は70Bクラスのモデルでは不足することがあるので、モデルサイズとネット速度に合わせて調整する。

どのモデルを採用すべきかは用途とVRAM容量によって変わってくる。VRAMが4GBのサーバーには`-q4_0`量子化タグのモデルを、8GB以上なら`-q8_0`を選ぶのが基本方針だ。詳細はローカルLLMのモデルを比較する方法を参照してほしい。

最終的なPlaybookのディレクトリ構成は次のようになる。

~/ansible/ollama/ ├── inventory.ini # サーバーグループと接続情報 ├── ollama-deploy.yml # メインPlaybook ├── health-check.yml # ヘルスチェック用(後述) ├── templates/ │ └── override.conf.j2 # サーバー別パラメータをJinja2展開する場合 └── host_vars/ ├── server-01.yml # server-01固有の変数 ├── server-02.yml └── server-03.yml

Playbookを実行して動作を確認する

実行前に`--check`フラグでドライランを行い、差分を確認する。実際の変更は加えない。

# ドライラン(変更は実行しない) $ ansible-playbook -i inventory.ini ollama-deploy.yml --check # 本番実行 $ ansible-playbook -i inventory.ini ollama-deploy.yml # 特定サーバーのみ対象にする $ ansible-playbook -i inventory.ini ollama-deploy.yml --limit server-01 # モデル取得タスクのみ再実行(tagsを事前にタスクへ付与している場合) $ ansible-playbook -i inventory.ini ollama-deploy.yml --tags models

デプロイ完了後、各サーバーのAPIへcurlで疎通確認する。

# 全台のモデル取得状況を一括確認 $ for host in 192.168.1.101 192.168.1.102 192.168.1.103; do echo -n "$host: " curl -s http://$host:11434/api/tags \ | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d['models']),'models')" done # 期待する出力 192.168.1.101: 2 models 192.168.1.102: 2 models 192.168.1.103: 2 models

全台で同じ数のモデルが表示されれば一括デプロイは成功だ。2回目以降にPlaybookを実行すると、変更のないタスクは`ok`と表示されてスキップされる。冪等性が正しく機能している証拠だ。

運用時の拡張とよくあるトラブル対処

本番環境でAnsible管理を続けるうえで役立つ拡張Playbookと、現場でよく踏むエラーの対処をまとめる。

1. 定期ヘルスチェックPlaybook

稼働中のOllamaサービスと読み込まれているモデル数を全台で確認する軽量Playbookを別ファイルで用意しておくと便利だ。

# ~/ansible/ollama/health-check.yml --- - name: Health check Ollama on all servers hosts: ollama_servers tasks: - name: Check Ollama API status uri: url: http://localhost:11434/api/tags status_code: 200 register: health - name: Show model count per server debug: msg: "{{ inventory_hostname }}: {{ health.json.models | length }} models loaded"

2. Ollamaのバージョンアップ手順

バージョンアップは`when`条件を変更してインストーラを強制再実行するタスクを追加するか、shellモジュールで`ollama --version`を取得して期待バージョンと比較する設計が実用的だ。アップデート専用のPlaybook(`ollama-upgrade.yml`)として分けておくと誤操作を防げる。

3. よくあるエラーと対処

UNREACHABLE! ssh: connect to host ... Connection refused
対象サーバーのSSHサービスが停止しているか、ファイアウォールでポート22がブロックされている。`systemctl status ssh`とufwのルールを確認する。

ollama pullがタイムアウトで失敗する
`timeout: 600`の値を増やすか、モデルを小さい量子化タグ(`-q4_0`)に切り替える。70Bクラスはネット環境によって30分以上かかることがある。注意: ネットワーク帯域が細い環境で70Bモデルを全台に一括pullすると、1台あたり60分以上かかるケースがある。タイムアウト値は環境に合わせて設定すること。

インストール直後にAPIが応答しない
`uri`モジュールの`retries`と`delay`を増やして待機時間を延ばす。`retries: 20` `delay: 10`(最大200秒待機)を目安にする。

毎回「changed」になって冪等性が崩れる
`ollama pull`はコマンドの性質上、実行のたびにAnsibleがchangedと判断する。`changed_when`で標準出力のキーフレーズ(例: `'pulling manifest' in pull_result.stdout`)を条件にして誤検知を抑える。

まとめ

AnsibleでOllamaを複数のLinuxサーバーに一括デプロイする手順を解説した。要点を整理する。
作業 主なコマンド/ファイル ポイント
inventory作成 inventory.ini グループ変数でPythonパスを明示する
疎通確認 ansible -i inventory.ini all -m ping 全台pong返却を確認してから進む
ドライラン ansible-playbook ollama-deploy.yml --check 本番前に必ず差分を確認する
一括デプロイ ansible-playbook -i inventory.ini ollama-deploy.yml 冪等設計で再実行しても安全
モデル追加 ansible-playbook ... --tags models varsのollama_modelsを更新後にタグ実行
ヘルスチェック ansible-playbook -i inventory.ini health-check.yml 全台のAPI稼働とモデル数を一括確認
サーバーが1台のうちは手作業でも問題ない。しかし2台目が増えたタイミングでPlaybookを書いておくことが後々の工数削減につながる。現場でよく聞く話だが、「今日やらなかった自動化は、5台目のサーバーが増えた日に3倍の作業コストで返ってくる」は本当のことだ。

まずはテスト環境の2台でinventoryとPlaybookを試してみてほしい。冪等性を体感すると手作業には戻れなくなる。

OllamaクラスターのAnsible管理を実機で体験する

Ansible+Ollamaの複数台デプロイは、頭で理解するより手を動かすほうがはるかに速く習得できる。実機GPU環境で手を動かしながら習得したい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。

>> ローカルAIマスターセミナーの詳細を確認する
ローカルLLMの構築・運用に関する関連記事もあわせて参考にしてください。

Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド
社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢
ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント

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

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

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

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

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

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

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

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

この記事を書いた人

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

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

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