Docker
API del motore Docker
Ricerca…
introduzione
Un'API che ti consente di controllare ogni aspetto di Docker dalle tue applicazioni, creare strumenti per gestire e monitorare le applicazioni in esecuzione su Docker e persino usarlo per creare app su Docker stesso.
Abilita l'accesso remoto all'API Docker su Linux
Modifica /etc/init/docker.conf
e aggiorna la variabile DOCKER_OPTS
al seguente:
DOCKER_OPTS='-H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock'
Riavvia Deamon Docker
service docker restart
Verifica se l'API remota funziona
curl -X GET http://localhost:4243/images/json
Abilita l'accesso remoto all'API Docker su Linux con sistema systemd
Linux con systemd, come Ubuntu 16.04, aggiungendo -H tcp://0.0.0.0:2375
a /etc/default/docker
non ha l'effetto a cui è abituato.
Invece, crea un file chiamato /etc/systemd/system/docker-tcp.socket
per rendere disponibile la finestra mobile su un socket TCP sulla porta 4243:
[Unit]
Description=Docker Socket for the API
[Socket]
ListenStream=4243
Service=docker.service
[Install]
WantedBy=sockets.target
Quindi abilita il nuovo socket:
systemctl enable docker-tcp.socket
systemctl enable docker.socket
systemctl stop docker
systemctl start docker-tcp.socket
systemctl start docker
Ora verifica se l'API remota funziona:
curl -X GET http://localhost:4243/images/json
Abilita l'accesso remoto con TLS su Systemd
Copiare il file dell'unità di installazione del pacchetto su / etc dove le modifiche non verranno sovrascritte su un aggiornamento:
cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
Aggiorna /etc/systemd/system/docker.service con le tue opzioni su 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
Si noti che dockerd
è il nome del daemon 1.12, prima era docker daemon
. Si noti inoltre che 2376 è la porta TLS standard per i docker, 2375 è la porta standard non crittografata. Vedere questa pagina per i passaggi per creare la propria CA autofirmata TLS, certificato e chiave.
Dopo aver apportato le modifiche ai file dell'unità systemd, eseguire quanto segue per ricaricare systemd config:
systemctl daemon-reload
Quindi eseguire quanto segue per riavviare la finestra mobile:
systemctl restart docker
È una cattiva idea ignorare la crittografia TLS quando si espone la porta Docker poiché chiunque abbia accesso alla rete a questa porta ha effettivamente accesso completo alla radice sull'host.
Immagine che tira con le barre di avanzamento, scritte in Go
Ecco un esempio di immagine che tira usando le Docker Engine API
Go
e Docker Engine API
e le stesse barre di avanzamento di quelle mostrate quando si esegue la docker pull your_image_name
nella CLI
. Ai fini delle barre di avanzamento vengono utilizzati alcuni codici 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
}
Per una migliore leggibilità, le azioni del cursore con i codici ANSI vengono spostate in una struttura separata, che assomiglia a questo:
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")
}
Dopodiché nel tuo pacchetto principale puoi chiamare la funzione PullImage
passando il nome dell'immagine che vuoi estrarre. Naturalmente, prima di chiamarlo, è necessario accedere al registro Docker, dove si trova l'immagine.
Fare una richiesta CURL con il passaggio di alcune strutture complesse
Quando si utilizza cURL
per alcune query Docker API
, potrebbe essere un po 'complicato passare alcune strutture complesse. Diciamo che ottenere un elenco di immagini consente di utilizzare i filtri come parametro di query, che deve essere una rappresentazione JSON
della map[string][]string
della mappa (sulle mappe in Go
puoi trovare altre informazioni qui ).
Ecco come ottenere questo:
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}}'
Qui viene utilizzato il flag -G
per specificare che i dati nel parametro --data-urlencode
verranno utilizzati in una richiesta HTTP GET
invece della richiesta POST
che altrimenti verrebbe utilizzata. I dati verranno aggiunti all'URL con un ?
separatore.