Docker
API-интерфейс Docker Engine
Поиск…
Вступление
API, который позволяет вам контролировать все аспекты Docker из ваших собственных приложений, создавать инструменты для управления и мониторинга приложений, работающих на Docker, и даже использовать его для создания приложений на самом Docker.
Включить удаленный доступ к Docker API в Linux
Измените DOCKER_OPTS
/etc/init/docker.conf
и обновите переменную DOCKER_OPTS
следующим образом:
DOCKER_OPTS='-H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock'
Перезапустить Docker deamon
service docker restart
Проверьте, работает ли Remote API
curl -X GET http://localhost:4243/images/json
Включить удаленный доступ к API-интерфейсу Docker на Linux, работающем systemd
Linux, работающий systemd, как Ubuntu 16.04, добавление -H tcp://0.0.0.0:2375
в /etc/default/docker
не имеет никакого эффекта, к которому он привык.
Вместо этого создайте файл с именем /etc/systemd/system/docker-tcp.socket
чтобы сделать докеры доступными для TCP-сокета на порту 4243:
[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
Теперь проверьте, работает ли Remote API:
curl -X GET http://localhost:4243/images/json
Включить удаленный доступ с помощью TLS на Systemd
Скопируйте файл блока установщика пакета в / etc, где изменения не будут перезаписаны при обновлении:
cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
Обновите /etc/systemd/system/docker.service с вашими параметрами в ExecStart:
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
dockerd
. Также обратите внимание, что 2376 - стандартный стандартный порт TLS, 2375 - стандартный незашифрованный порт. См. Эту страницу о шагах по созданию собственного собственного сертификата CA, сертификата и ключа TLS.
После внесения изменений в файлы unitd, запустите следующую команду, чтобы перезагрузить конфигурацию systemd:
systemctl daemon-reload
Затем запустите следующий перезапуск докера:
systemctl restart docker
Плохая идея пропустить шифрование TLS при экспорте порта Docker, поскольку любой, у кого есть сетевой доступ к этому порту, имеет полный доступ root на хост.
Потяжка изображения с индикаторами выполнения, написанная на Go
Вот пример вытягивания изображения с использованием Docker Engine API
Go
и Docker Engine API
и тех же индикаторов выполнения, что и показанные при запуске 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 с передачей некоторой сложной структуры
При использовании cURL
для некоторых запросов к Docker API
может быть немного сложно передать некоторые сложные структуры. Скажем, получение списка изображений позволяет использовать фильтры в качестве параметра запроса, которые должны быть 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
будут использоваться в запросе HTTP GET
вместо запроса POST
который в противном случае использовался бы. Данные будут добавлены к URL-адресу с помощью ?
разделитель.