docker『Host is Down』の原因と対処法

docker『Host is Down』の原因と対処法

「Host is Down」は、コンテナやホストから特定のホスト名・IPアドレスに接続しようとしたとき、その宛先が「到達不能」だとOSやネットワーク層が判断したときに出るエラー。リモートサーバの停止、ネットワーク機器の障害、ファイアウォールやVPN、WSL2 / Docker Desktop のブリッジ問題、NFSなどのリモートボリューム障害など、インフラ側の要因が多い。docker だけの問題として切るのではなく、「どのホストへのどの経路が落ちているか」を順に切り分けていくことが重要になる。

エラーの意味と代表的な発生条件

「Host is Down」は Docker 固有のエラーではなく、OSレベルのネットワークエラーとして現れることが多い。docker ログやアプリのログには例えば次のように出る。

curl: (7) Failed to connect to api.example.com port 443: Host is down
ping: sendto: Host is down
nc: connect to 10.0.0.5 port 5432 (tcp) failed: Host is down

これが docker コンテナ内で出ているときの典型的な発生条件は次のようなもの。

・コンテナから外部のAPIサーバ・DBサーバに接続しようとしているが、そのサーバが停止中。

・ホストのルーターやVPN、クラウドVPCなどネットワークパス上の機器がダウン。

・NFS / CIFS などのリモートボリュームをマウントしているコンテナで、ストレージサーバが落ちている。

・Docker Desktop / WSL2 のネットワークブリッジがおかしくなっていて、外部に出られない。

・DNS設定は生きているが、解決されたIP先が応答していない。

まずはホスト側から疎通確認する(Dockerの前にネットワーク)

コンテナ側の調査に入る前に、「ホストOSからそのホストへ到達できるか」を確認する。

# ホストからターゲットへの疎通確認
ping -c 3 api.example.com || echo "ping NG"

# IP直指定でも確認
ping -c 3 10.0.0.5 || echo "ping NG"

# TCPポートへ接続できるか(例: 443, 5432など)
nc -vz api.example.com 443
nc -vz 10.0.0.5 5432

# DNS解決だけ確認
nslookup api.example.com || dig api.example.com

ここでホストからも「Host is down」「Destination Host Unreachable」になる場合は、docker ではなくインフラ側の問題になる。

・リモートサーバの起動状況・再起動。

・ルーター / FW / VPN / クラウドVPCの状態。

・OSレベルのルーティング設定(ip route)やデフォルトゲートウェイ設定。

コンテナ内からの疎通確認(ホストとは結果が違うかを比べる)

ホストからは到達できるのに、コンテナからだけ「Host is Down」になる場合は、Dockerネットワークレイヤの問題が濃厚になる。

# コンテナ内からターゲットにping/curlしてみる
docker exec -it app sh -lc "
  echo '--- ping ---';
  ping -c 3 api.example.com || echo 'ping NG';
  echo '--- curl ---';
  curl -v https://api.example.com/health || echo 'curl NG';
"

# コンテナ内から自身のネットワーク設定を確認
docker exec -it app sh -lc "
  ip addr show;
  ip route show;
  cat /etc/resolv.conf;
"

コンテナ内では:

・デフォルトゲートウェイが設定されているか。

・DNSサーバに到達できているか。

・bridge / overlay ネットワークが壊れていないか。

を確認する。

Dockerネットワーク(bridge / overlay)の状態を確認する

コンテナが所属しているネットワーク自体に問題がある場合、「Host is Down」が大量に出ることがある。

# ネットワーク一覧を確認
docker network ls

# 特定ネットワークの詳細
docker network inspect bridge
docker network inspect myapp_net

確認ポイント。

・ネットワークの Gateway / Subnet が想定どおりか。

・コンテナの IP/Endpoint が正しく登録されているか。

・一度壊れた network を作り直すと改善することも多い。

# 壊れていそうな bridge を再作成する例(検証環境で)
docker network rm myapp_net
docker network create myapp_net

# その後コンテナを再起動してネットワークに再参加させる
docker compose down
docker compose up -d

Swarm や overlay ネットワークの場合は、ノード間疎通やVXLANポート(udp/4789など)がFWで開いているかもあわせて確認する。

リモートサーバ・サービスが本当に起動しているか確認する

ターゲットとなるホスト(DBサーバ、APIサーバ、NFSサーバなど)が実際に「落ちている」場合もある。

# ターゲット側でサービス状態を確認(例: PostgreSQL)
sudo systemctl status postgresql

# サーバ自身から自分のポートを確認
ss -ltnp | grep 5432

# NFSサーバならエクスポート確認
showmount -e

・再起動中・メンテナンス中・クラッシュなどでダウンしていれば、Docker側からできることは限られる。

・リモートサービスを復旧させたあとに、コンテナをリトライ(再起動やヘルスチェックの自動リトライ)させる設計にしておくと耐障害性が高まる。

ファイアウォール / セキュリティグループが原因の「Host is Down」

FW やクラウドのセキュリティグループで ICMP/TCP が絞られていると、実際にはサーバは生きていても、到達不能として扱われることがある。

典型的な例。

・オンプレFWが Docker ホストのIPから宛先サーバへのアクセスを拒否。

・クラウドVPCのSG/ACLで、コンテナの出ていくIPレンジが許可されていない。

・VPNのルート設定で、特定セグメントへの経路がない。

# 例: クラウド環境の場合の概念
# SGで 10.0.1.0/24 → 10.0.2.10:5432 を許可

対処

・ホストのIP/サブネットを正しく許可する。

