Введение: почему 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 — исклю