Docker
ドッカーエンジンAPI
サーチ…
前書き
独自のアプリケーションからDockerのあらゆる側面を制御したり、Docker上で動作するアプリケーションを管理および監視したり、Docker上でアプリケーションを構築するために使用するツールを作成するためのツールを構築するAPI。
Linux上でDocker APIへのリモートアクセスを有効にする
/etc/init/docker.conf
を編集し、 DOCKER_OPTS
変数を次のように更新します。
DOCKER_OPTS='-H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock'
Dockerデーモンを再開する
service docker restart
リモートAPIが動作しているかどうかを確認する
curl -X GET http://localhost:4243/images/json
systemdを実行しているLinuxでDocker APIへのリモートアクセスを有効にする
Ubuntu 16.04のように、Linuxが稼動しているsystemdは、 -H tcp://0.0.0.0:2375
を/etc/default/docker
-H tcp://0.0.0.0:2375
追加しても、これまでの影響はありません。
その代わり、というファイルを作成/etc/systemd/system/docker-tcp.socket
ポート4243上のTCPソケットにドッキングウィンドウを利用できるようにします。
[Unit]
Description=Docker Socket for the API
[Socket]
ListenStream=4243
Service=docker.service
[Install]
WantedBy=sockets.target
次に、新しいソケットを有効にします。
systemctl enable docker-tcp.socket
systemctl enable docker.socket
systemctl stop docker
systemctl start docker-tcp.socket
systemctl start docker
次に、リモートAPIが動作しているかどうかを確認します。
curl -X GET http://localhost:4243/images/json
Systemd上のTLSによるリモートアクセスを有効にする
パッケージインストーラユニットファイルを/ etcにコピーします。ここで変更はアップグレード時に上書きされません:
cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
ExecStartのオプションで/etc/systemd/system/docker.serviceを更新してください:
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376 \
--tlsverify --tlscacert=/etc/docker/certs/ca.pem \
--tlskey=/etc/docker/certs/key.pem \
--tlscert=/etc/docker/certs/cert.pem
その注意dockerd
前にそれがあった、1.12デーモン名でdocker daemon
。また、2376はドッカーの標準TLSポート、2375は標準の暗号化されていないポートです。独自のTLS自己署名CA、証明書、およびキーを作成する手順については、 このページを参照してください 。
systemdユニットファイルを変更した後、次のコマンドを実行してsystemd configをリロードします。
systemctl daemon-reload
ドッカーを再起動するには、次のコマンドを実行します。
systemctl restart docker
Dockerポートを公開するとTLS暗号化をスキップするのは悪い考えです.Dockerポートへのネットワークアクセス権を持つユーザーは、実質的にホストにフルルートアクセスできます。
Goで書かれたプログレスバー付きのイメージ引っ張り
ここでは、 Go
とDocker Engine API
を使用したイメージのdocker pull your_image_name
と、 CLI
docker pull your_image_name
を実行したときのプログレスバーと同じプログレスバーを示しCLI
。進捗バーの目的のために、いくつかのANSIコードが使用されます 。
package yourpackage
import (
"context"
"encoding/json"
"fmt"
"io"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
// Struct representing events returned from image pulling
type pullEvent struct {
ID string `json:"id"`
Status string `json:"status"`
Error string `json:"error,omitempty"`
Progress string `json:"progress,omitempty"`
ProgressDetail struct {
Current int `json:"current"`
Total int `json:"total"`
} `json:"progressDetail"`
}
// Actual image pulling function
func PullImage(dockerImageName string) bool {
client, err := client.NewEnvClient()
if err != nil {
panic(err)
}
resp, err := client.ImagePull(context.Background(), dockerImageName, types.ImagePullOptions{})
if err != nil {
panic(err)
}
cursor := Cursor{}
layers := make([]string, 0)
oldIndex := len(layers)
var event *pullEvent
decoder := json.NewDecoder(resp)
fmt.Printf("\n")
cursor.hide()
for {
if err := decoder.Decode(&event); err != nil {
if err == io.EOF {
break
}
panic(err)
}
imageID := event.ID
// Check if the line is one of the final two ones
if strings.HasPrefix(event.Status, "Digest:") || strings.HasPrefix(event.Status, "Status:") {
fmt.Printf("%s\n", event.Status)
continue
}
// Check if ID has already passed once
index := 0
for i, v := range layers {
if v == imageID {
index = i + 1
break
}
}
// Move the cursor
if index > 0 {
diff := index - oldIndex
if diff > 1 {
down := diff - 1
cursor.moveDown(down)
} else if diff < 1 {
up := diff*(-1) + 1
cursor.moveUp(up)
}
oldIndex = index
} else {
layers = append(layers, event.ID)
diff := len(layers) - oldIndex
if diff > 1 {
cursor.moveDown(diff) // Return to the last row
}
oldIndex = len(layers)
}
cursor.clearLine()
if event.Status == "Pull complete" {
fmt.Printf("%s: %s\n", event.ID, event.Status)
} else {
fmt.Printf("%s: %s %s\n", event.ID, event.Status, event.Progress)
}
}
cursor.show()
if strings.Contains(event.Status, fmt.Sprintf("Downloaded newer image for %s", dockerImageName)) {
return true
}
return false
}
読みやすくするために、ANSIコードのカーソルアクションは、次のような別の構造体に移動されます。
package yourpackage
import "fmt"
// Cursor structure that implements some methods
// for manipulating command line's cursor
type Cursor struct{}
func (cursor *Cursor) hide() {
fmt.Printf("\033[?25l")
}
func (cursor *Cursor) show() {
fmt.Printf("\033[?25h")
}
func (cursor *Cursor) moveUp(rows int) {
fmt.Printf("\033[%dF", rows)
}
func (cursor *Cursor) moveDown(rows int) {
fmt.Printf("\033[%dE", rows)
}
func (cursor *Cursor) clearLine() {
fmt.Printf("\033[2K")
}
その後、メインパッケージで、プルしたい画像名を渡してPullImage
関数を呼び出すことができます。もちろん、それを呼び出す前に、画像があるDockerレジストリにログインする必要があります。
複雑な構造を渡してcURL要求を行う
Docker API
へのクエリにcURL
を使用する場合、複雑な構造を渡すのは少し難しいかもしれません。さんが言ってみましょう、 画像の一覧を取得するクエリパラメータとしてフィルタを使用することができ、されなければならないJSON
の表現map[string][]string
(内マップについてのGo
あなたはもっと見つけることができるここに )。
これを達成する方法は次のとおりです。
curl --unix-socket /var/run/docker.sock \
-XGET "http:/v1.29/images/json" \
-G \
--data-urlencode 'filters={"reference":{"yourpreciousregistry.com/path/to/image": true}, "dangling":{"true": true}}'
ここでは、 -G
フラグを使用して、 --data-urlencode
パラメータのデータを、別の方法で使用されるPOST
要求の代わりにHTTP GET
要求で使用するように指定します。データは?
URLに追加されます?
セパレータ。