概要
- curl や wget が使えない最小限の Docker コンテナでの HTTP 通信方法の紹介
- bash の /dev/tcp 機能を利用した GET リクエストの実行手順
- 追加ヘッダー の送信方法や注意点の解説
- 制限事項 (TLS非対応・POSIX非互換など)への言及
- 簡易チェックやデバッグ用途 に有効なテクニックの説明
curl や wget なしで Docker コンテナ間の HTTP 通信確認
- curl や wget がインストールされていない極小イメージでの HTTP 通信確認方法
- bash の /dev/tcp 機能を使い、 TCPソケット を直接オープン
- サービス名やホスト名、ポート番号は Docker ネットワーク 内で解決可能なものを指定
-
以下のコマンドで GET /health リクエストを送信し、レスポンス全体を取得可能
exec 3<>/dev/tcp/service/8642printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3cat <&3
- service 部分には通信したいサービス名やホスト名を指定
- レスポンス にはステータスライン、ヘッダー、空行、ボディがすべて含まれる
HTTPヘッダー追加や Bearer 認証の付与方法
- Authorization ヘッダーなどを追加したい場合は、リクエストのヘッダー行を増やす
-
例:Bearer トークンを付与して /v1/models にアクセス
exec 3<>/dev/tcp/service/8642printf 'GET /v1/models HTTP/1.1\r\nHost: service\r\nAuthorization: Bearer %s\r\nConnection: close\r\n\r\n' "$API_KEY" >&3cat <&3
- 各ヘッダーは \r\n で区切り、最後は空行でリクエスト終了を明示
/dev/tcp の仕組みと注意点
- /dev/tcp は実際のデバイスファイルではなく、bash 内部でのみ動作する特殊リダイレクト
ls /dev/tcpなどで実体を確認することはできない- bash マニュアルによると、 /dev/tcp/host/port 形式で指定すると、bash が自動的に DNS 解決とソケット接続を実行
- exec 3<> でファイルディスクリプタ3をソケットに割り当て、 読み書き が可能
制限事項と運用上のポイント
- これは 本格的な HTTP クライアント ではなく、
- リダイレクト や チャンク転送、 圧縮、 リトライ、 TLS など curl が持つ機能は一切非対応
- Connection: close ヘッダーが重要
- 省略するとサーバ側が接続を開いたままにし、cat が永遠に待機してしまう
- サーバに接続終了を明示し、cat が EOF で終了できるようにする
- timeout コマンドでタイムアウト制御も推奨
- 例:
timeout 6 bash -c '...'
- 例:
- TLS(HTTPS)非対応
- /dev/tcp はプレーンなソケット接続のみ
- HTTPS が必要な場合は openssl s_client など他ツールが必要
- bash 固有機能
- POSIX 標準ではなく dash や zsh では非対応
- #!/bin/bash で明示的に bash を指定
- bash ビルド時に --enable-net-redirections オプションが有効な場合のみ利用可能
- 多くのディストリビューションでは有効だが、最小構成や古い環境では無効の場合あり
- 通常は curl 推奨
- あくまで極小コンテナや一時的なデバッグ用途のテクニック
- 必要に応じて適切な HTTP クライアントの導入検討が望ましい
まとめ
- bash の /dev/tcp 機能 を使えば、curl や wget なしで簡易的な HTTP 通信が可能
- 最小限コンテナ内の疎通確認やデバッグ に便利な裏技
- 制限事項や利用条件 を理解した上で、適切に使い分けることが重要