Sobes.tech
Назад к вопросам
Middle+
5

Как реализовать graceful shutdown Go-сервиса в Kubernetes при деплое новой версии?

Компании, где спрашивали
Ozon ФинтехOzon Финтех

Ответ от нейросети

sobes.tech AI

Для реализации graceful shutdown Go-сервиса в Kubernetes при деплое новой версии нужно корректно обработать сигнал завершения и дать сервису время завершить текущие операции.

Основные шаги:

  1. Обработка сигнала SIGTERM

В Go-приложении нужно слушать системный сигнал SIGTERM, который Kubernetes посылает перед остановкой контейнера.

import (
    "os"
    "os/signal"
    "syscall"
    "context"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGTERM, syscall.SIGINT)

    go func() {
        <-sigs
        cancel() // сигнализируем о завершении
    }()

    // Запускаем основную работу с ctx
    run(ctx)
}
  1. Завершение работы с учетом контекста

В функции run или в обработчиках нужно проверять ctx.Done() и корректно завершать обработку, например, закрывать соединения, завершать горутины.

  1. Настройка Kubernetes
  • Убедиться, что в Deployment задано terminationGracePeriodSeconds — время, которое Kubernetes даст поду для завершения.
  • При получении SIGTERM Kubernetes ждет указанное время, прежде чем убить контейнер.
  1. Пример
func run(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            // очистка ресурсов
            return
        default:
            // основная логика
        }
    }
}

Таким образом, сервис корректно завершит работу, не прерывая важные операции, что особенно важно при обновлениях в Kubernetes.