Szukaj…


Wprowadzenie

Interfejs API, który pozwala kontrolować każdy aspekt Dockera z poziomu własnych aplikacji, budować narzędzia do zarządzania i monitorowania aplikacji działających w Docker, a nawet używać go do tworzenia aplikacji na Docker.

Włącz zdalny dostęp do Docker API w systemie Linux

Zmodyfikuj /etc/init/docker.conf i zaktualizuj zmienną DOCKER_OPTS do następujących:

DOCKER_OPTS='-H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock'

Uruchom ponownie Damon Docker

service docker restart

Sprawdź, czy zdalny interfejs API działa

curl -X GET http://localhost:4243/images/json

Włącz zdalny dostęp do Docker API w systemie Linux z systememd

Linux z systemem systemd, taki jak Ubuntu 16.04, dodanie -H tcp://0.0.0.0:2375 do /etc/default/docker nie wywołuje takiego efektu.

Zamiast tego utwórz plik o nazwie /etc/systemd/system/docker-tcp.socket aby udostępnić dokera w gnieździe TCP na porcie 4243:

[Unit]
Description=Docker Socket for the API  
[Socket]
ListenStream=4243  
Service=docker.service  
[Install]
WantedBy=sockets.target 

Następnie włącz nowe gniazdo:

systemctl enable docker-tcp.socket
systemctl enable docker.socket
systemctl stop docker
systemctl start docker-tcp.socket
systemctl start docker

Teraz sprawdź, czy Remote API działa:

curl -X GET http://localhost:4243/images/json

Włącz dostęp zdalny za pomocą TLS w Systemd

Skopiuj plik jednostki instalatora pakietu do / etc, gdzie zmiany nie zostaną nadpisane podczas aktualizacji:

cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service

Zaktualizuj /etc/systemd/system/docker.service z opcjami na 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

Zauważ, że dockerd jest nazwą demona 1.12, zanim był docker daemon . Należy również pamiętać, że 2376 to standardowy port dokerów TLS, 2375 to standardowy nieszyfrowany port. Zobacz tę stronę, aby dowiedzieć się, jak utworzyć własny podpisany certyfikat TLS, certyfikat i klucz TLS.

Po wprowadzeniu zmian w plikach jednostki systemowej uruchom następujące polecenie, aby ponownie załadować konfigurację systemd:

systemctl daemon-reload

Następnie uruchom następujące polecenie, aby zrestartować okno dokowane:

systemctl restart docker

Nie należy ominąć szyfrowania TLS podczas ujawniania portu Docker, ponieważ każdy, kto ma dostęp do tego portu w sieci, ma w rzeczywistości pełny dostęp do roota na hoście.

Ciągnięcie obrazu z paskami postępu, napisane w Go

Oto przykład wizerunku ciągnięcie za pomocą Go i Docker Engine API i te same paski postępu jak te pokazane podczas uruchamiania docker pull your_image_name w CLI . Do celów pasków postępu używane są niektóre kody 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
}

Dla lepszej czytelności akcje kursora z kodami ANSI są przenoszone do osobnej struktury, która wygląda następująco:

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")
}

Następnie w głównym pakiecie możesz wywołać funkcję PullImage przekazując nazwę obrazu, który chcesz pobrać. Oczywiście przed wywołaniem go należy zalogować się do rejestru Docker, w którym znajduje się obraz.

Wykonanie żądania cURL z przekazaniem złożonej struktury

Podczas korzystania z cURL przypadku niektórych zapytań do Docker API przekazywanie skomplikowanych struktur może być nieco trudne. Załóżmy, że pobranie listy obrazów pozwala na użycie filtrów jako parametru zapytania, które muszą być reprezentacją JSON map[string][]string (o mapach w Go można znaleźć więcej tutaj ).
Oto jak to osiągnąć:

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}}'

W tym przypadku flaga -G służy do określenia, że dane w parametrze --data-urlencode zostaną użyte w HTTP GET zamiast żądania POST które w innym przypadku zostałyby użyte. Dane zostaną dołączone do adresu URL za pomocą ? separator.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow