Деплой Go приложения на Kubernetes: пошаговое руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: почему Go и Kubernetes — идеальная пара

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

В этом руководстве мы на практике разберем полный цикл деплоя простого Go-приложения на Kubernetes. Вы узнаете, как написать Dockerfile, создать манифесты для Kubernetes (Deployment, Service, ConfigMap) и запустить приложение в кластере. Все примеры кода можно сразу использовать в своих проектах.

1. Подготовка Go-приложения для контейнеризации

Для начала создадим простое HTTP-сервер на Go, которое будет отвечать на запросы и выводить приветствие. Важно, чтобы приложение слушало порт, который мы укажем через переменную окружения. Это стандартная практика для Kubernetes.

Создайте файл main.go:

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
)

func main() {
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        name := os.Getenv("APP_NAME")
        if name == "" {
            name = "Go App"
        }
        fmt.Fprintf(w, "Привет от %s! Работаем на порту %s", name, port)
    })

    log.Printf("Сервер запущен на порту %s", port)
    log.Fatal(http.ListenAndServe(":"+port, nil))
}

Этот код читает переменные окружения PORT и APP_NAME, что позволит нам гибко настраивать приложение через ConfigMap в Kubernetes.

2. Создание Dockerfile для Go-приложения

Для деплоя на Kubernetes нам нужен Docker-образ. Используем многоступенчатую сборку (multi-stage build) — это уменьшит размер образа и повысит безопасность.

Создайте файл Dockerfile:

# Этап сборки
FROM golang:1.22-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .

# Финальный образ
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]

Соберите образ и отправьте его в реестр (например, Docker Hub):

docker build -t yourusername/go-k8s-app:latest .
docker push yourusername/go-k8s-app:latest

3. Манифесты Kubernetes: Deployment, Service, ConfigMap

Теперь создадим манифесты для развертывания приложения в кластере. Рекомендуется хранить их в папке k8s/.

3.1. ConfigMap для конфигурации

Вынесем настройки приложения в ConfigMap — это позволит менять их без пересборки образа.

Файл k8s/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: go-app-config
data:
  APP_NAME: "Мое Go-приложение"
  PORT: "8080"

3.2. Deployment — описание пода

Deployment управляет репликами пода и обеспечивает обновления без downtime.

Файл k8s/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-app-deployment
  labels:
    app: go-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: go-app
  template:
    metadata:
      labels:
        app: go-app
    spec:
      containers:
      - name: go-app
        image: yourusername/go-k8s-app:latest
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: go-app-config
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 5

Важно: мы добавили livenessProbe и readinessProbe — Kubernetes будет проверять здоровье приложения и перезапускать под при сбоях. Проблемы используют HTTP GET запрос к корневому пути.

3.3. Service — точка доступа к приложению

Service обеспечивает стабильный IP и DNS-имя для доступа к подам.

Файл k8s/service.yaml:

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

Тип LoadBalancer создаст внешний балансировщик (если ваш кластер поддерживает это, например, в облаке). Для локального тестирования можно использовать NodePort.

4. Деплой и проверка приложения

Примените все манифесты к вашему кластеру (убедитесь, что kubectl настроен):

kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml

Проверьте статус подов:

kubectl get pods
kubectl get svc go-app-service

Если вы используете minikube, получите доступ к приложению командой:

minikube service go-app-service

В браузере откроется страница с приветствием. Для проверки работы ConfigMap измените значение APP_NAME в configmap.yaml и примените его снова — приложение обновится без перезапуска (если используете watch-механизм или просто перезагрузите страницу после перезапуска подов).

Заключение: лучшие практики и дальнейшие шаги

Мы разобрали базовый, но полностью рабочий процесс деплоя Go-приложения на Kubernetes. Вот несколько советов для продакшн-среды:

  • Используйте .dockerignore — исклю

Блоги

Рекомендаций по книгам