CGo
Тема дорожной карты · Golang
cgo — механизм Go, позволяющий Go-пакетам вызывать код на C, что открывает возможность повторно использовать существующие C-библиотеки и работать с API операционной системы или оборудования, не имеющими эквивалента на чистом Go. Импортируя специальный псевдопакет "C" и размещая исходный код C в блоке комментариев непосредственно над ним (так называемая преамбула cgo), разработчики могут вызывать функции C, работать с типами C вроде C.int и C.char и даже передавать Go-значения через границу. cgo использует CGO_ENABLED=1 при go build; установка CGO_ENABLED=0 создаёт полностью статический бинарник без зависимости от C-рантайма, что рекомендуется для минимальных Docker-образов на базе scratch-контейнеров. Поскольку вызовы cgo пересекают границу между Go- и C-рантаймами, они несут накладные расходы по сравнению с чистым Go-вызовом и могут усложнить кросс-компиляцию — GOOS и GOARCH должны соответствовать C-тулчейну для целевой платформы. Используйте cgo осознанно: при наличии чистых Go-библиотек предпочитайте их, а cgo-код оборачивайте в тонкий, хорошо протестированный пакет.
Как это работает
CGo знаменито прост: go build создаёт один статический бинарь, запускаемый на любом хосте с тем же OS+arch. Кросс-компиляция через GOOS=linux GOARCH=amd64 go build. Контейнеризуйте бинарь через FROM scratch или FROM gcr.io/distroless/static (несколько МБ total). go build -ldflags="-s -w" — для удаления debug-символов (меньше бинарь). Health-эндпойнты: /healthz, /readyz. Graceful shutdown через http.Server.Shutdown(ctx).
Когда применять
Multi-stage Dockerfile: builder-образ гонит go build; runner — scratch или distroless с одним бинарём + CA-сертификатами. Всегда graceful SIGTERM — drain in-flight запросы до выхода. Версию встраивайте через -ldflags "-X main.Version=$(git describe)" для вывода myapp version. Запуск под non-root, read-only ФС, минимальные capabilities.
Типичные ошибки
Ловушки CGo: FROM alpine, но компиляция против glibc (CGO_ENABLED=1 + alpine = мистические крэши — используйте CGO_ENABLED=0); нет CA-сертификатов в scratch-образах (TLS валится x509-ошибками — добавьте ca-certificates); нет graceful shutdown (k8s rolling-деплои дропают in-flight запросы); огромные бинари из-за забытых -w -s-флагов.