Если ты хоть раз администрировал кластеры Kubernetes в закрытых корпоративных сетях или изолированных контурах (air-gapped), то наверняка знаешь эту боль: рабочим нодам категорически запрещен прямой выход в публичные реестры вроде Docker Hub или GitHub Packages. Политики безопасности требуют, чтобы все контейнерные образы хранились исключительно во внутренних доверенных репозиториях компании — в локальном Harbor, AWS ECR или Nexus.
Обычно эту задачу решают по старинке: пишут громоздкие скрипты на bash в CI/CD пайплайнах, настраивают хрупкие крон-джобы на сервере сборки или пытаются включить облачные pull-through кэши, которые работают только внутри одного конкретного провайдера. Но стоит упасть раннеру или обновиться токену авторизации — и вся доставка артефактов встаёт колом.
Решить эту проблему нативно призван новый открытый Kubernetes-оператор Portager версии v0.5.0. Он переносит логику синхронизации прямо в Control Plane кластера, превращая зеркалирование образов в прозрачный GitOps-процесс.
Анатомия оператора: CRD ImageSync и реконсиляция по расписанию
Название проекта отсылает к историческому термину portage (волок) — практике переноса судов и грузов по суше между реками. В мире контейнеров оператор переносит OCI-артефакты между изолированными реестрами.
Вместо спагетти-скриптов инженеры описывают желаемое состояние через кастомный ресурс (Custom Resource Definition) ImageSync. Контроллер оператора работает по заданному cron-расписанию (например, каждые 6 часов) или реагирует на ручные триггеры через аннотации:
- Проверка манифестов без скачивания слоёв: контроллер отправляет легковесный HTTP-запрос
HEADв исходный и целевой реестры и сверяет SHA256-дайджесты манифестов. Если дайджесты совпадают, слои образа даже не скачиваются по сети. - Динамическая фильтрация тегов по SemVer: вместо жесткой фиксации каждого патча (
1.27.1,1.27.2) оператор поддерживает диапазоны версий вида~1.27.0или^22.0.0, автоматически подтягивая свежие обновления безопасности. - Автосоздание репозиториев (
createDestinationRepos: true): при синхронизации в AWS ECR или Harbor оператор сам создает целевой репозиторий при его отсутствии, предотвращая ошибки отклонения push.
Все события транслируются в стандартную ленту Kubernetes Events (kubectl describe imagesync), что позволяет мониторить статус зеркалирования без копания в чужих пайплайнах.
Практическая настройка: от Helm-чарта до AWS ECR
Установка оператора в кластер выполняется буквально за пару минут с помощью официального Helm-чарта, опубликованного в открытом OCI-реестре GitHub:
# Установка оператора Portager v0.5.0 из официального OCI-реестра
helm install portager oci://ghcr.io/jarodr47/portager/charts/portager \
--version 0.5.0 \
--namespace portager-system \
--create-namespace
# Проверка готовности пода контроллера
kubectl get pods -n portager-system -l app.kubernetes.io/name=portager
После старта контроллера создаем декларативный манифест синхронизации базовых системных образов:
apiVersion: portager.portager.io/v1alpha1
kind: ImageSync
metadata:
name: corporate-base-images
namespace: default
spec:
schedule: "@every 6h"
source:
registry: docker.io/library
destination:
registry: 123456789012.dkr.ecr.us-east-1.amazonaws.com
auth:
method: ecr
repositoryPrefix: mirror
createDestinationRepos: true
images:
- name: alpine
tags: ["3.21", "latest"]
- name: nginx
tags: ["latest"]
semver: "~1.27.0"
Применяем ресурс командой kubectl apply -f base-images.yaml. В секции событий describe ты сразу увидишь фазы выполнения: RepoEnsured (целевой репозиторий проверен в ECR), ImageSynced (слои успешно скопированы) и SyncComplete (итоговый отчет о переносе).
Безопасность цепочки поставок и ограничения в продакшене
Главное преимущество запуска прямо в Kubernetes — интеграция с корпоративными политиками безопасности. Для авторизации в приватных реестрах можно использовать стандартные секреты kubernetes.io/dockerconfigjson, а в облаке AWS — привязывать права через IAM Roles for Service Accounts (IRSA) без использования статических паролей.
Кроме того, Portager поддерживает проверку криптографических подписей Cosign перед зеркалированием. Это отлично дополняет практики, о которых мы говорили в материале по контролю целостности образов в Kubernetes через Cosign и Kyverno: образ не просто копируется, а гарантированно верифицируется до попадания в закрытый контур.
Но помни об ограничениях: проект находится в версии v0.5.0 с альфа-версией API v1alpha1. При первой синхронизации десятков тяжелых образов потребуется достаточная пропускная способность сети. А если ты тянешь образы с Docker Hub анонимно, частый cron-опрос быстро упрется в лимиты запросов (rate limits), поэтому авторизационный секрет обязателен.
Для небольших и средних команд Portager закрывает многолетнюю дыру в инфраструктурном тулинге, избавляя от самописных батников и делая доставку образов предсказуемой.