・NAT や LB 経由でアクセスしている場合は、そのIPアドレスからのトラフィックを許可する。

・docker0 ブリッジをFWでブロックしていないかを確認する(iptables / firewalld / UFW)。

Docker Desktop / WSL2 環境での「Host is Down」

Windows + Docker Desktop / WSL2 の組み合わせでは、仮想ネットワークの不調で「Host is Down」が発生することがある。典型例。

・VPN接続した直後に docker 側のルートが更新されず、特定ネットワークへ到達できない。

・WSL2 のディストリを長時間起動しっぱなしにしていて、仮想NICが壊れる。

対処例。

# WSL2 リセット
wsl --shutdown

# Docker Desktop の Restart
# → GUIメニューから "Restart Docker Desktop"

# 再起動後、WSL2ディストリ内から疎通確認
wsl
ping api.example.com

VPNとの共存が難しい場合は、「VPN接続前にDockerをいったん停止」「VPN接続後にDocker再起動」という運用にすると安定するケースが多い。

NFS / リモートボリュームでの「Host is Down」

コンテナがマウントしているNFS/CIFSなどのリモートボリュームのホストが落ちると、ファイルアクセス時に「Host is Down」「stale NFS file handle」などのエラーが出る。

docker run / compose でよくある例。

# docker-compose.yml の例
services:
  app:
    image: myorg/app
    volumes:
      - nfsdata:/data

volumes:
  nfsdata:
    driver: local
    driver_opts:
      type: nfs
      o: addr=10.0.0.10,nolock,soft
      device: ":/export/data"

NFSサーバ (10.0.0.10) が落ちると、/data へのアクセスで Host is Down となることがある。対処案。

・NFSサーバを復旧させ、再マウントを行う。

・soft マウント / timeo / retrans 等でリトライ挙動を調整する。

# 例: NFSマウントオプション(概念)
o: addr=10.0.0.10,nolock,soft,timeo=5,retrans=3

ストレージ障害が頻発する環境では、アプリ側にも「I/Oエラー時のリトライ」「書き込みの冪等性」を持たせておくと安全。

アプリ側のリトライ・タイムアウト設定での実務的対処

インフラ側を整えても、ネットワークやサーバが瞬断することは避けられない。そのため、アプリケーション側でも「Host is Down や接続失敗時の再試行」「適切なタイムアウト設定」を持たせておくと、ユーザーに見えるエラーを小さくできる。

Node.js の例。

// Node.js axios の例
const axiosInstance = axios.create({
  timeout: 5000, // 5秒でタイムアウト
});

async function callApi() {
  for (let attempt = 1; attempt <= 3; attempt++) {
    try {
      const res = await axiosInstance.get("https://api.example.com/health");
      return res.data;
    } catch (err) {
      console.error(`Attempt ${attempt} failed:`, err.message);
      if (attempt === 3) throw err;
      await new Promise(r => setTimeout(r, 1000 * attempt)); // バックオフ
    }
  }
}

Go の例。

client := &http.Client{
  Timeout: 5 * time.Second,
}

for i := 1; i <= 3; i++ {
  resp, err := client.Get("https://api.example.com/health")
  if err == nil {
    // 正常
    break
  }
  log.Printf("attempt %d failed: %v", i, err)
  time.Sleep(time.Duration(i) * time.Second)
}

アプリ側で再試行しても回復しない場合にのみ、アラートやエラー画面に繋げる運用にすると運用が安定する。

NG→OK 早見表(よくあるパターンと修正例)

# 1) ホスト自身がターゲットに届かない
# NG
docker exec app curl https://api.example.com   # Host is down
# OK: まずホストから確認し、ネットワーク/サーバを復旧
ping -c 3 api.example.com
nc -vz api.example.com 443

# 2) コンテナのみ届かない(Dockerネットワーク問題)
# NG
docker exec app ping 10.0.0.5   # Host is down
# OK: ネットワークを確認・再作成
docker network inspect myapp_net
docker network rm myapp_net
docker network create myapp_net
docker compose down && docker compose up -d

# 3) VPN接続後にDocker Desktopから外に出られない
# NG: そのまま使い続ける
# OK: WSL2とDockerを再起動
wsl --shutdown
# Docker Desktopの "Restart"
docker exec app ping api.example.com

# 4) NFSサーバダウンでコンテナ内I/Oエラー
# NG
docker run -v nfsdata:/data myorg/app   # Host is down
# OK: NFSサーバを復旧し、必要ならマウントオプション調整
# (addr / timeo / retransなど)

チェックリスト(上から順に潰す)

1) どのホスト(api.example.comや10.0.0.5など)にアクセスしたときに「Host is Down」になるか特定したか
2) ホストOSからそのホストにping / nc / curlしてみて、本当に到達できないか確認したか
3) コンテナ内からも同じテストを行い、ホストと結果が違うかどうかを比較したか
4) Dockerネットワーク(bridge / overlay)の設定や状態(gateway/subnet/endpoint)を確認したか
5) リモートサーバ(DB/API/NFSなど)が起動しており、ポートをリッスンしているか確認したか
6) FW / セキュリティグループ / VPNルートで、Dockerホスト(またはコンテナが出ていくIP)の通信が許可されているか
7) Docker Desktop / WSL2 を使っている場合、仮想ネットワークの再起動(wsl –shutdown, Restart Docker Desktop)を試したか
8) NFS / リモートボリュームを使っている場合、そのストレージホストが落ちていないか、マウントオプションが適切か確認したか
9) 断続的な障害に備え、アプリ側に適切なタイムアウトとリトライロジックを入れているか