# yandex-dns-controller CronJob-контроллер для управления DNS-записями Yandex 360. **Safe mode**: управляет только записями с `managed: true`. Все остальные записи игнорируются — никогда не изменяются и не удаляются. ## Принцип работы ``` ConfigMap (zones.yaml) ↓ CronJob (*/5 мин) ↓ controller.py ↓ Yandex 360 DNS API ``` ### Модель управления | Запись | Поведение | |---|---| | `managed: true` в ConfigMap | Контроллер добавляет, обновляет, и при полном удалении из конфига — удаляет | | `managed: false` в ConfigMap | Документация только, контроллер не трогает | | Отсутствует в ConfigMap | Игнорируется полностью, никогда не удаляется | ### Логика удаления (очень важно) Запись удаляется из DNS **только при одновременном выполнении двух условий**: 1. Запись была создана этим контроллером (есть в state) 2. Запись **полностью удалена** из ConfigMap (не просто переключена в `managed: false`) Если запись переключается из `managed: true` → `managed: false`, контроллер **перестаёт её отслеживать, но не удаляет** из DNS. ### State ConfigMap Контроллер хранит состояние в ConfigMap `yandex-dns-controller-state`. Это позволяет безопасно удалять записи которые были удалены из конфига. ```bash # Просмотр текущего состояния kubectl -n yandex-dns-controller get cm yandex-dns-controller-state \ -o jsonpath='{.data.state\.json}' | jq . ``` ## Быстрый старт ### 1. Настроить credentials ```yaml # group_vars/all/vault.yml (зашифровать через ansible-vault) yandex_dns: org_id: "2312056" # https://admin.yandex.ru/company-profile token: "y0_Agk..." # https://oauth.yandex.ru/ (scope: DNS) ``` Как получить токен: 1. Создай приложение на https://oauth.yandex.ru/ 2. Доступ: **Управление записями DNS** 3. Открой в браузере: `https://oauth.yandex.ru/authorize?response_type=token&client_id={CLIENT_ID}` 4. Скопируй `access_token` со страницы ### 2. Настроить зоны ```yaml # group_vars/all/addons.yml addon_yandex_dns_controller: true yandex_dns_controller_zones: domains: - name: antropoff.ru # 🔐 СИСТЕМНЫЕ — не трогаем (managed: false — только документация) systemRecords: - name: "@" type: MX ttl: 21600 value: "mx.yandex.net." priority: 10 managed: false - name: "@" type: TXT ttl: 21600 value: "v=spf1 redirect=_spf.yandex.net" managed: false - name: "mail" type: CNAME ttl: 21600 value: "domain.mail.yandex.net." managed: false # 🌐 ОСНОВНЫЕ A-записи — не трогаем coreRecords: - name: "@" type: A ttl: 3600 value: "217.150.201.203" managed: false # 🧩 СЕРВИСЫ — не трогаем serviceRecords: - name: "git" type: CNAME ttl: 3600 value: "antropoff.ru." managed: false # ...остальные CNAME... # ✅ УПРАВЛЯЕМ КОНТРОЛЛЕРОМ - name: "k8s-test" type: CNAME ttl: 300 value: "antropoff.ru." managed: true # Записи которыми управляет K3S кластер records: - name: k8s-ingress type: A ttl: 300 value: "192.168.1.100" # kube-vip VIP managed: true ``` ### 3. Развернуть ```bash make addon-yandex-dns-controller ``` ## Конфигурация | Переменная | По умолчанию | Описание | |---|---|---| | `yandex_dns_controller_namespace` | `yandex-dns-controller` | Namespace | | `yandex_dns_controller_schedule` | `*/5 * * * *` | Расписание CronJob | | `yandex_dns_controller_dry_run` | `false` | Dry-run (не вносить изменения) | | `yandex_dns_controller_image` | `python:3.11-slim` | Docker образ | | `yandex_dns_controller_zones` | `{domains: []}` | Конфигурация зон | ## Поддерживаемые типы записей | Тип | Поле API | Пример value | |---|---|---| | `A` | `content` | `"192.168.1.1"` | | `AAAA` | `content` | `"::1"` | | `CNAME` | `target` | `"antropoff.ru."` | | `TXT` | `text` | `"v=spf1 ..."` | | `MX` | `exchange` + `preference` | `"mx.yandex.net."` + `priority: 10` | | `NS` | `target` | `"ns1.example.com."` | ## Dry-run режим Включить временно без изменения конфига: ```bash make addon-yandex-dns-controller ARGS="-e yandex_dns_controller_dry_run=true" ``` Или задать постоянно: ```yaml yandex_dns_controller_dry_run: true ``` В dry-run режиме контроллер показывает что бы он сделал, но не вносит изменений в DNS. ## Ручной запуск ```bash # Запустить немедленно kubectl create job --from=cronjob/yandex-dns-controller \ dns-manual-$(date +%s) -n yandex-dns-controller # Наблюдать за логами kubectl -n yandex-dns-controller logs \ -l app.kubernetes.io/name=yandex-dns-controller \ --tail=100 -f ``` ## Диагностика ```bash # Статус CronJob kubectl -n yandex-dns-controller get cronjob,jobs,pods # Логи последнего запуска kubectl -n yandex-dns-controller logs \ $(kubectl -n yandex-dns-controller get pods \ -l app.kubernetes.io/name=yandex-dns-controller \ --sort-by=.metadata.creationTimestamp -o name | tail -1) \ -c controller --tail=100 # Что контролируется (state) kubectl -n yandex-dns-controller get cm yandex-dns-controller-state \ -o jsonpath='{.data.state\.json}' | jq . # Просмотр текущего ConfigMap зон kubectl -n yandex-dns-controller get cm yandex-dns-zones -o yaml # Редактировать зоны вручную (без Ansible) kubectl -n yandex-dns-controller edit cm yandex-dns-zones ``` ## Обновление записей через GitOps Все изменения DNS делаются через `group_vars/all/addons.yml`: 1. Добавить/изменить запись в `yandex_dns_controller_zones` с `managed: true` 2. Закоммитить и запустить `make addon-yandex-dns-controller` 3. Контроллер подхватит изменение на следующем запуске CronJob ## Защита существующих записей Все записи с `managed: false` — это документация. Контроллер **никогда**: - Не создаёт их (даже если они отсутствуют в DNS) - Не обновляет (даже если value отличается) - Не удаляет Это гарантирует что MX-записи Яндекс.Почты, DKIM, SPF и другие критичные записи не будут затронуты. ## Официальные ресурсы - Официальный сайт: [https://360.yandex.ru/](https://360.yandex.ru/) - Официальная документация: [https://yandex.ru/dev/api360/doc/ru/ref/DnsService](https://yandex.ru/dev/api360/doc/ru/ref/DnsService) - Версии Helm chart / ПО: [https://oauth.yandex.ru/](https://oauth.yandex.ru/)