Поиск…


Вступление

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-адресу с помощью ? разделитель.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow