Сегодня большинство производственных систем работают на контейнерах. И большая часть контейнеризации выполняется через докер. Docker решает одну из самых больших проблем, с которыми мы сталкиваемся при разработке программного обеспечения:
¯ \ _ (ツ) _ / ¯
Работает на моем компьютере
Мы используем команду docker
, чтобы поговорить с демоном докеров, запущенным на нашем хост-компьютере.
$ docker run nginx $ docker ps $ docker stop <container_id>
Код за командой docker
- это docker cli. Он использует библиотеку docker client для связи с демоном docker через REST API docker engine.
Да, команда docker
, которую мы используем изо дня в день, управляется API, а это означает, что мы можем подключать быстрые решения для масштабирования приложений докеров. Давайте посмотрим, как мы можем выполнить основные действия докера, такие как запуск, список и удаление, с помощью Golang.
Вы можете установить docker SDK for go, используя go get
.
go get github.com/docker/docker
Вот что мы собираемся сделать: возьмем nginx:latest
изображение и выполним некоторые основные действия. В следующих разделах будут представлены команды, соответствующий фрагмент кода и объяснение кода.
Создать докер-контейнер
Команда
$ docker run nginx:latest
Код
Все API-интерфейсы Docker Engine доступны через объект cli
, возвращаемый client.NewEnvClient()
.
cli, err := client.NewEnvClient() if err != nil { fmt.Println("Unable to create docker client") panic(err) }
NewEnvClient
возвращает клиента, принимая необходимые параметры из переменных среды вместо параметров функции.
На данный момент не нужно беспокоиться о переменных среды, если вам не нужно передавать некоторые параметры. По умолчанию он позаботится об этом. Мы используем client.NewEnvClient()
, потому что это самый простой способ создать докер-клиент без передачи каких-либо аргументов.
cli.ContainerCreate
создает для нас контейнер. Он принимает несколько аргументов и возвращает структуруContainerCreateCreatedBody
с идентификатором контейнера в ней. Сигнатура типа функции выглядит так:
ContainerCreate func(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error)
Параметры config
, hostConfig
и networkingConfig
- это типы, которые необходимо импортировать из модуля докера.
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
Узнав параметры функции, мы вызываем функцию cli.ContainerCreate()
cont, err := cli.ContainerCreate( context.Background(), &container.Config{ Image: image, }, &container.HostConfig { PortBindings: portBinding, }, nil, "") if err != nil { panic(err) }
Поскольку мы запускаем контейнер nginx, мы должны открыть порт 80
контейнера для порта 8000
хост-машины. Отображение передается как атрибут: PortBindings
в структуру параметров hostConfig
. Обратите внимание, что мы уже построили отображение, импортировав его типы из пакета nat
.
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") }
После создания контейнера мы получаем идентификатор контейнера из возвращенного объекта и запускаем контейнер.
cli.ContainerStart(context.Background(), cont.ID, types.ContainerStartOptions{})
Если вы заключите этот код в пакет и вызовете функцию, адрес localhost:8000
в вашем браузере должен напечатать приветственное сообщение от nginx, запущенного внутри контейнера.
Список контейнеров докеров
Командование
$ docker container ps
Код
Код здесь довольно прост: вы создаете NewEnvClient()
, вызываете ContainerList
и затем перебираете возвращенный список контейнеров. ContainerList
принимает несколько параметров, таких как ограничение, фильтр и т. Д. Типа types.ContainerListOptions
, но мы просто передаем пустые параметры.
Остановить контейнер докеров
Командование
$ docker container stop <container-id>
Код
ContainerStop()
также принимает тайм-аут как последний аргумент. Здесь мы не указываем таймауты для остановки контейнера.
err = cli.ContainerStop(context.Background(), containerID, nil) if err != nil { panic(err) }
Принимаем в производство
Код, который вы видели, почти готов к работе :)
Вы можете запустить этот код в рабочую среду, просто обернув эти фрагменты в собственные пакеты. Замените все panic
операторами return
и замените операторы Print
некоторой записью в журнал.
Вот, я уже сделал это для вас.
Клонируйте репозиторий и cd
в папку docker-sdk
. Структура кода там должна выглядеть так:
docker-sdk | |_ main.go | |_ glide.lock | |_ glide.yaml | |_ container/ | |_ container.go | |_ container_test.go
Я использовал Glide как пакетный менеджер. Итак, установите glide, выполнив brew install glide
. Если вы не используете macOS, сделайте go get github.com/Masterminds/glide
.
Установите зависимости, запустив glide install
из папки docker-sdk
.
Теперь вы можете поиграть с кодом, вызывая различные функции пакета container
внутри main.go
.
Считаете этот пост интересным?
Для меня было бы очень много значить, если бы вы могли удерживать значок хлопать и кричать мне в twitter. Это действительно сделало бы мой день лучше.
Также вы можете подписаться на нашу рассылку, чтобы получать больше сообщений в блогах и курсов по серверной инженерии.
- спасибо!