Go에서 Docker 컨테이너 관리

선적 서류 비치!

서버에서 컨테이너를 자동으로 업데이트/시작하기 위해 도커 허브 또는 레지스트리에서 후크를 잡기 위해 자전거를 작성하기로 결정한 경우 Docker Cli는 시스템에서 Docker 데몬을 관리하는 데 유용할 수 있습니다.
Go에서 Docker 컨테이너 관리

작동하려면 Go 버전이 1.9.4 이상이어야 합니다.

여전히 모듈로 전환하지 않은 경우 다음 명령을 사용하여 Cli를 설치합니다.

go get github.com/docker/docker/client

컨테이너 실행

다음 예제는 Docker API를 사용하여 컨테이너를 실행하는 방법을 보여줍니다. 명령줄에서 다음 명령을 사용합니다. docker run,하지만 우리 서비스에서이 작업에 쉽게 대처할 수 있습니다.
이 예는 명령을 실행하는 것과 동일합니다. 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)
}

실행 중인 컨테이너 목록 가져오기

이 예는 명령을 실행하는 것과 동일합니다. 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)
    }
}

실행 중인 모든 컨테이너 중지

컨테이너를 만들고 실행하는 방법을 배웠으니 이제 컨테이너를 관리하는 방법을 배울 차례입니다. 다음 예제는 실행 중인 모든 컨테이너를 중지합니다.

프로덕션 서버에서 이 코드를 실행하지 마십시오!

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

단일 컨테이너의 출력 로그

개별 컨테이너로 작업할 수 있습니다. 다음 예시는 지정된 ID를 가진 컨테이너의 로그를 출력합니다. 시작하기 전에 로그를 가져오려는 컨테이너의 ID를 변경해야 합니다.

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

이미지 목록 가져오기

이 예는 명령을 실행하는 것과 동일합니다. 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)
    }
}

당기세요

이 예는 명령을 실행하는 것과 동일합니다. 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)
}

사용자 인증으로 이미지 다운로드

이 예는 명령을 실행하는 것과 동일합니다. docker pull, 인증.

인증 데이터는 일반 텍스트로 전송됩니다. 공식 도커 레지스트리는 HTTPS를 사용합니다.
사설 레지스트리도 HTTPS를 사용하여 통신하도록 구성해야 합니다.

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

출처 : habr.com

코멘트를 추가