логотип PurpleSchool
логотип PurpleSchool

Оркестрация контейнеров Go с Kubernetes + DockerGj

Автор

Александр Гольцман

Golang (или просто Go) — это язык программирования, который отлично подходит для создания высоконагруженных распределённых систем. Kubernetes (K8s) — это мощная платформа для оркестрации контейнеров, позволяющая управлять их развертыванием, масштабированием и отказоустойчивостью. В этой статье я расскажу, почему Go так хорошо сочетается с Kubernetes, какие инструменты есть для работы с кластером и как развернуть Go-приложение в Kubernetes.

Почему Golang и Kubernetes — удачное сочетание?

Прежде чем переходить к практике, давайте разберёмся, почему Go и Kubernetes так хорошо работают вместе.

  1. Kubernetes написан на Go. Весь код Kubernetes реализован на Go, поэтому разработчикам на этом языке проще разбираться в его устройстве, писать операторы, контроллеры и плагины.
  2. Лёгкие и быстрые контейнеризированные приложения. Go-приложения компилируются в статически слинкованные бинарные файлы, не требуют интерпретаторов и виртуальных машин, что делает их идеальными для контейнеров.
  3. Поддержка многопоточности. Благодаря goroutines, Go отлично подходит для сервисов, работающих в распределённой среде.
  4. Официальный клиент для работы с Kubernetes. В экосистеме Go есть удобный клиентский пакет для взаимодействия с Kubernetes API.

Основные инструменты для работы с Kubernetes в Go

Смотрите, если вам нужно управлять Kubernetes-кластером из Go-кода, стоит обратить внимание на несколько ключевых инструментов:

  • client-go — официальный Go-клиент для Kubernetes API.
  • controller-runtime — библиотека для написания кастомных контроллеров и операторов Kubernetes.
  • kubebuilder — инструмент для создания и управления кастомными ресурсами Kubernetes.
  • Helm SDK — если вы работаете с Helm-чартами, есть удобный API для работы с ними в Go.

Как развернуть Go-приложение в Kubernetes

Теперь давайте разберём, как развернуть простое Go-приложение в Kubernetes.

Подготовка Docker-образа

Прежде всего, необходимо создать Docker-образ с Go-приложением. Вот базовый Dockerfile:

FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o app

FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/app .
CMD ["./app"]

Этот Dockerfile сначала собирает бинарник Go-приложения, а затем помещает его в лёгкий контейнер на базе Alpine Linux.

Далее создаём образ и загружаем его в Docker Hub или другую реестр-репозиторию:

docker build -t my-app .
docker tag my-app my-dockerhub-user/my-app:v1
docker push my-dockerhub-user/my-app:v1

Описание манифестов Kubernetes

Теперь нам нужно создать манифесты для Kubernetes. Начнём с Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-dockerhub-user/my-app:v1
        ports:
        - containerPort: 8080

Здесь я разместил описание Deployment, которое разворачивает три реплики контейнера с Go-приложением.

Добавим Service, чтобы сделать приложение доступным внутри кластера:

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP

Теперь запустим всё это в Kubernetes:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

Проверка работы

После развертывания убедимся, что приложение запущено:

kubectl get pods
kubectl get services

Если всё настроено правильно, Go-приложение будет доступно через Kubernetes-сервис.

Работа с Kubernetes API в Go

Если вам нужно программно управлять кластером, можно использовать client-go. Установите его:

go get k8s.io/client-go

Вот пример подключения к Kubernetes API и получения списка подов:

package main

import (
    "context"
    "fmt"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
)

func main() {
    config, err := rest.InClusterConfig()
    if err != nil {
        panic(err)
    }

    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err)
    }

    pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        panic(err)
    }

    for _, pod := range pods.Items {
        fmt.Println("Найден под:", pod.Name)
    }
}

Смотрите, здесь мы создаём клиент, подключаемся к API Kubernetes и запрашиваем список всех подов в кластере. Это полезно для мониторинга, автоматизации и управления инфраструктурой.

Заключение

Go и Kubernetes — это отличное сочетание для разработки современных облачных сервисов. В этой статье я показал, как развернуть Go-приложение в Kubernetes, работать с API кластера и использовать клиентские библиотеки для управления ресурсами.

Если вам нужно просто развернуть приложение, достаточно Docker-контейнера и Kubernetes-манифестов. Если же требуется более глубокая интеграция, стоит изучить client-go и controller-runtime.

Теперь у вас есть базовые знания, чтобы начинать работу с Kubernetes в Go. Дальше всё зависит от ваших задач и требований к инфраструктуре.

Стрелочка влевоМиграции базы данных в GolangGo Playground и компилятор GolangСтрелочка вправо

Все гайды по Golang

Работа с YAML в GolangПреобразование типов в GolangКонвертация структур в JSON в GolangStrconv в GolangИспользование пакета SQLx для работы с базами данных в GolangРазбираемся с SQL в GolangРазделение строк с помощью функции split в GolangSort в GoПоиск и замена строк в Go - GolangИспользование пакета reflect в GolangРабота с PostgreSQL в GoPointers в GolangПарсинг в GoРабота со списками (list) в GolangПреобразование int в string в GolangРабота с числами с плавающей точкой в GolangРабота с полями в GolangИспользование enum в GolangОбработка JSON в GoЧтение и запись CSV-файлов в GolangРабота с cookie в GolangРегистры в GoКэширование данных в GolangПреобразование byte в string в GolangByte в GoИспользование bufio для работы с потоками данных в GolangДобавление данных и элементов (add) в Go
Логирование в Golang. Zap, Logrus, Loki, GrafanaРабота с Docker-контейнерами в GoИспользование pprof в GolangМеханизмы синхронизации в GolangРабота с пакетом S3 в GolangМониторинг Golang приложений с помощью PrometheusОптимизация проектов на GoПаттерны проектирования в GolangМиграции базы данных в GolangОркестрация контейнеров Go с Kubernetes + DockerGjGo Playground и компилятор GolangИспользование go mod init для создания модулей GolangРабота с переменными окружения (env) в GolangКоманда go build в GolangАвтоматизация Golang проектов — CI/CD с GitLab CI и JenkinsОтладка кода в GolangЧтение и использование конфигурации в приложениях на GolangКомпиляция в GolangКак развернуть Go-приложение на облаке AWSАутентификация в Golang
Сетевые протоколы в GoПеременные в GolangЗначения в GolangДженерик %T и его применение в GolangТипы данных в GolangИспользование tls в GolangИспользование tag в структурах GolangSwitch в GoСтроки в GolangРабота с потоками (stream) в GolangSelect в GoРуны в GoРабота с пакетом params в GolangКонвертация строк в числа в GolangNull, Nil, None, 0 в GoНаименования переменных, функций и структур в GoInt в GolangУстановка GolangЧтение и установка HTTP заголовков в GolangMethods в GolangGoLand — IDE для разработки на Golang от JetBrainsОбработка «not found» в GolangFloat в GolangФлаги командной строки в Go (Golang)Запуск внешних команд в GolangОбработка ошибок в GoИспользование defer в GolangЗначения default в GolangГенерация кода в GoФорматирование кода в GolangЧистая архитектура в GolangКаналы (channels) в GolangПолучение body из HTTP запроса в Golang
Открыть базу знаний