Зачем это нужно
Пайплайн без секретов редок: пароль registry, API-ключ облака, токен Git. Одна строка password = "sk-123" в Jenkinsfile — инцидент безопасности и учебный провал. Второй навык — диагностика: Jenkins красный в половине случаев из-за окружения, а не из-за кода. Умение читать лог stage и чинить типовые сбои экономит часы всей команде.
Основные идеи
Credentials в Jenkins. Секреты хранят в Credentials Store (глобально или на folder). В pipeline — только ID, не значение:
withCredentials([ string(credentialsId: 'minio-access-key', variable: 'MINIO_KEY') ]) { sh 'python upload.py --key "$MINIO_KEY"' }
Типы: Username/Password, Secret text, SSH key, Secret file. Jenkins маскирует секреты в логах (но осторожно с set +x и echo).
Не секреты в Git. Запрещено: .env с паролями в repo, ARG REGISTRY_PASSWORD в Dockerfile, base64 «для obscurity». Правильно: .env.example без значений; runtime — Kubernetes Secret или Jenkins credentials.
Binding в Docker login. Пароль в stdin, не в командной строке (иначе виден в ps):
sh 'echo "$REG_PASS" | docker login registry -u "$REG_USER" --password-stdin'
Типичные отказы и что проверять
| Симптом | Частая причина |
|---|---|
docker: not found |
Docker не установлен на agent или нет label |
permission denied при docker |
User agent не в группе docker |
unauthorized: authentication required |
Неверный credentialsId или истёк токен |
pytest: command not found |
Зависимости не установлены в stage до test |
| Flaky test | Гонка, зависимость от сети, время |
| Out of disk | Нет cleanWs(), копятся слои Docker |
| Timeout | Обучение модели в CI без GPU — вынести в nightly |
Flaky builds. Нестабильный пайплайн подрывает доверие. Фиксируйте: seed для тестов, mock внешних API, retry только там, где оправдано (network blip), не для падающих assert.
Безопасность ML-артефактов. Registry credentials дают push; отдельные read-only credentials — для pull в k8s (imagePullSecrets). Модель не должна утекать через публичный лог (не печатайте содержимое Secret).
Отказоустойчивость процесса. CI упал — PR не мержим. CD (Helm/Argo) не обновляет prod, если новый образ не собран. Явная связь: нет зелёного CI → нет нового тега → нет деплоя.
Как это выглядит на практике
Сценарий 1: push падает с 401.
Открыть лог stage Push.
Проверить credentialsId в Jenkins (Manage Credentials).
Перевыпустить token в registry, обновить secret в Jenkins.
Rebuild без изменения кода.
Сценарий 2: «работало вчера».
Compare: обновился ли базовый образ
python:3.11-slim?Зафиксировать digest базового образа в Dockerfile или lockfile.
Добавить
--pullтолько по расписанию, не на каждый PR.
Сценарий 3: секрет попал в Git (учебный fire-drill).
Немедленно rotate credential.
Удалить из истории git (BFG / git filter-repo) — с помощью преподавателя.
Включить pre-commit hook или scanning (gitleaks) — тема смежная.
Postmortem в Confluence: что сломалось, как обнаружили, как предотвратить — навык из блока 1.
Что сделать после занятия
Перенесите все секреты из скриптов в Jenkins Credentials; проверьте, что в логе они замаскированы.
Создайте таблицу «5 типовых ошибок CI» для вашего проекта с симптомом и fix.
Намеренно сломайте пайплайн (неверный credentialsId) и восстановите по логу — тренировка on-call.