LoginSignup
3
0

More than 3 years have passed since last update.

RustでDocker APIを叩く

Posted at

DockerはREST APIを提供しています。
$ docker build
$ docker run
といったコマンド操作は、内部的にはdocker deamonへの命令をREST API経由で行っており、
それはCLIだけでなくcurlやプログラムで直に叩くこともできます。

Docker Engineは、
1. docker daemon
2. REST API
3. docker CLI
で構成されたクライアント&サーバ アプリケーションです。
https://docs.docker.com/get-started/overview/#docker-engine

Docker公式のSDK(Go, Python)が提供されていますが、Rustの勉強がてらRustで叩いてみました。

コード

main.rs
use std::error::Error;
use std::path::Path;

use futures_util::stream::TryStreamExt;
use hyper::{Client};
use hyperlocal::{Uri, UnixClientExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
    let path = Path::new("/var/run/docker.sock");
    // API version はローカルにインストール済みのdockerのバージョンを確認する
    let url = Uri::new(path, "/v1.40/containers/json");
    let client = Client::unix();
    let response_body = client.get(url.into()).await?.into_body();
    let bytes = response_body
        .try_fold(Vec::default(), |mut buf, bytes| async {
            buf.extend(bytes);
            Ok(buf)
        })
        .await?;

    println!("{}", String::from_utf8(bytes)?);

    Ok(())
}

hyperlocalのリポジトリのREADMEからほぼ引用のコードですが、そのままだと動作しなかったため、一部修正してます。

以下のコンテナの状況
image.png
でプログラム実行してみると、こんな感じで返ってきます。(文字列で出してるので表示が雑ですが。。)
image.png

hyperlocal

docker daemonはデフォルトでUNIX domain socket(/var/run/docker.sock)をリッスンするように設定されており、Hyper(RustのHTTPクライアント&サーバライブラリ)だけでなく、unixソケット通信を実現する hyperlocal を使用する必要がありました。

参考

[公式Doc]
https://docs.docker.com/get-started/overview/#docker-engine
https://docs.docker.com/get-started/overview/#docker-architecture
さわって理解するDocker入門

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0