Go'da Docker konteynerlarini boshqarish

Hujjatlar!

Serverdagi konteynerlarni avtomatik yangilash/ishlash uchun docker hub yoki registrdan ilgaklarni ushlash uchun o'z velosipedingizni yozishga qaror qilganingizda, tizimingizda Docker demonini boshqarishga yordam beradigan Docker Cli-ni foydali deb topishingiz mumkin.
Go'da Docker konteynerlarini boshqarish

Ishlash uchun sizga 1.9.4 dan past bo'lmagan Go versiyasi kerak bo'ladi

Agar siz hali ham modullarga o'tmagan bo'lsangiz, Cli-ni quyidagi buyruq bilan o'rnating:

go get github.com/docker/docker/client

Konteynerni ishga tushirish

Quyidagi misol Docker API yordamida konteynerni qanday ishga tushirishni ko'rsatadi. Buyruqlar satrida siz buyruqdan foydalanasiz docker run, lekin biz xizmatimizda bu vazifani osongina engishimiz mumkin.
Ushbu misol buyruqni bajarishga teng docker run alpine echo hello world

package main {
    ctx := context.Background()
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err)
    }

    // Π”Π΅Π»Π°Π΅ΠΌ docker pull
    reader, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{})
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, reader)

    hostBinding := nat.PortBinding{
        HostIP:   "0.0.0.0",
        HostPort: "8000",
    }
    containerPort, err := nat.NewPort("tcp", "80")
    if err != nil {
        panic("Unable to get the port")
    }
    portBinding := nat.PortMap{containerPort: []nat.PortBinding{hostBinding}}

    // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ с Π·Π°Π΄Π°Π½Π½ΠΎΠΉ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ
    resp, err := cli.ContainerCreate(ctx, &container.Config{
        Image: "alpine",
        Cmd:   []string{"echo", "hello world"},
        Tty:   true,
    }, &container.HostConfig{
        PortBindings: portBinding,
    }, nil, "")
    if err != nil {
        panic(err)
    }

    // ЗапускаСм ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€
    if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
        panic(err)
    }

    // ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π»ΠΎΠ³ΠΈ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°
    out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, out)
}

Ishlayotgan konteynerlar ro'yxatini olish

Ushbu misol buyruqni bajarishga teng docker ps

package main

import (
    "context"
    "fmt"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err)
    }

    // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ списка Π·Π°ΠΏΡƒΡ†Ρ‰Π΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ²(docker ps)
    containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
    if err != nil {
        panic(err)
    }

    // Π’Ρ‹Π²ΠΎΠ΄ всСх ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ²
    for _, container := range containers {
        fmt.Println(container.ID)
    }
}

Barcha ishlaydigan konteynerlarni to'xtatish

Konteynerlarni yaratish va ishga tushirishni o'rganganingizdan so'ng, ularni qanday boshqarishni o'rganish vaqti keldi. Quyidagi misol barcha ishlaydigan konteynerlarni to'xtatadi.

Ushbu kodni ishlab chiqarish serverida ishlatmang!

package main

import (
    "context"
    "fmt"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err)
    }

    // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ списка Π·Π°ΠΏΡƒΡ†Ρ‰Π΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ²(docker ps)
    containers, err := cli.ContainerList(ctx, types.ContainerListOptions{})
    if err != nil {
        panic(err)
    }

    for _, c := range containers {
        fmt.Print("Stopping container ", c.ID[:10], "... ")
        if err := cli.ContainerStop(ctx, c.ID, nil); err != nil {
            panic(err)
        }
        fmt.Println("Success")
    }
}

Bitta konteyner uchun jurnallar ko'rsatilmoqda

Siz individual idishlar bilan ishlashingiz mumkin. Quyidagi misolda belgilangan identifikator bilan konteyner jurnallari ko'rsatilgan. Ishni boshlashdan oldin, jurnallarini olmoqchi bo'lgan konteynerning identifikatorini o'zgartirishingiz kerak.

package main

import (
    "context"
    "io"
    "os"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err)
    }

    options := types.ContainerLogsOptions{ShowStdout: true}
    // Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚Π΅ id ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° здСсь
    out, err := cli.ContainerLogs(ctx, "f1064a8a4c82", options)
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, out)
}

Rasmlar ro'yxatini olish

Ushbu misol buyruqni bajarishga teng docker image ls

package main

import (
    "context"
    "fmt"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err)
    }

    // ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ списка ΠΎΠ±Ρ€Π°Π·ΠΎΠ²
    images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
    if err != nil {
        panic(err)
    }

    for _, image := range images {
        fmt.Println(image.ID)
    }
}

Torting

Ushbu misol buyruqni bajarishga teng docker pull

package main

import (
    "context"
    "io"
    "os"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err)
    }

    // docker pull alpine
    out, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{})
    if err != nil {
        panic(err)
    }
    defer out.Close()
    io.Copy(os.Stdout, out)
}

Foydalanuvchi autentifikatsiyasi bilan rasm yuklab olinmoqda

Ushbu misol buyruqni bajarishga teng docker pull, autentifikatsiya bilan.

Autentifikatsiya ma'lumotlari aniq matnda yuboriladi. Rasmiy docker registri HTTPS dan foydalanadi,
xususiy registrlar HTTPS yordamida ma'lumotlarni uzatish uchun ham sozlanishi kerak.

package main

import (
    "context"
    "encoding/base64"
    "encoding/json"
    "io"
    "os"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewEnvClient()
    if err != nil {
        panic(err)
    }

    // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ
    authConfig := types.AuthConfig{
        Username: "username",
        Password: "password",
    }
    encodedJSON, err := json.Marshal(authConfig)
    if err != nil {
        panic(err)
    }
    authStr := base64.URLEncoding.EncodeToString(encodedJSON)

    out, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{RegistryAuth: authStr})
    if err != nil {
        panic(err)
    }

    defer out.Close()
    io.Copy(os.Stdout, out)
}

Manba: www.habr.com

a Izoh qo'shish