В этой статье мы рассмотрим пример простого HTTP-сервера, написанного на языке программирования Golang, который предоставляет информацию о контейнерах Docker.
Ссылка на Github
Импорты
Мы начинаем с импорта нескольких пакетов которые нам понадобятся, чтобы работать с Docker и HTTP. Это подобно тому, как вы берете инструменты для ремонта, прежде чем начать работу.
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"net/http"
)
Структура 'DContainer'
Мы определяем специальную структуру (как шаблон), которая будет хранить информацию о контейнерах. В данном случае, эта структура содержит ID контейнера и имя образа.
type DContainer struct {
ID string `json:"id"`
Image string `json:"image"`
}
Функция 'getContainers'
Эта функция ответственна за обработку запросов, которые мы получаем от пользователей. Она использует специальные инструменты, чтобы связаться с Docker, получить список контейнеров и вернуть этот список в формате JSON.
func getContainers(w http.ResponseWriter, r *http.Request) {
// Создание клиента Docker через переменную 'cli'.
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Получение списка контейнеров с использованием Docker API.
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Создание среза 'containersList' для хранения информации о контейнерах.
containersList := make([]DContainer, len(containers))
// Проход по списку контейнеров и заполнение 'containersList'.
for i, container := range containers {
containersList[i] = DContainer{
ID: container.ID[:10], // Обрезаем ID контейнера до 10 символов.
Image: container.Image,
}
}
// Установка заголовка HTTP-ответа для указания формата JSON.
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
// Кодирование 'containersList' в формат JSON и отправка его в HTTP-ответе.
if err := json.NewEncoder(w).Encode(containersList); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
Функция main
Это место, где начинается выполнение программы. Мы говорим программе, что делать при запуске. В данном случае, мы говорим ей создать сервер, который будет слушать запросы на порту 3600, и мы также указываем, какой код должен выполняться при получении запросов.
func main() {
http.HandleFunc("/containers", getContainers)
port := ":3600"
fmt.Printf("Server listening on %s\n", port)
if err := http.ListenAndServe(port, nil); err != nil {
panic(err)
}
}
Запуск сервера
Убедитесть, что у вас установлены Docker и Go
Скопировать код в файл с расширением .go
Запустить сервер выполнив
go run main.go
После запуска сервер будет доступен по адресу http://localhost:3600/containers и предоставит информацию о контейнерах в формате JSON.
Этот сервер - простой пример исключительно для обучения. Вы можете его расширить и добавить больше функций, чтобы сделать его более полезным для мониторинга контейнеров Docker.
Комментарии (7)
mthbtqeytjhzdv
02.10.2023 16:20+1Не знаю на сколько ценно, то что написано в статье, но мне как фронту, было интересно почитать.
capcom6
02.10.2023 16:20В статье нет планов по дальнейшему развитию сего проекта (хотя теги намекают), но вот лично у меня давно руки не дойдут сделать минималистичный аналог cadvisor, хотя там ничего сложного.
Что касается аутентификации, то не сторонник, чтобы этим занимался сам сервис, если он простой как две копейки. Для простых случаев есть reverse-прокси/api gateway. Что nginx, что Traefik прекрасно справятся с организацией Basic-аутентификации. Для Docker Swarm я себе свой простенький reverse-прокси с auto-discovery и возможность аутентификации для отдельных сервисов написал ради интереса (не для прода).
В общем, есть куда стремиться, главное не перестараться.
PS Если хочется прокачаться, то стоит сервис мониторинга и сервис бота делать отдельными. А связь между ними организовать по GRPC. Подозреваю, к этому все и придет)
mrobespierre
02.10.2023 16:20+2Это так странно видеть приличный go-код от негофера. Бросайте фронт, переходите в бэк, у вас неплохо получается)
diyor28
Хотелось бы увидеть продолжение в виде полноценного проекта