dockerをAPIで操作できるようにする
dockerをAPIで操作したくなったため環境構築手順と操作手順を残す やりたいこと
手順
code:/lib/systemd/system/docker.service
# ここを
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# こうなおす
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock
code:sh
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl status docker
動作確認
dockerコマンドのときは、単発のコマンドを実行するのはdocker runで十分だった APIではrunに相当するAPIが存在しない
自分でゴニョゴニョAPIを呼ぶ必要がある
以下の順番でAPIを呼び出す
POST /containers/create
POST /containers/{id}/start
GET /containers/{id}/logs?stdout=true&follow=true
GET /containers/{id}/logs?stderr=true&follow=true
code:run-command.sh
# vim: tw=0:
set -eu
# 後始末用
trap '
docker ps -qa | xargs docker rm -f
' 0 EXIT
# containers create
# timeは標準エラー出力に出すので、標準出力とエラー出力を同時に取得できる
curl \
-H 'Content-Type:application/json' \
-X POST \
# containers start
curl \
-H 'Content-Type:application/json' \
-X POST \
# read stdout log
# read stderr log
echo "=== stdout ==="
cat /tmp/1.out
echo "=== stderr ==="
cat /tmp/2.out
OK
ハマったこと
GET /containers/{id}/logs APIが返すデータはcurlではバイナリ形式のレスポンスと判定される よって画面に出力しようとするとエラー扱いになる
当初、curlのプログレス出力が邪魔だったので-sで出力を消していた 結果、取得されるログがバイナリ形式扱いされたため、エラーになっており、画面に出力されなかった
こういうログがでる
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
-sでこれらの出力もまるごと捨てられることを失念していた
「docker logsコマンドならログ取れるのになんでAPIだと取れないんだ~~~~!」ってなった(アホ)
POST /containers/createで"Tty":trueにしているとlogsAPIで普通にログを取得できていたこともあり気づくのが遅れてしまった
Stream format when using a TTY
When the TTY setting is enabled in POST /containers/create, the stream is not multiplexed. The data exchanged over the hijacked connection is simply the raw data from the process PTY and client's stdin.
POST / containers / createでTTY設定が有効になっている場合、ストリームは多重化されません。ハイジャックされた接続を介して交換されるデータは、単にプロセスPTYおよびクライアントのstdinからの生データです。
まぁ、むやみに出力を捨てるのはやめよう