この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
最近Goの勉強がてらDocker Engine SDKを使って、コンテナを操作するCLIツールを作っているのでそのメモです。
今回SDKを使って行ったのは以下の処理です。
- ローカルのコンテナ一覧を取得する
- コンテナをdocker-composeのプロジェクトごとにグループ化する
環境
この記事のサンプルで使ったGolangとSDKのバージョンは下記の通りです。
- go version go1.14.5 darwin/amd64
- github.com/docker/docker v1.13.1
クライアントの生成
Docker APIの接続先としてDOCKER_HOST
などの環境変数を参照するクライアントを生成するサンプルコードは以下になります。(サンプルにあったクライアントの生成はビルドできなくなっていました)
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
)
func main() {
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
panic(err)
}
}
コンテナ一覧取得
コンテナ一覧取得は以下のようなコードになります。
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{
All: true
})
ここでContainerListの引数は以下の構造体です。各項目の役割はdocker ps
のオプションに準じます。
type ContainerListOptions struct {
Quiet bool
Size bool
All bool
Latest bool
Since string
Before string
Limit int
Filters filters.Args
}
フィルタ
docker ps コマンドと同様にフィルタの指定ができます。特定のラベルの値を指定する場合は下記のようになります。
下記の例ではラベルcom.docker.compose.project
に値some_project
がセットされているコンテナに絞り込みます。
// ラベル"com.docker.compose.project=some_project"がついているコンテナ
// (docker-composeにより起動されたコンテナには`"com.docker.compose"`で始まるラベルが付与されている)
labelFilters := filters.NewArgs()
labelFilters.Add("label", "com.docker.compose.project=some_project")
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{
All: true,
Filters: labelFilters,
})
ラベルの値に関わらず、ラベルが付与されているという条件を表すには以下のようになります。
labelFilters := filters.NewArgs()
labelFilters.Add("label", "com.docker.compose.project")
ラベルを使ったグループ化
ContainerListの結果はコンテナ間の関係に関わらずフラットになっています。結果をdocker-composeのプロジェクト単位にグループ化するにはコンテナのラベル値を使って以下のようになります。(自明ですが・・・)
この例ではプロジェクト名をキー、コンテナのリストを値にもつマップを生成しています。
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
)
type ServiceContainerMap map[string][]types.Container
func ListContainerListGroupByService() (ServiceContainerMap, error) {
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
return nil, err
}
//ラベルありのコンテナを取得
labelFilters := filters.NewArgs()
labelFilters.Add("label", "com.docker.compose.project")
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{
All: true,
Filters: labelFilters,
})
if err != nil {
return nil, err
}
//プロジェクトでグループ化
containersByProject := map[string][]types.Container{}
for _, container := range containers {
label := container.Labels["com.docker.compose.project"]
cons := containersByProject[label]
if cons == nil {
cons = []types.Container{}
}
cons = append(cons, container)
containersByProject[label] = cons
}
return containersByProject, nil
}
まとめ
Docker Engine SDKを使ってコンテナ一覧の取得とフィルタリングを行いました。