One place for hosting & domains

      развертывание

      Развертывание масштабируемого и защищенного приложения Django с помощью Kubernetes


      Введение

      В этом учебном модуле мы развернем контейнеризованное приложение Django polls в кластере Kubernetes.

      Django — это мощная веб-структура, позволяющая быстро развернуть ваше приложение Python с нуля. Она включает ряд удобных функций, в том числе реляционную карту объектов, аутентификацию пользователей и настраиваемый административный интерфейс для вашего приложения. Также она включает систему кэширования и помогает проектировать оптимизированные приложения с помощью диспетчера URL и системы шаблонов.

      В учебном модуле Создание приложения Django и Gunicorn с помощью Docker мы изменили приложение Polls из учебного модуля Django согласно методологии Двенадцать факторов, предназначенной для построения масштабируемых веб-приложений, оптимизированных для работы в облаке. Для масштабирования и защиты контейнера использовался обратный прокси-сервер Nginx и подписанный Let’s Encrypt сертификат TLS (см. описание в учебном модуле Масштабирование и защита приложения Django с помощью Docker, Nginx и Let’s Encrypt). В этом последнем учебном модуле из серии От контейнеров к Kubernetes с Django мы покажем, как развернуть модернизированное приложение Django polls в кластере Kubernetes.

      Kubernetes — мощная система оркестрации контейнеров с открытым исходным кодом, помогающая автоматизировать развертывание, масштабирование и управление контейнеризованными приложениями. Такие объекты Kubernetes как ConfigMaps и Secrets позволяют централизовать конфигурацию и отсоединить ее от контейнеров, а такие контроллеры как Deployments автоматически перезагружают неработающие контейнеры и позволяют быстро масштабировать реплики контейнеров. Шифрование TLS активируется с помощью объекта Ingress и контроллера ingress-nginx с открытым исходным кодом. Надстройка Kubernetes cert-manager проверяет и выпускает сертификаты, используя бесплатный центр сертификации Let’s Encrypt.

      Предварительные требования

      Для данного обучающего модуля вам потребуется следующее:

      • Кластер Kubernetes версии 1.15 или выше с включенным контролем доступа на основе ролей (RBAC). В нашем примере будет использоваться кластер DigitalOcean Kubernetes, но вы можете создать кластер с помощью другого метода.
      • Инструмент командной строки kubectl, установленный на локальном компьютере и настроенный для подключения к вашему кластеру. Дополнительную информацию об установке kubectl можно найти в официальной документации. Если вы используете кластер DigitalOcean Kubernetes, ознакомьтесь с руководством Подключение к кластеру DigitalOcean Kubernetes, чтобы узнать, как подключиться к кластеру с помощью kubectl.
      • Зарегистрированное доменное имя. В этом учебном модуле мы будем использовать имя your_domain.com. Вы можете получить бесплатный домен на Freenom или зарегистрировать доменное имя по вашему выбору.
      • Контроллер ingress-nginx и диспетчер сертификатов TLS cert-manager должны быть установлены в вашем кластере и настроены на использование сертификатов TLS. Чтобы узнать, как установить и настроить Ingress с помощью cert-manager, воспользуйтесь руководством Настройка Nginx Ingress с помощью Cert-Manager в кластере DigitalOcean Kubernetes.
      • Запись DNS A для your_domain.com, указывающая на публичный IP-адрес балансировщика нагрузки Ingress. Если вы используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.
      • Хранилище объектов S3, например пространство DigitalOcean, для хранения статических файлов проекта Django и набор ключей доступа к этому пространству. Чтобы узнать, как создать пространство, ознакомьтесь с документом Как создавать пространства. Чтобы узнать, как создать ключи доступа, ознакомьтесь со статьей Предоставление доступа к пространству с помощью ключей доступа. Внеся незначительные изменения, вы можете использовать любой сервис хранения, который поддерживает плагин django-storages.
      • Экземпляр сервера PostgreSQL, база данных и пользователь для приложения Django. Внеся незначительные изменения, вы можете использовать любую базу данных, которую поддерживает Django.
      • Учетная запись Docker Hub и публичный репозиторий. Более подробную информацию по их созданию можно найти в разделе Repositories (Репозитории) в документации по Docker.
      • Система Docker, установленная на локальном компьютере. Более подробную информацию можно найти в руководстве Установка и использование Docker в Ubuntu 18.04.

      Проверив наличие этих компонентов, вы можете начать прохождение этого обучающего модуля.

      Шаг 1 — Клонирование и настройка приложения

      На этом шаге мы клонируем код приложения с GitHub и настроим такие параметры, как учетные данные БД и ключи хранения объектов.

      Код приложения и файл Dockerfile можно найти в ветви polls-docker репозитория Django Tutorial Polls App на GitHub. Этот репозиторий содержит код приложения Polls, используемого в документации по Django в качестве образца, на примере которого показывается, как создать приложение для опросов с нуля.

      Ветвь polls-docker содержит размещенную в контейнере Docker версию приложения Polls. Более подробную информацию об изменениях, внесенных в приложение Polls для эффективной работы в контейнеризированной среде, можно найти в руководстве Создание приложения Django и Gunicorn с помощью Docker.

      Для начала используйте git, чтобы клонировать ветвь polls-docker репозитория Django Tutorial Polls App на GitHub на локальном компьютере:

      • git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

      Перейдите в каталог django-polls:

      В этом каталоге содержится код Python приложения Django, файл Dockerfile, который Docker будет использовать для построения образа контейнера, а также файл env, содержащий список переменных среды для передачи в рабочую среду контейнера. Проверьте файл Dockerfile:

      Output

      FROM python:3.7.4-alpine3.10 ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex && apk add --no-cache --virtual .build-deps postgresql-dev build-base && python -m venv /env && /env/bin/pip install --upgrade pip && /env/bin/pip install --no-cache-dir -r /app/requirements.txt && runDeps="$(scanelf --needed --nobanner --recursive /env | awk '{ gsub(/,/, "nso:", $2); print "so:" $2 }' | sort -u | xargs -r apk info --installed | sort -u)" && apk add --virtual rundeps $runDeps && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"]

      В качестве базы в файле Dockerfile используется официальный образ Docker Python 3.7.4, который устанавливает требуемые пакеты Python для Django и Gunicorn в соответствии с файлом django-polls/requirements.txt. Затем он удаляет некоторые ненужные файлы сборки, копирует код приложения в образ и устанавливает параметр выполнения PATH. И в заключение заявляет, что порт 8000 будет использоваться для принятия входящих подключений контейнера, и запускает gunicorn с тремя рабочими элементами, прослушивающими порт 8000.

      Дополнительную информацию о каждом этапе в Dockerfile см. в шаге 6 руководства Создание приложения Django и Gunicorn с помощью Docker.

      Теперь создайте образ с помощью docker build:

      Назовем образ polls, используя флаг -t, и передадим в текущий каталог как контекст сборки набор файлов для справки при построении образа.

      После того как Docker создаст и отметит образ, перечислите доступные образы, используя docker images:

      Вы должны увидеть образ polls:

      OutputREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
      polls               latest              80ec4f33aae1        2 weeks ago         197MB
      python              3.7.4-alpine3.10    f309434dea3a        8 months ago        98.7MB
      

      Перед запуском контейнера Django нам нужно настроить его рабочую среду с помощью файла env, присутствующего в текущем каталоге. Этот файл передается в команду docker run, которая используется для запуска контейнера, после чего Docker внедрит настроенные переменные среды в рабочую среду контейнера.

      Откройте файл env с помощью nano или своего любимого редактора:

      django-polls/env

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Заполните недостающие значения для следующих ключей:

      • DJANGO_SECRET_KEY: задает уникальное, непрогнозируемое значение, как описано в документации Django. Один метод генерирования этого ключа представлен в разделе Изменение настроек приложения руководства Масштабируемое приложение Django.
      • DJANGO_ALLOWED_HOSTS: эта переменная защищает приложение и предотвращает атаки через заголовки хоста HTTP. С целью тестирования установите * как подстановочный символ, подходящий для всех хостов. В производственной среде следует использовать значение your_domain.com. Дополнительную информацию об этой настройке Django см. в разделе Core Settings (Базовые настройки) документации Django.
      • DATABASE_USERNAME: задает пользователя базы данных PostgreSQL, созданного на предварительных этапах.
      • DATABASE_NAME: задает polls или имя базы данных, созданной на предварительных этапах.
      • DATABASE_PASSWORD: задает пароль пользователя базы данных PostgreSQL, созданного на предварительных этапах.
      • DATABASE_HOST: задает имя хоста базы данных.
      • DATABASE_PORT: укажите порт вашей базы данных.
      • STATIC_ACCESS_KEY_ID: укажите ключ доступа своего пространства или хранилища объектов.
      • STATIC_SECRET_KEY: укажите секретный ключ своего пространства или хранилища объектов.
      • STATIC_BUCKET_NAME: укажите имя своего пространства или корзину хранилища объектов.
      • STATIC_ENDPOINT_URL: укажите URL соответствующего пространства или конечного пункта хранилища объектов, например https://your_space_name.nyc3.digitaloceanspaces.com, если ваше пространство находится в области nyc3.

      После завершения редактирования сохраните и закройте файл.

      На следующем шаге мы запустим настроенный контейнер в локальной среде и создадим схему базы данных. Также мы выгрузим в хранилище объектов статические ресурсы, такие как таблицы стилей и изображения.

      Шаг 2 — Создание схемы базы данных и выгрузка ресурсов в хранилище объектов

      После построения и настройки контейнера используйте docker run, чтобы заменить заданную команду CMD в файле Dockerfile и создайте схему базы данных, используя команды manage.py makemigrations и manage.py migrate:

      • docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate"

      Мы запускаем образ контейнера polls:latest, передаем в только что измененный файл переменной среды и переопределяем команду Dockerfile с помощью sh -c "python manage.py makemigrations && python manage.py migrate", которая создаст схему базы данных, определяемую кодом приложения.

      Если запускаете эти команды впервые, вы должны увидеть следующее:

      Output

      No changes detected Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying polls.0001_initial... OK Applying sessions.0001_initial... OK

      Это означает, что схема базы данных успешно создана.

      При последующем запуске команды migrate Django не будет выполнять никаких операций, если схема базы данных не изменилась.

      Затем мы запустим еще один экземпляр контейнера приложения и используем внутри него интерактивную оболочку для создания административного пользователя проекта Django.

      • docker run -i -t --env-file env polls sh

      Вы получите строку оболочки внутри работающего контейнера, которую сможете использовать для создания пользователя Django:

      • python manage.py createsuperuser

      Введите имя пользователя, адрес электронной почты и пароль для пользователя, а после создания пользователя нажмите CTRL+D для выхода из контейнера и его удаления.

      В заключение мы создадим статические файлы приложения и загрузим их в пространство DigitalOcean с помощью collectstatic. Обратите внимание, что для завершения процесса может потребоваться время.

      • docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"

      После создания и загрузки файлов вы получите следующий вывод.

      Output

      121 static files copied.

      Теперь мы можем запустить приложение:

      • docker run --env-file env -p 80:8000 polls

      Output

      [2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0 [2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) [2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync [2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7 [2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8 [2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9

      Мы запустим определенную в Dockerfile команду по умолчанию gunicorn --bind :8000 --workers 3 mysite.wsgi:application и откроем порт контейнера 8000, чтобы установить соответствие порта 80 на локальном компьютере и порта 8000 контейнера polls.

      Теперь у вас должна появиться возможность открыть приложение polls в браузере, для чего нужно ввести http://localhost в адресную строку. Поскольку маршрут для пути / не определен, скорее всего, вы получите ошибку 404 Страница не найдена.

      Введите в адресную строку http://localhost/polls, чтобы увидеть интерфейс приложения Polls:

      Интерфейс приложения «Опросы»

      Чтобы открыть интерфейс администрирования, введите адрес http://localhost/admin. Вы должны увидеть окно аутентификации администратора приложения «Опросы»:

      Страница аутентификации администратора приложения

      Введите имя администратора и пароль, которые вы создали с помощью команды createsuperuser.

      После аутентификации вы сможете получить доступ к административному интерфейсу приложения «Опросы»:

      Основной интерфейс администратора приложения

      Обратите внимание, что статические активы приложений admin и polls поступают напрямую из хранилища объекта. Чтобы убедиться в этом, ознакомьтесь с материалами Тестирование доставки статических файлов пространства.

      После завершения изучения данных нажмите CTRL+C в окне терминала, где запущен контейнер Docker, чтобы удалить контейнер.

      Когда образ Docker приложения Django будет протестирован, статичные ресурсы будут выгружены в хранилище объектов, а схема базы данных будет настроена и готова к выгрузке образа приложения Django в реестр образов, например в Docker Hub.

      Шаг 3 — Размещение образа приложения Django в Docker Hub

      Чтобы развернуть приложение в Kubernetes, необходимо будет выгрузить образ приложения в реестр, например, в Docker Hub. Kubernetes извлечет образ приложения из репозитория, а затем развернет его в кластере.

      Вы можете использовать частный реестр Docker, например, реестр контейнеров DigitalOcean Container Registry, предварительная версия которого в настоящее время предоставляется бесплатно, или публичный реестр Docker, такой как Docker Hub. Docker Hub также позволяет создавать частные репозитории Docker. Публичный репозиторий позволяет любому пользователю видеть и извлекать образы контейнеров, а в частном репозитории доступ имеется только у вас и у членов вашей команды.

      В этом учебном модуле мы разместим образ Django в публичном репозитории Docker Hub, созданном на этапе предварительных требований. Также вы можете перенести образ в частный репозиторий, однако извлечение образов из частного репозитория в этой статье не описывается. Чтобы получить более подробную информацию об аутентификации Kubernetes с Docker Hub и извлечении образов из частного репозитория, ознакомьтесь со статьей Pull an Image from a Private Registry (Извлечение образа из частного реестра) в документации по Kubernetes.

      Для начала выполните вход в Docker Hub на локальном компьютере:

      Output

      Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username:

      Введите имя пользователя и пароль Docker Hub для входа в систему.

      Образ Django сейчас помечен тегом polls:latest. Чтобы поместить его в ваш репозиторий Docker Hub, измените теги образа, указав свое имя пользователя Docker Hub и имя репозитория:

      • docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest

      Разместите образ в репозитории:

      • docker push sammy/sammy-django:latest

      В этом учебном модуле мы используем имя пользователя Docker Hub sammy и имя репозитория sammy-django. Вам следует заменить эти значения своим именем пользователя Docker Hub и именем репозитория.

      По мере размещения слоев образа в Docker Hub вы будете видеть на экране определенные сообщения.

      Теперь ваш образ доступен Kubernetes в репозитории Docker Hub, и вы можете начать его развертывание в своем кластере.

      Шаг 4 — Настройка ConfigMap

      При локальном запуске контейнера Django мы передали файл env в docker run для вставки переменных конфигурации в среду исполнения. Для вставки переменных конфигурации в Kubernetes используются элементы ConfigMap и Secret.

      Элементы ConfigMap следует использовать для сохранения неконфиденциальной информации о конфигурации, такой как параметры приложения, а элементы Secret следует использовать для хранения важной информации, такой как ключи API и учетные данные для входа в базу данных. Они вставляются в контейнеры примерно одинаково, но у элементов Secret имеются дополнительные функции контроля доступа и безопасности, такие как шифрование в состоянии покоя. Элементы Secret хранят данные в формате base64, а элементы ConfigMap хранят данные в формате обычного текста.

      Для начала необходимо создать каталог yaml, где мы будем хранить наши манифесты Kubernetes. Перейдите в каталог.

      Откройте файл polls-configmap.yaml в nano или в другом предпочитаемом текстовом редакторе:

      • nano polls-configmap.yaml

      Вставьте в него следующий манифест ConfigMap:

      polls-configmap.yaml

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: polls-config
      data:
        DJANGO_ALLOWED_HOSTS: "*"
        STATIC_ENDPOINT_URL: "https://your_space_name.space_region.digitaloceanspaces.com"
        STATIC_BUCKET_NAME: "your_space_name"
        DJANGO_LOGLEVEL: "info"
        DEBUG: "True"
        DATABASE_ENGINE: "postgresql_psycopg2"
      

      Мы извлекли неконфиденциальные данные конфигурации из файла env, измененного на шаге 1, и передали их в манифест ConfigMap. Объект ConfigMap носит имя polls-config. Скопируйте те же самые значения, введенные в файл env на предыдущем шаге.

      Для тестирования оставьте для DJANGO_ALLOWED_HOSTS значение *, чтобы отключить фильтрацию на основе заголовков хоста. В производственной среде здесь следует указать домен вашего приложения.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Создайте в своем кластере элемент ConfigMap, используя kubectl apply:

      • kubectl apply -f polls-configmap.yaml

      Output

      configmap/polls-config created

      Мы создали элемент ConfigMap, а на следующем шаге мы создадим элемент Secret, который будет использоваться нашим приложением.

      Шаг 5 — Настройка элемента Secret

      Значения Secret должны иметь кодировку base64, то есть создавать объекты Secret в кластере немного сложнее, чем объекты ConfigMaps. Вы можете повторить описанную на предыдущем шаге процедуру, выполнив кодирование значений Secret в формате base64 вручную и вставив их в файл манифеста. Также вы можете создавать их, используя файл переменных среды, kubectl create и флаг --from-env-file, что мы и сделаем на этом шаге.

      Мы снова используем файл env из шага 1, удалив переменные, вставленные в ConfigMap. Создайте копию файла env с именем polls-secrets в каталоге yaml:

      • cp ../env ./polls-secrets

      Отредактируйте файл в предпочитаемом редакторе:

      polls-secrets

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Удалите все переменные, вставленные в манифест ConfigMap. Когда вы закончите, содержимое файла должно выглядеть следующим образом:

      polls-secrets

      DJANGO_SECRET_KEY=your_secret_key
      DATABASE_NAME=polls
      DATABASE_USERNAME=your_django_db_user
      DATABASE_PASSWORD=your_django_db_user_password
      DATABASE_HOST=your_db_host
      DATABASE_PORT=your_db_port
      STATIC_ACCESS_KEY_ID=your_space_access_key
      STATIC_SECRET_KEY=your_space_access_key_secret
      

      Обязательно используйте те же значения, что и на шаге 1. Закончив, сохраните и закройте файл.

      Создайте в кластере объект Secret, используя kubectl create secret:

      • kubectl create secret generic polls-secret --from-env-file=poll-secrets

      Output

      secret/polls-secret created

      Здесь мы создадим объект Secret с именем polls-secret и передадим в него созданный нами файл secrets.

      Вы можете проинспектировать объект Secret, используя kubectl describe:

      • kubectl describe secret polls-secret

      Output

      Name: polls-secret Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== DATABASE_PASSWORD: 8 bytes DATABASE_PORT: 5 bytes DATABASE_USERNAME: 5 bytes DJANGO_SECRET_KEY: 14 bytes STATIC_ACCESS_KEY_ID: 20 bytes STATIC_SECRET_KEY: 43 bytes DATABASE_HOST: 47 bytes DATABASE_NAME: 5 bytes

      Мы сохранили конфигурацию вашего приложения в кластере Kubernetes, используя типы объектов Secret и ConfigMap. Мы готовы развернуть приложение в кластере.

      Шаг 6 — Развертывание приложения Django с помощью контроллера Deployment

      На этом шаге мы создадим Deployment для вашего приложения Django. Kubernetes Deployment — контроллер, который можно использовать для управления приложениями без состояния в вашем кластере. Контроллер — это контур управления, регулирующий рабочие задачи посредством вертикального масштабирования. Контроллеры также перезапускают и очищают неисправные контейнеры.

      Контроллеры Deployment контролируют один или несколько подов. Под — это наименьшая развертываемая единица в кластере Kubernetes. Поды содержат один или несколько контейнеров. Чтобы узнать о различных типах рабочих задач, ознакомьтесь с учебным модулем Введение в Kubernetes.

      Для начала откройте файл polls-deployment.yaml в предпочитаемом текстовом редакторе:

      • nano polls-deployment.yaml

      Вставьте в него следующий манифест Deployment:

      polls-deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: polls-app
        labels:
          app: polls
      spec:
          replicas: 2
        selector:
          matchLabels:
            app: polls
        template:
          metadata:
            labels:
              app: polls
          spec:
            containers:
              - image: your_dockerhub_username/app_repo_name:latest
                name: polls
                envFrom:
                - secretRef:
                    name: polls-secret
                - configMapRef:
                    name: polls-config
                ports:
                  - containerPort: 8000
                    name: gunicorn
      

      Введите соответствующее имя образа контейнера, ссылаясь на образ Django Polls, который вы разместили в Docker Hub на шаге 2.

      Здесь мы определяем контроллер Kubernetes Deployment с именем polls-app и присваиваем ему пару ключ-значение app: polls. Мы указываем, что хотим запустить две реплики пода, определенного под полем template.

      Используя envFrom с secretRef и configMapRef, мы указываем, что все данные из объектов polls-secret и polls-config следует вставить в контейнеры как переменные среды. Ключи ConfigMap и Secret становятся именами переменных среды.

      В заключение мы откроем порт containerPort 8000 и назовем его gunicorn.

      Чтобы узнать больше о настройке контроллеров Kubernetes Deployment, ознакомьтесь с разделом Deployments в документации по Kubernetes.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Создайте в кластере контроллер Deployment, используя kubectl apply -f:

      • kubectl apply -f polls-deployment.yaml
      • deployment.apps/polls-app created

      Убедитесь, что контроллер Deployment развернут правильно, используя kubectl get:

      • kubectl get deploy polls-app

      Output

      NAME READY UP-TO-DATE AVAILABLE AGE polls-app 2/2 2 2 6m38s

      Если вы столкнетесь с ошибкой или что-то не будет работать, вы можете использовать kubectl describe для проверки неработающего контроллера Deployment:

      Чтобы проинспектировать два пода, используйте kubectl get pod:

      Output

      NAME READY STATUS RESTARTS AGE polls-app-847f8ccbf4-2stf7 1/1 Running 0 6m42s polls-app-847f8ccbf4-tqpwm 1/1 Running 0 6m57s

      В кластеры запущены и работают две реплики вашего приложения Django. Чтобы получить доступ к приложению, вам нужно создать Kubernetes Service, и мы сделаем это на следующем шаге.

      Шаг 7 — Предоставление внешнего доступа с использованием Service

      На этом шаге мы создаем Service для нашего приложения Django. Kubernetes Service — это абстракция, позволяющая предоставить доступ к набору работающих подов как к сетевой службе. Используя Service, вы можете создать для вашего приложения стабильный конечный пункт, который не будет изменяться по мере уничтожения и воссоздания подов.

      Существует несколько типов служб Service, в том числе службы ClusterIP, открывающие доступ к Service через внутренний IP-адрес кластера, службы NodePort, открывающие доступ к Service на каждом узле статического порта NodePort, и службы LoadBalancer, предоставляющие облачный балансировщик нагрузки для управления внешним трафиком подов вашего кластера (через порты NodePort, которые он создает автоматически). Чтобы узнать больше об этом, ознакомьтесь с разделом Service в документации по Kubernetes.

      На заключительном шаге настройки мы используем службу ClusterIP Service, доступ к которой открыт через Ingress и контроллер Ingress, настроенный на этапе подготовки к этому учебному модулю. Сейчас мы убедимся, что все элементы работают корректно. Для этого мы создадим временную службу NodePort Service для доступа к приложению Django.

      Для начала создайте файл с именем polls-svc.yaml в предпочитаемом редакторе:

      Вставьте в него следующий манифест Service:

      polls-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: polls
        labels:
          app: polls
      spec:
        type: NodePort
        selector:
          app: polls
        ports:
          - port: 8000
            targetPort: 8000
      

      Здесь мы создаем службу NodePort под названием polls и присваиваем ей ярлык app: polls. Мы выберем поды серверной части с ярлыком app: polls и установим в качестве цели порты 8000.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Разверните Service с помощью команды kubectl apply:

      • kubectl apply -f polls-svc.yaml

      Output

      service/polls created

      Убедитесь, что служба была создана с использованием kubectl get svc:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls NodePort 10.245.197.189 <none> 8000:32654/TCP 59s

      Этот вывод показывает внутренний IP-адрес кластера службы и номер порта NodePort (32654). Чтобы подключиться к службе, нам потребуется внешний IP-адрес для нашего узла кластера:

      Output

      NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME pool-7no0qd9e0-364fd Ready <none> 27h v1.18.8 10.118.0.5 203.0.113.1 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fi Ready <none> 27h v1.18.8 10.118.0.4 203.0.113.2 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fv Ready <none> 27h v1.18.8 10.118.0.3 203.0.113.3 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9

      Откройте в браузере приложение Polls, используя внешний IP-адрес и порт NodePort любого узла. С учетом приведенного выше вывода URL приложения будет выглядеть так: http://203.0.113.1:32654/polls.

      Вы должны увидеть тот же интерфейс приложения Polls, который вы открыли локально на шаге 1:

      Интерфейс приложения «Опросы»

      Вы можете повторить ту же проверку, используя маршрут /admin: http://203.0.113.1:32654/admin. Вы увидите тот же интерфейс администрирования, что и раньше:

      Страница аутентификации администратора приложения

      Мы развернули две реплики контейнера приложения Django Polls, используя Deployment. Также мы создали стабильный конечный пункт сети для этих двух реплик и обеспечили внешний доступ к ним через службу NodePort.

      Заключительный шаг этого учебного модуля заключается в том, чтобы защитить внешний трафик нашего приложения, используя HTTPS. Для этого мы используем контроллер ingress-nginx, установленный на этапе предварительных требований, и создадим объект Ingress для перенаправления внешнего трафика в службу Kubernetes polls.

      Шаг 8 — Настройка HTTPS с использованием Nginx Ingress и cert-manager

      Сущности Ingress в Kubernetes обеспечивают гибкую маршрутизацию внешнего трафика кластера Kubernetes среди служб внутри кластера. Это достигается с помощью ресурсов Ingress, которые определяют правила маршрутизации трафика HTTP и HTTPS для служб Kubernetes, и контроллеров Ingress, которые реализуют правила посредством балансировки нагрузки трафика и его перенаправления на соответствующие службы серверной части.

      На этапе предварительных требований мы установили контроллер ingress-nginx и надстройку cert-manager для автоматизации сертификатов TLS. Также мы настроили испытательную и производственную среду ClusterIssuers для вашего домена, используя центр сертификации Let’s Encrypt, и создали объект Ingress для проверки выдачи сертификатов и шифрования TLS для двух фиктивных серверных служб. Прежде чем продолжить выполнение этого шага, удалите объект echo-ingress, созданный в подготовительном учебном модуле:

      • kubectl delete ingress echo-ingress

      При желании вы также можете удалить фиктивные службы и развертывания, используя команды kubectl delete svc и kubectl delete deploy, но для прохождения этого учебного модуля это не обязательно.

      Также вы должны были создать запись DNS типа A для your_domain.com, указывающую на публичный IP-адрес балансировщика нагрузки Ingress. Если вы используете балансировщик нагрузки DigitalOcean, вы можете найти этот IP-адрес в разделе Load Balancers панели управления. Если вы также используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.

      Если вы используете DigitalOcean Kubernetes, убедитесь, что вы внедрили обходное решение, описанное в шаге 5 учебного модуля Настройка Nginx Ingress с помощью Cert-Manager в DigitalOcean Kubernetes.

      Когда у вас будет запись A, указывающая на балансировщик нагрузки контроллера Ingress, вы можете создать Ingress для your_domain.com и службы polls.

      Откройте файл с именем polls-ingress.yaml в предпочитаемом текстовом редакторе:

      Вставьте следующий манифест Ingress:

      [polls-ingress.yaml]
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: polls-ingress
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: "letsencrypt-staging"
      spec:
        tls:
        - hosts:
          - your_domain.com
          secretName: polls-tls
        rules:
        - host: your_domain.com
          http:
            paths:
            - backend:
                serviceName: polls
                servicePort: 8000
      

      Мы создаем объект Ingress под именем polls-ingress и добавляем к нему аннотацию, чтобы уровень управления использовал контроллер ingress-nginx и размещение ClusterIssuer. Также мы включаем TLS для домена your_domain.com и сохраняем сертификат и закрытый ключ в объекте Secret с именем polls-tls. В заключение мы определяем правило перенаправления трафика для хоста your_domain.com в службу polls через порт 8000.

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Создайте в кластере объект Ingress, используя kubectl apply:

      • kubectl apply -f polls-ingress.yaml

      Output

      ingress.networking.k8s.io/polls-ingress created

      Вы можете использовать kubectl describe для отслеживания состояния только что созданного объекта Ingress:

      • kubectl describe ingress polls-ingress

      Output

      Name: polls-ingress Namespace: default Address: workaround.your_domain.com Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) TLS: polls-tls terminates your_domain.com Rules: Host Path Backends ---- ---- -------- your_domain.com polls:8000 (10.244.0.207:8000,10.244.0.53:8000) Annotations: cert-manager.io/cluster-issuer: letsencrypt-staging kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 51s nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 51s cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 25s nginx-ingress-controller Ingress default/polls-ingress

      Также вы можете запустить команду describe для сертификата polls-tls, чтобы убедиться, что он был успешно создан:

      • kubectl describe certificate polls-tls

      Output

      . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 3m33s cert-manager Issuing certificate as Secret does not exist Normal Generated 3m32s cert-manager Stored new private key in temporary Secret resource "polls-tls-v9lv9" Normal Requested 3m32s cert-manager Created new CertificateRequest resource "polls-tls-drx9c" Normal Issuing 2m58s cert-manager The certificate has been successfully issued

      Это подтверждает, что сертификат TLS успешно выдан, и шифрование HTTPS для домена your_domain.com активно.

      Поскольку мы использовали тестовую версию ClusterIssuer, большинство браузеров не будут доверять поддельному сертификату Let’s Encrypt, который она выдает, и поэтому при переходе по адресу your_domain.com появится страница с сообщением об ошибке.

      Чтобы отправить тестовый запрос, мы используем wget из командной строки:

      • wget -O - http://your_domain.com/polls

      Output

      . . . ERROR: cannot verify your_domain.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to your_domain.com insecurely, use `--no-check-certificate'.

      Мы используем предлагаемый флаг --no-check-certificate, чтобы пропустить проверку сертификата:

      • wget --no-check-certificate -q -O - http://your_domain.com/polls

      Output

      <link rel="stylesheet" type="text/css" href="https://your_space.nyc3.digitaloceanspaces.com/django-polls/static/polls/style.css"> <p>No polls are available.</p>

      В этом выводе показан код HTML для страницы интерфейса /polls, а также подтверждается выдача таблицы стилей из хранилища объектов.

      Мы успешно проверили выдачу сертификата с помощью тестовой версии ClusterIssuer и теперь можем изменить Ingress для использования производственной версии ClusterIssuer.

      Снова откройте файл polls-ingress.yaml для редактирования:

      Измените аннотацию cluster-issuer:

      [polls-ingress.yaml]
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: polls-ingress
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: "letsencrypt-prod"
      spec:
        tls:
        - hosts:
          - your_domain.com
          secretName: polls-tls
        rules:
        - host: your_domain.com
          http:
            paths:
            - backend:
                serviceName: polls
                servicePort: 8000
      

      Внесите необходимые изменения, после чего сохраните и закройте файл. Обновите Ingress, используя kubectl apply:

      • kubectl apply -f polls-ingress.yaml

      Output

      ingress.networking.k8s.io/polls-ingress configured

      Вы можете использовать команды kubectl describe certificate polls-tls и kubectl describe ingress polls-ingress для отслеживания статуса выдачи сертификата:

      • kubectl describe ingress polls-ingress

      Output

      . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 23m nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 23m cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 76s (x2 over 22m) nginx-ingress-controller Ingress default/polls-ingress Normal UpdateCertificate 76s cert-manager Successfully updated Certificate "polls-tls"

      Приведенный выше вывод подтверждает, что новый производственный сертификат успешно выдан и сохранен в объекте Secret polls-tls.

      Откройте в браузере адрес your_domain.com/polls, чтобы убедиться, что шифрование HTTPS включено, и все работает ожидаемым образом. Вы должны увидеть интерфейс приложения Polls:

      Интерфейс приложения «Опросы»

      Убедитесь, что в браузере включено шифрование HTTPS. Если вы используете Google Chrome, то если вышеуказанная страница откроется без ошибок, это будет означать, что все работает правильно. Кроме того, на панели URL должно быть изображение замка. Нажав на замок, вы сможете просмотреть детали сертификата Let’s Encrypt.

      Для окончательной очистки вы можете переключить тип службы polls с NodePort на внутренний тип ClusterIP.

      Отредактируйте файл polls-svc.yaml в текстовом редакторе:

      Измените type с NodePort на ClusterIP:

      polls-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: polls
        labels:
          app: polls
      spec:
        type: ClusterIP
        selector:
          app: polls
        ports:
          - port: 8000
            targetPort: 8000
      

      Когда вы завершите редактирование файла, сохраните и закройте его.

      Разверните изменения с помощью команды kubectl apply:

      • kubectl apply -f polls-svc.yaml --force

      Output

      service/polls configured

      Убедитесь, что служба Service была изменена, используя kubectl get svc:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls ClusterIP 10.245.203.186 <none> 8000/TCP 22s

      Этот вывод показывает, что тип Service — ClusterIP. Для доступа можно использовать только домен и Ingress, созданный на этом шаге.

      Заключение

      В этом учебном модуле мы развернули масштабируемое приложение Django с защитой HTTPS в кластере Kubernetes. Статичный контент выдается напрямую из хранилища объектов, а количество работающих подов можно быстро увеличивать или уменьшать, используя поле replicas в манифесте Deployment polls-app.

      Если вы используете пространство DigitalOcean Space, вы также можете включить доставку статичных ресурсов через сеть доставки контента и создать настраиваемый субдомен для своего пространства. Дополнительную информацию можно найти в разделе Включение CDN учебного модуля Настройка масштабируемого приложения Django с управляемыми базами данных и пространствами DigitalOcean.

      С остальными частями серии можно ознакомиться на странице От контейнеров к Kubernetes с Django.



      Source link

      Развертывание Laravel 7 и MySQL в Kubernetes с помощью Helm


      Автор выбрал Diversity in Tech Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Laravel — одна из самых популярных в настоящее время инфраструктур приложений PHP с открытым исходным кодом. Обычно она развертывается с СУБД MySQL, но ее можно настроить и для других решений хранения данных. Laravel отличается использованием преимуществ современных возможностей PHP и обширной экосистемой пакетов.

      Kubernetes — платформа оркестровки контейнеров, которую можно размещать на кластерах DigitalOcean Kubernetes для упрощения администрирования, настройки и использования контейнеров в производственной среде. Helm — это диспетчер пакетов Kubernetes, упрощающий настройку и установку служб и подов в Kubernetes.

      В этом обучающем модуле вы создадите приложение Laravel PHP, добавите приложение в образ Docker и развернете этот образ в кластере DigitalOcean Kubernetes, используя чарт LAMP Helm. Затем вы настроите контроллер Ingress для добавления SSL и собственного доменного имени вашего приложения. После прохождения вы получите работающее приложение Laravel, подключенноек базе данных MySQL, запущенной на кластере Kubernetes.

      Предварительные требования

      • Система Docker, установленная на компьютере, с которого вы будете подключаться к кластеру. Подробные инструкции по установке Docker для большинства дистрибутивов Linux можно найти здесь или на сайте Docker для других операционных систем.
      • В этом обучающем модуле вы создадите учетную запись Docker Hub для хранения образов Docker.
      • Кластер DigitalOcean Kubernetes с конфигурацией подключения, настроенной с помощью kubectl по умолчанию. Процесс создания кластера Kubernetes в DigitalOcean, описан в документе «Быстрое начало работы с Kubernetes». Процедура подключения к кластеру описана в руководстве «Подключение к кластеру DigitalOcean Kubernetes».
      • Диспетчер пакетов Helm 3, установленный на локальном компьютере. Выполните первый шаг и добавьте репозиторий stable из второго шага обучающего модуля «Установка программного обеспечения в кластерах Kubernetes с помощью диспетчера пакетов Helm 3».
      • Полностью зарегистрированное доменное имя с доступной записью A. В этом обучающем руководстве мы будем использовать your_domain. Вы можете купить доменное имя на Namecheap, получить его бесплатно на Freenom или воспользоваться услугами любого предпочитаемого регистратора доменных имен. Сейчас не нужно думать о привязке записи A вашего домена к IP-адресу. Когда вы дойдете до шага 5 и ваш контроллер Ingress будет установлен, вы подключите your_domain к правильному IP-адресу.

      Шаг 1 — Создание нового приложения Laravel

      На этом шаге мы используем Docker для создания нового приложения Laravel 7, но у вас должна быть возможность выполнить эту же процедуру с существующим приложением Laravel, которое использует MySQL в качестве опорной базы данных. Создаваемое новое приложение подтверждает подключение Laravel к базе данных и отображает имя базы данных.

      Перейдите в домашний каталог и создайте новое приложение Laravel с использованием контейнера composer Docker:

      • cd ~
      • docker run --rm -v $(pwd):/app composer create-project --prefer-dist laravel/laravel laravel-kubernetes

      Когда контейнер будет готов и все пакеты Composer будут установлены, вы увидите новую установку Laravel в текущем каталоге laravel-kubernetes/. Перейдите в этот каталог:

      Остальные команды этого обучающего модуля должны выполняться в нем.

      Цель этого приложения — протестировать подключение к базе данных и вывести ее имя в браузере. Чтобы протестировать подключение к базе данных, откройте файл ./resources/views/welcome.blade.php в текстовом редакторе:

      • nano ./resources/views/welcome.blade.php

      Найдите раздел <div class="links">...</div> и замените его содержимое следующим:

      ./resources/views/welcome.blade.php

      ...
      <div class="links">
         <strong>Database Connected: </strong>
          @php
              try {
                  DB::connection()->getPDO();
                  echo DB::connection()->getDatabaseName();
                  } catch (Exception $e) {
                  echo 'None';
              }
          @endphp
      </div>
      ...
      

      Сохраните и закройте файл.

      Это все настройки, которые потребуется внести в приложение Laravel по умолчанию для этого обучающего модуля. После завершения этот небольшой код PHP протестирует ваше подключение к базе данных и выведет имя данных на всплывающем экране Laravel в вашем браузере.

      На следующем шаге мы используем Docker для создания образа, содержащего это приложение Laravel, и Docker Compose для тестирования локального запуска и подключения к базе данных MySQL.

      Шаг 2 — Контейнеризация вашего приложения Laravel

      Мы создали новое приложение Laravel, и теперь нам нужно добавить код в образ Docker и протестировать образ с помощью Docker Compose. Хотя целью этого обучающего модуля является развертывание приложения в кластере Kubernetes, Docker Compose открывает удобный способ протестировать образ и конфигурацию Docker локально перед их запуском в облаке. Этот быстрый цикл обратной связи может быть полезен для внесения и тестирования небольших изменений.

      Вначале используйте nano или другой предпочитаемый текстовый редактор для создания в корневом каталоге вашего приложения Laravel файла с именем Dockerfile:

      Добавьте в файл следующее: Docker будет использовать этот файл для встраивания кода в образ:

      ./Dockerfile

      FROM php:7.4-apache
      
      # Install packages
      RUN apt-get update && apt-get install -y 
          git 
          zip 
          curl 
          sudo 
          unzip 
          libicu-dev 
          libbz2-dev 
          libpng-dev 
          libjpeg-dev 
          libmcrypt-dev 
          libreadline-dev 
          libfreetype6-dev 
          g++
      
      # Apache configuration
      ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
      RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
      RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
      RUN a2enmod rewrite headers
      
      # Common PHP Extensions
      RUN docker-php-ext-install 
          bz2 
          intl 
          iconv 
          bcmath 
          opcache 
          calendar 
          pdo_mysql
      
      # Ensure PHP logs are captured by the container
      ENV LOG_CHANNEL=stderr
      
      # Set a volume mount point for your code
      VOLUME /var/www/html
      
      # Copy code and run composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      COPY . /var/www/tmp
      RUN cd /var/www/tmp && composer install --no-dev
      
      # Ensure the entrypoint file can be run
      RUN chmod +x /var/www/tmp/docker-entrypoint.sh
      ENTRYPOINT ["/var/www/tmp/docker-entrypoint.sh"]
      
      # The default apache run command
      CMD ["apache2-foreground"]
      

      Сохраните и закройте файл.

      Этот файл Dockerfile начинает с образа PHP 7.4 Apache Docker из Docker Hub, а затем устанавливает несколько пакетов Linux, которые обычно требуются для приложений Laravel. Затем он создает файлы конфигурации Apache и включает перезапись заголовков. Dockerfile устанавливает несколько общих расширений PHP и добавляет переменную среды для обеспечения трансляции журналов Laravel в контейнер через stderr. Это позволяет просматривать журналы Laravel через журналы Docker Compose или Kubernetes.

      В заключение, Dockerfile копирует весь код приложения Laravel в каталог /var/www/tmp и устанавливает зависимости Composer. Затем он устанавливает ENTRYPOINT, но нам еще нужно создать этот файл, что мы сейчас и сделаем.

      Создайте в корневом каталоге проекта новый файл с именем docker-entrypoint.sh. Этот файл будет запускаться при запуске контейнера в локальном режиме или в кластере Kubernetes и будет копировать код приложения Laravel из каталога /var/www/tmp в каталог /var/www/html, где его будет обслуживать Apache.

      • nano ./docker-entrypoint.sh

      Добавьте следующий скрипт:

      ./docker-entrypoint.sh

      #!/bin/bash
      
      cp -R /var/www/tmp/. /var/www/html/
      chown -R www-data:www-data /var/www/html
      
      exec "$@"
      

      Заключительная строка exec "$@" предписывает оболочки запустить любую команду, которая будет передана следующей в качестве входного аргумента. Это важно, потому что нам нужно, чтобы Docker продолжал выполнять команду запуска Apache (apache2-foreground) после выполнения этого скрипта. Сохраните и закройте файл.

      Создайте файл .dockerignore в корневом каталоге вашего приложения. С этим файлом при сборке образа Docker он не будет загрязнен пакетами или файлами среды, которые не следует в него копировать:

      ./.dockerignore

      .env
      /vendor
      

      Сохраните и закройте файл.

      Теперь перед локальным запуском приложения с помощью Docker Compose осталось только создать файл docker-compose.yml. Во время настройки этого файла YAML нужно будет ввести ключ APP_KEY, сгенерированный Laravel во время установки. Чтобы найти его, нужно открыть и запустить поиск файла . /.env или запустить следующие команды cat и grep:

      Результат должен будет выглядеть следующим образом:

      Output

      APP_KEY=base64:0EHhVpgg ... UjGE=

      Скопируйте ключ в буфер обмена. Обязательно добавьте префикс base64:. Теперь создайте файл docker-compose.yml в корневом каталоге вашего приложения:

      • nano ./docker-compose.yml

      Здесь мы включим образ PHP вашего приложения Laravel и контейнер MySQL для запуска вашей базы данных. Добавьте следующее содержимое:

      ./docker-compose.yml

      version: '3.5'
      services:
        php:
          image: your_docker_hub_username/laravel-kubernetes:latest
          restart: always
          ports:
            - 8000:80
          environment:
            - APP_KEY="your_laravel_app_key"
            - APP_ENV=local
            - APP_DEBUG=true
            - DB_PORT=3306
            - DB_HOST=mysql
            - DB_DATABASE
            - DB_USERNAME
            - DB_PASSWORD
        mysql:
          image: mysql:5.7
          restart: always
          environment:
            - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
            - MYSQL_DATABASE=${DB_DATABASE}
            - MYSQL_USER=${DB_USERNAME}
            - MYSQL_PASSWORD=${DB_PASSWORD}
      

      Используйте скопированную вами в буфер обмена переменную APP_KEY для переменной your_laravel_app_key и используйте свое имя пользователя Docker Hub для переменной your_docker_hub_username. Сохраните и закройте файл.

      Первый образ вы создадите локально с помощью docker build. Второй образ — это официальный образ MySQL Docker, доступный в Docker Hub. Для обоих из них требуется несколько переменных среды, которые добавляются при запуске контейнеров.

      Запустите следующую команду для сборки образа Docker, содержащего ваше приложение Laravel. Обязательно замените your_docker_hub_username своим именем пользователя или именем пользователя команды Docker Hub, где будет храниться этот образ:

      • docker build -t your_docker_hub_username/laravel-kubernetes:latest .

      Затем вы можете запустить два контейнера с помощью Docker Compose, используя требуемые учетные данные БД:

      • DB_ROOT_PASSWORD=rootpassword DB_DATABASE=local_db DB_USERNAME=admin DB_PASSWORD=password docker-compose up -d

      Вы можете изменять четыре используемых здесь переменных среды (DB_ROOT_PASSWORD, DB_DATABASE, DB_USERNAME, DB_PASSWORD) , но поскольку вы только тестируете приложение на локальной системе, вам не нужно беспокоиться об их защите.

      Инициализация базы данных MySQL и подготовка контейнеров могут занять до 30 секунд. Когда контейнеры будут готовы, вы можете просмотреть свое приложение Laravel на локальном компьютере по адресу localhost:8000.

      Приложение Laravel, запущенное локально с помощью Docker Compose

      Ваше приложение PHP подключится к вашей базе данных MySQL. После успешного подключения под логотипом Laravel появится текст «Database Connected: local_db».

      Мы протестировали образ Docker на локальной системе с помощью Docker Compose и теперь можем остановить контейнеры с помощью команды docker-compose down:

      В следующем разделе мы отправим образ Docker в Docker Hub, чтобы чарт Helm мог использовать его для развертывания вашего приложения в вашем кластере Kubernetes.

      Шаг 3 — Отправка образа Docker в Docker Hub

      Чарт LAMP Helm, который мы будем использовать для развертывания кода в Kubernetes, требует, чтобы код был доступен в реестре контейнеров. Хотя вы можете отправить свой образ в частный или собственный реестр, в этом обучающем модуле мы будем использовать общедоступный бесплатный реестр Docker в Docker Hub.

      Откройте в браузере свою учетную запись на Docker Hub и создайте новый репозиторий с именем laravel-kubernetes.

      Создание нового репозитория в Docker Hub

      Затем если вы не подключились к Docker Hub с локального компьютера, вам нужно будет войти в Docker Hub. Это можно сделать через командную строку:

      • docker login -u your_docker_hub_username

      Введите в диалоге свои учетные данные. Обычно это нужно делать только один раз на каждом компьютере, поскольку Docker сохраняет ваши учетные данные в каталоге ~/.docker/config.json в вашем домашнем каталоге.

      В заключение отправьте свой образ в Docker Hub:

      • docker push your_docker_hub_username/laravel-kubernetes:latest

      Выгрузка приложения может занять несколько минут в зависимости от скорости подключения, однако после завершения этой операции Docker вы увидите в окне терминала окончательную сводную хэш-сумму и размер вашего образа. Он будет выглядеть примерно так:

      Output

      latest: digest: sha256:df4bdeda91484c8c26a989b13b8f27ab14d93ab2e676e3c396714cb3811c4086 size: 4918

      Мы поместили ваше приложение Laravel в контейнер и отправили образ в Docker Hub, и теперь вы можете использовать этот образ для развертывания чарта Helm или Kubernetes. На следующем шаге мы зададим персонализированные значения на базе чарта LAMP Helm и развернем его в вашем кластере DigitalOcean Kubernetes.

      Шаг 4 — Настройка и развертывание приложения с помощью чарта LAMP Helm

      В Helm имеется ряд чартов, помогающих настраивать приложения Kubernetes с использованием готовых комбинаций инструментов. Хотя вы можете самостоятельно написать служебные файлы Kubernetes для аналогичного развертывания, в этом разделе вы увидите, что использование чарта Helm требует намного меньше настроек.

      Прежде всего, вам потребуется каталог для хранения всех ваших файлов конфигурации Helm. Создайте в корневом каталоге вашего проекта Laravel новый каталог с именем helm/:

      В каталоге helm/ мы создадим два новых файла: values.yml и secrets.yml. Вначале создайте и откройте файл values.yml:

      Файл values.yml будет содержать несекретные параметры конфигурации, которые будут заменять значения по умолчанию в чарте LAMP Helm. Добавьте следующие конфигурации, заменив your_docker_hub_username своим именем пользователя:

      ./helm/values.yml

      php:
        repository: "your_docker_hub_username/laravel-kubernetes"
        tag: "latest"
        fpmEnabled: false
        envVars:
          - name: APP_ENV
            value: production
          - name: APP_DEBUG
            value: false
          - name: DB_PORT
            value: 3306
          - name: DB_HOST
            value: localhost
      

      Сохраните и закройте файл.

      Теперь создайте файл secrets.yml:

      secrets.yml не регистрируется в системе контроля версий. Он будет содержать важные данные конфигурации, в том числе ваш пароль базы данных и ключ приложения Laravel. Добавьте следующие конфигурации с вашими учетными данными:

      ./helm/secrets.yml

      mysql:
        rootPassword: "your_database_root_password"
        user: your_database_user
        password: "your_database_password"
        database: your_database_name
      
      php:
        envVars:
          - name: APP_KEY
            value: "your_laravel_app_key"
          - name: DB_DATABASE
            value: your_database_name
          - name: DB_USERNAME
            value: your_database_user
          - name: DB_PASSWORD
            value: "your_database_password"
      

      Обязательно используйте надежные сочетания имени пользователя и пароля для производственной базы данных и используйте тот же ключ your_laravel_app_key, что и выше, или откройте новое окно терминала и сгенерируйте новый ключ с помощью следующей команды. После этого вы можете скопировать новое значение, задаваемое Laravel в вашем файле .env:

      • docker run --rm -v $(pwd):/app php:cli php /app/artisan key:generate

      Сохраните и закройте файл secrets.yml.

      Чтобы ваш файл secrets.yml не добавлялся в образ Docker и не сохранялся в системе контроля версий, обязательно добавьте следующую строку в ваши файлы .dockerignore и .gitignore. Откройте и добавьте /helm/secrets.yml в каждый файл или запустите следующую команду для добавления в оба файла:

      • echo '/helm/secrets.yml' >> ./.dockerignore && echo '/helm/secrets.yml' >> ./.gitignore

      Вы создали файлы конфигурации Helm для вашего приложения и образа Docker и теперь можете установить этот чарт Helm как новый релиз в вашем кластере Kubernetes. Установите чарт из корневого каталога вашего приложения:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Результат должен будет выглядеть следующим образом:

      Output

      NAME: laravel-kubernetes LAST DEPLOYED: Mon May 18 13:21:20 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      Ваше приложение будет доступно через одну-две минуты, но вы можете запустить следующую команду для мониторинга служб Kubernetes в вашем кластере:

      Поищите имя вашего приложения:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) laravel-kubernetes-lamp LoadBalancer your_cluster_ip your_external_ip 80:32175/TCP,3306:32243/TCP

      Когда новая служба laravel-kubernetes-lamp отображает IP-адрес под EXTERNAL-IP, вы можете открыть your_external_ip, чтобы увидеть приложение, запущенное в кластере Kubernetes. Ваше приложение подключится к вашей базе данных, и вы увидите имя базы данных под логотипом Laravel, как при локальном запуске приложения с помощью Docker Compose.

      Приложение Laravel, запущенное в Kubernetes с помощью чарта LAMP Helm

      Для концептуальных испытаний веб-приложение можно запустить с незащищенного IP-адреса, но ваш сайт не будет готов для производственной среды без сертификата SSL и персонализированного доменного имени. На следующем шаге мы настроим их, но предварительно нужно удалить релиз через командную строку:

      • helm delete laravel-kubernetes

      На следующем шаге мы расширим первую конфигурацию Helm, добавив контроллер Ingress, сертификат SSL и персонализированный домен в наше приложение Laravel.

      Шаг 5 — Добавление контроллера Ingress и SSL в кластер Kubernetes

      В Kubernetes контроллер Ingress отвечает за предоставление доступа к службам вашего приложения через интернет. На предыдущем шаге чарт LAMP Helm создал балансировщик нагрузки DigitalOcean и открыл прямой доступ к вашему приложению через IP-адрес балансировщика.

      Вы можете вывести SSL и доменное имя напрямую на балансировщик нагрузки, но поскольку мы работаем в Kubernetes, будет удобнее управлять всем в одном месте. Дополнительную информацию о контроллерах Ingress и подробные сведения о следующих шагах можно найти в руководстве «Настройка Nginx Ingress в DigitalOcean Kubernetes с помощью Helm».

      Чарт LAMP Helm включает опцию конфигурации для поддержки Ingress. Откройте ваш файл helm/values.yml:

      Добавьте в него следующие строки:

      ./helm/values.yml

      ...
      # Use Ingress Controller
      service:
        type: ClusterIP
        HTTPPort: 80
      ingress:
        enabled: true
        domain: your_domain
      

      Данная опция указывает, что при развертывании не нужно устанавливать балансировщик нагрузки и что нужно предоставить доступ к приложению через порт 80 кластера Kubernetes, доступ к которому контроллер Ingress откроет через Интернет. Сохраните и закройте файл values.yml.

      Запустите команду helm install, которую вы запускали ранее, чтобы снова запустить приложение Laravel. Команду нужно запускать из корневого каталога вашего приложения:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Затем установите контроллер nginx-ingress в своем кластере Kubernetes, используя обслуживаемый Kubernetes-контроллер Nginx Ingress:

      • helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true

      После установки вы увидите следующий результат:

      Output

      NAME: nginx-ingress LAST DEPLOYED: Mon May 18 13:28:34 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      Чтобы открыть доступ к развертыванию вашего приложения Laravel, вам также потребуется ресурс Ingress. Создайте в корневом каталоге вашего приложения новый файл с именем ingress.yml:

      В этом файле определяются хост приложения, диспетчер сертификатов SSL, серверная служба и имя порта. Добавьте следующие конфигурации, заменив your_domain выбранным именем домена:

      ./ingress.yml

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: laravel-kubernetes-ingress
        annotations:
          kubernetes.io/ingress.class: nginx
          cert-manager.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
          - hosts:
              - your_domain
            secretName: laravel-kubernetes-tls
        rules:
          - host: your_domain
            http:
              paths:
                - backend:
                    serviceName: laravel-kubernetes-lamp
                    servicePort: 80
      

      Сохраните и закройте файл.

      Затем необходимо установить Cert-Manager и создать центр, который позволит вам создавать производственные сертификаты SSL с помощью Let’s Encrypt. Для Cert-Manager требуются персонализированные определения ресурсов, которые вы можете применить из репозитория Cert-Manager через командную строку:

      • kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml

      При этом будет создан ряд ресурсов Kubernetes, которые будут выведены в командной строке:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io create

      Cert-Manager также требуется пространство имен для его изоляции в кластере Kubernetes:

      • kubectl create namespace cert-manager

      Вы увидите следующее:

      Output

      namespace/cert-manager created

      Поскольку Jetstack Cert-Manager не входит в число чартов, обслуживаемых Kubernetes, вам нужно будет также добавить репозиторий Jetstack Helm. Запустите следующую команду, чтобы сделать ее доступной в Helm:

      • helm repo add jetstack https://charts.jetstack.io

      При успешном добавлении вывод будет выглядеть так:

      Output

      "jetstack" has been added to your repositories

      Теперь мы готовы установить Cert-Manager в пространство имен cert-manager в кластере Kubernetes:

      • helm install cert-manager --version v0.15.0 --namespace cert-manager jetstack/cert-manager

      После выполнения этой операции вы увидите сводную информацию о развертывании:

      Output

      NAME: cert-manager LAST DEPLOYED: Mon May 18 13:32:08 2020 NAMESPACE: cert-manager STATUS: deployed REVISION: 1

      В заключение нужно добавить в корневой каталог приложения Laravel файл конфигурации Kubernetes с именем production_issuer.yml. Создайте файл:

      • nano ./production_issuer.yml

      Добавьте следующее:

      apiVersion: cert-manager.io/v1alpha2
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # Email address used for ACME registration
          email: your_email_address
          server: https://acme-v02.api.letsencrypt.org/directory
          privateKeySecretRef:
            # Name of a secret used to store the ACME account private key
            name: letsencrypt-prod-private-key
          # Add a single challenge solver, HTTP01 using nginx
          solvers:
            - http01:
                ingress:
                  class: nginx
      

      Сохраните и закройте файл.

      Let’s Encrypt будет отправлять на адрес your_email_address все важные уведомления и предупреждения об окончании срока действия сертификата, так что укажите адрес, который вы будете регулярно проверять. Сохраните этот файл и создайте новый ресурс для вашего ресурса Ingress и производственного центра сертификации в вашем кластере Kubernetes:

      • kubectl create -f ingress.yml
      • kubectl create -f production_issuer.yml

      В заключение обновите записи DNS вашего доменного имени, чтобы запись A указывала на IP-адрес вашего балансировщика нагрузки. Чтобы найти IP-адрес вашего контроллера Ingress, введите следующую команду:

      • kubectl get service nginx-ingress-controller

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-controller LoadBalancer your_cluster_ip your_external_ip 80:30187/TCP,443:31468/TCP 6m10s

      Используйте адрес your_external_ip в качестве IP-адреса вашей записи DNS A. Процесс обновления записей DNS зависит от того, где вы управляете доменными именами и хостингом DNS, но если вы используете DigitalOcean, вы можете сослаться на наше руководство по управлению записями DNS.

      После обновления ваших записей DNS и генерирования сертификата SSL ваше приложение будет доступно по адресу your_domain с включенным SSL.

      Приложение Laravel с SSL и персонализированным доменным именем

      Хотя ваше приложение PHP и база данных уже связаны, вам все равно необходимо провести миграцию базы данных. На последнем шаге мы увидим, как запускать команды Artisan в поде Kubernetes для миграции базы данных и выполнения других распространенных задач технического обслуживания.

      Шаг 6 — Дистанционный запуск команд

      Хотя ваше приложение Laravel уже запущено и подключено к базе данных MySQL в Kubernetes, вам нужно выполнить несколько стандартных операций после установки приложения Laravel. В частности, вам следует провести миграцию баз данных.

      Прежде чем запускать команду Artisan для вашего приложения Laravel, вам нужно знать имя пода, где запущен контейнер вашего приложения Laravel. Для просмотра всех подов в вашем кластере Kubernetes используйте следующую команду:

      Результат должен будет выглядеть следующим образом:

      Output

      NAME READY STATUS RESTARTS AGE laravel-kubernetes-lamp-77fb989b46-wczgb 2/2 Running 0 16m

      Выберите под для развертывания laravel-kubernetes-lamp-... Обязательно используйте выведенное имя, а не указанное выше. Теперь вы можете запустить для него команду kubectl exec. Например, для проведения миграции базы данных используйте команду artisan migrate. Мы добавляем флаг --force, поскольку команда выполняется на поде в производственной среде:

      • kubectl exec laravel-kubernetes-lamp-77fb989b46-wczgb -- php artisan migrate --force

      Эта команда выводит следующее:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.16 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.05 seconds)

      Мы успешно развернули Laravel 7 и MySQL в Kubernetes и выполнили необходимую задачу по обслуживанию базы данных.

      Заключение

      В этом обучающем модуле мы научились выполнять контейнеризацию приложения Laravel PHP, подключать его к базе данных MySQL, отправлять образ Docker с кодом в Docker Hub, а затем использовать чарт Helm для развертывания этого образа в кластере DigitalOcean Kubernetes. В заключение мы добавили SSL и персонализированное доменное имя и научились запускать инструменты командной строки в работающих подах.

      Kubernetes и Helm дают ряд преимуществ по сравнению с традиционными вариантами хостинга стека LAMP: масштабируемость, возможность замены служб без прямого входа на сервер, инструменты для обновления во время работы и контроль над средой хостинга. При этом сложность начальной контейнеризации и настройки приложения делает начало работы непростой задачей. С этим руководством развертывание Laravel в кластере Kubernetes станет более достижимой задачей. Теперь вы можете изучить дополнительную информацию о возможностях Laravel и добавлении в Kubernetes инструментов мониторинга, таких как Linkerd, которые вы можете установить вручную с помощью нашего руководства или системы DigitalOcean 1-Click.



      Source link

      Развертывание и управление DNS с использованием DNSControl в Debian 10


      Автор выбрал Electronic Frontier Foundation Inc для получения пожертвований в рамках программы Write for DOnations.

      Введение

      DNSControl — это инструмент, построенный по принципу «инфраструктура как код», который поддерживает развертывание и управление зонами DNS с использованием стандартных принципов разработки программного обеспечения, включая контроль версий, тестирование и автоматизированное развертывание. Инструмент DNSControl разработан Stack Exchange и написан на Go.

      Использование DNSControl помогает избавиться от многих сложностей ручного управления DNS, поскольку файлы зон хранятся в программируемом формате. Инструмент позволяет одновременно развертывать зоны для нескольких поставщиков DNS, определять ошибки синтаксиса и автоматически извлекать конфигурации DNS, за счет чего снижается риск человеческой ошибки. Также DNSControl часто используется для быстрого переноса DNS на другого провайдера; например, в случае DDoS-атаки или выхода системы из строя.

      В этом обучающем руководстве мы научимся устанавливать и настраивать DNSControl, создадим базовую конфигурацию DNS и начнем развертывание записей DNS на рабочем провайдере. Для этого обучающего руководства мы используем DigitalOcean в качестве примера провайдера DNS. Если вы хотите использовать другого провайдера, настройки будут выглядеть очень похоже. После завершения работы вы сможете управлять своей конфигурацией DNS и тестировать ее в безопасной среде, отключенной от сети, а затем автоматически развертывать в производственной среде.

      Предварительные требования

      Для прохождения этого обучающего руководства вам потребуется следующее:

      • Один сервер Debian 10, настроенный в соответствии с указаниями по начальной настройке сервера Debian 10, включая пользователя sudo без привилегий root и активированный брандмауэр для блокировки ненужных портов. your-server-ipv4-address обозначает IP-адрес сервера, где вы размещаете свой сайт или домен. your-server-ipv6-address обозначает адрес IPv6 сервера, где вы размещаете свой сайт или домен.
      • Полностью зарегистрированное доменное имя с хостингом DNS у поддерживаемого провайдера. В этом обучающем руководстве мы используем доменное имя your_domain и DigitalOcean как провайдера услуг.
      • Ключ DigitalOcean API (персональный токен доступа) с разрешениями чтения и записи. Его создание описано в материале Создание персонального токена доступа.

      Подготовив все вышеперечисленное, войдите на сервер без привилегий root, чтобы начать подготовку.

      Шаг 1 — Установка DNSControl

      Инструмент DNSControl написан на языке Go, и поэтому вначале вам нужно установить Go на свой сервер и задать GOPATH.

      Go доступен в репозиториях программного обеспечения Debian по умолчанию, и поэтому его можно установить с помощью стандартных инструментов управления пакетами.

      Также вам нужно будет установить Git, поскольку это требуется, чтобы дать Go возможность загрузки и установки программного обеспечения DNSControl из репозитория на GitHub.

      Для начала мы обновим указатель локальных пакетов, чтобы отразить последние изменения на предыдущих уровнях:

      Затем мы установим пакеты golang-go и git:

      • sudo apt install golang-go git

      После подтверждения установки apt выполнит загрузку и установку Go и Git, а также всех требуемых зависимостей.

      Далее вы настроите требуемые переменные среды path для Go. Дополнительную информацию можно получить в обучающем материале по GOPATH. Для начала отредактируем файл ~/.profile:

      Добавим в конец файла следующие строки:

      ~/.profile

      ...
      export GOPATH="$HOME/go"
      export PATH="$PATH:$GOPATH/bin"
      

      После добавления этих строк в конец файла мы сохраним и закроем его. Затем мы перезагрузим профиль, для чего выйдем из системы и снова войдем в нее или снова укажем файл в качестве источника:

      Мы установили и настроили Go и теперь можем перейти к установке DNSControl.

      Команду go get можно использовать для доставки копии кода, его автоматической компиляции и установки в директорию Go:

      • go get github.com/StackExchange/dnscontrol

      После этого мы можем проверить установленную версию и убедиться, что все работает правильно:

      Экран результатов должен выглядеть примерно следующим образом:

      Output

      dnscontrol 2.9-dev

      Если выводится сообщение об ошибке dnscontrol: command not found, необходимо еще раз проверить настройки путей Go.

      Мы установили DNSControl и теперь можем создать директорию конфигурации и подключить DNSControl к провайдеру DNS, чтобы дать инструменту возможность вносить изменения в ваши записи DNS.

      Шаг 2 — Настройка DNSControl

      На этом шаге мы создадим требуемые директории конфигурации DNSControl и подключим их к нашему провайдеру DNS, чтобы начать вносить изменения в записи DNS в реальном времени.

      Вначале нам нужно создать новую директорию для хранения конфигурации DNSControl и перейти в нее:

      • mkdir ~/dnscontrol
      • cd ~/dnscontrol

      Примечание. В этом обучающем модуле мы рассматриваем начальную настройку DNSControl, но для использования в производственной среде рекомендуется хранить конфигурацию DNSControl в системе контроля версий (VCS), такой как Git. Это дает преимущества полного контроля версий, интеграции с CI/CD для тестирования, удобства откатов при развертывании и т. д.

      Если вы планируете использовать DNSControl для записи файлов зоны BIND, вам также следует создать директорию zones:

      Файлы зоны BIND представляют собой чистый стандартизированный метод сохранения зон и записей DNS в простом текстовом формате. Они первоначально использовались для программного обеспечения сервера BIND DNS, однако сейчас они широко используются в качестве стандартного метода хранения зон DNS. Файлы зоны BIND, предоставляемые DNSControl, очень полезны, если их нужно импортировать в персонализированный или собственный сервер DNS, а также для целей аудита.

      Если вы хотите просто использовать DNSControl для передачи изменений DNS управляемому провайдеру, директория zones не потребуется.

      Далее требуется настроить файл creds.json, что позволит DNSControl выполнить аутентификацию вашего провайдера DNS и внести изменения. Формат файла creds.json может немного отличаться в зависимости от используемого провайдера DNS. Ознакомьтесь со списком провайдеров в официальной документации DNSControl, чтобы найти конфигурацию для вашего провайдера.

      Создайте файл creds.json в директории ~/dnscontrol:

      • cd ~/dnscontrol
      • nano creds.json

      Добавьте в файл образец конфигурации creds.json для вашего провайдера DNS. Если вы используете DigitalOcean в качестве своего провайдера DNS, вы можете использовать следующее:

      ~/dnscontrol/creds.json

      {
      "digitalocean": {
        "token": "your-digitalocean-oauth-token"
      }
      }
      

      Этот файл сообщает DNSControl, к каким провайдерам DNS нужно подключаться.

      Необходимо указать форму аутентификации для провайдера DNS. Обычно это ключ API или токен OAuth, однако для некоторых провайдеров требуется дополнительная информация, как описано в списке провайдеров в официальной документации DNSControl.

      Предупреждение. Этот токен предоставляет доступ к учетной записи провайдера DNS, так что его следует защитить паролем. Также необходимо убедиться, что если вы используете систему контроля версий, файл с токеном исключен (например, с помощью .gitignore) или зашифрован.

      Если в качестве провайдера DNS используется DigitalOcean, можно использовать требуемый токен OAuth в параметрах учетной записи DigitalOcean, сгенерированных при выполнении предварительных требований.

      Если вы используете нескольких провайдеров DNS, например для разных доменных имен или делегированных зон DNS, вы можете определить их в том же самом файле creds.json.

      Мы выполнили настройку первоначальных директорий конфигурации DNSControl и настроили файл creds.json так, чтобы DNSControl мог проходить аутентификацию у провайдера DNS и вносить изменения. Теперь мы создадим конфигурацию для наших зон DNS.

      Шаг 3 — Создание файла конфигурации DNS

      На этом шаге мы создадим начальный файл конфигурации DNS, который будет содержать записи DNS для вашего доменного имени или делегированной зоны DNS.

      dnsconfig.js — основной файл конфигурации DNS для DNSControl. В этом файле зоны DNS и соответствующие им записи определяются с использованием синтаксиса JavaScript. Этот синтаксис называется DSL или предметно-ориентированный язык. Дополнительную информацию можно найти на странице JavaScript DSL в официальной документации по DNSControl.

      Вначале создадим файл конфигурации DNS в директории ~/dnscontrol:

      • cd ~/dnscontrol
      • nano dnsconfig.js

      Затем добавим в файл следующий образец конфигурации:

      ~/dnscontrol/dnsconfig.js

      // Providers:
      
      var REG_NONE = NewRegistrar('none', 'NONE');
      var DNS_DIGITALOCEAN = NewDnsProvider('digitalocean', 'DIGITALOCEAN');
      
      // Domains:
      
      D('your_domain', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),
        A('@', 'your-server-ipv4-address')
      );
      

      В файле образца определяется доменное имя или зона DNS определенного провайдера. В данном случае это домен your_domain на хостинге DigitalOcean. Пример записи A также определен для зоны root (@) и указывает на адрес IPv4 сервера, где размещен ваш домен или сайт.

      Базовый файл конфигурации DNSControl состоит из трех основных функций:

      • NewRegistrar(имя, тип, метаданные)​​​​: определяет регистратора домена для доменного имени. DNSControl может использовать эту функцию для внесения требуемых изменений, в частности для модификации авторитетных серверов имен. Если вы хотите использовать DNSControl только для управления зонами DNS, их можно оставить как NONE.

      • NewDnsProvider(имя, тип, метаданные)​​: определяет провайдера DNS для доменного имени или делегированной зоны. Здесь DNSControl применяет вносимые нами изменения DNS.

      • D(имя, регистратор, модификаторы): определяет доменное имя или делегируемую зону DNS для управления DNSControl, а также присутствующие в зоне записи DNS.

      Мы должны настроить NewRegistrar(), NewDnsProvider() и D() соответствующим образом, используя список провайдеров в официальной документации по DNSControl.

      Если в качестве провайдера DNS используется DigitalOcean и нам требуется только вносить изменения DNS (а не авторитетных серверов имен), образцы из предыдущего блока кода подойдут для наших целей.

      После завершения следует сохранить и закрыть файл.

      На этом шаге мы настроили файл конфигурации DNS для DNSControl с определением соответствующих провайдеров. Далее мы заполним файл полезными записями DNS.

      Шаг 4 — Заполнение файла конфигурации DNS

      Далее мы можем заполнить файл конфигурации DNS полезными записями DNS для нашего сайта или сервиса, используя синтаксис DNSControl.

      В отличие от традиционных файлов зоны BIND, где записи DNS имеют формат построчных необработанных данных, в DNSControl записи DNS определяются как параметр функции D() (модификатор домена), как мы вкратце показали на шаге 3.

      Модификатор домена существует для каждого стандартного типа записей DNS, включая A, AAAA, MX, TXT, NS, CAA и т. д. Полный список доступных типов записей можно найти в разделе Модификаторы домена в документации по DNSControl.

      Также доступны модификаторы отдельных записей (модификаторы записей). Они в основном используются для настройки TTL (времени существования) для отдельных записей. Полный список доступных модификаторов записей можно найти в разделе Модификаторы записей документации по DNSControl. Модификаторы записей необязательны для использования, в большинстве простых случаев их можно опускать.

      Синтаксис настройки записей DNS немного отличается для каждого типа записей. Далее приведены несколько примеров наиболее распространенных типов записей:

      • Записи A:

        • Назначение: указывают на адрес IPv4.
        • Синтаксис: A('name', 'address', необязательные модификаторы записи)
        • Пример: A('@', 'your-server-ipv4-address', TTL(30))
      • Записи AAAA:

        • Назначение: указывают на адрес IPv6.
        • Синтаксис: AAAA('name', 'address', необязательные модификаторы записи)
        • Пример: AAAA('@', 'your-server-ipv6-address') (модификатор записи опущен, поэтому используется TTL по умолчанию)
      • Записи CNAME:

        • Назначение: делают домен или субдомен псевдонимом другого домена или субдомена.
        • Синтаксис: CNAME('name', 'target', необязательные модификаторы записи)
        • Пример: CNAME('subdomain1', 'example.org.') (обратите внимание, что если значение содержит точку, завершающий символ . обязательно должен присутствовать в конце)
      • Записи MX:

        • Назначение: направление электронной почты на определенные серверы или адреса.
        • Синтаксис: MX('name', 'priority', 'target', необязательные модификаторы записи)
        • Пример: MX('@', 10, 'mail.example.net') (обратите внимание, что если значение содержит точку, завершающий символ . обязательно должен присутствовать в конце)
      • Записи TXT:

        • Назначение: добавление произвольного обычного текста, часто используется для конфигураций без собственного выделенного типа записи.
        • Синтаксис: TXT('name', 'content', необязательные модификаторы записи)
        • Пример: TXT('@', 'Это запись TXT. ')
      • Записи CAA:

        • Назначение: ограничение и отчет о центрах сертификации (СА), которые могут выпускать сертификаты TLS для доменов или субдоменов.
        • Синтаксис: CAA('name', 'tag', 'value', необязательные модификаторы записи)
        • Пример: CAA('@', 'issue', 'letsencrypt.org')

      Чтобы начать добавлять записи DNS для нашего домена или делегированной зоны DNS, нам нужно отредактировать файл конфигурации DNS:

      Далее мы можем начать указывать параметры для существующей функции D(), используя синтаксис,описанный в предыдущем списке и в разделе Модификаторы доменов официальной документации DNSControl. Для разделения записей должна использоваться запятая (,).

      Приведенный здесь блок кода содержит полный образец базовой конфигурации DNS, предназначенный для справочных целей:

      ~/dnscontrol/dnsconfig.js

      ...
      
      D('your_domain', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),
        A('@', 'your-server-ipv4-address'),
        A('www', 'your-server-ipv4-address'),
        A('mail', 'your-server-ipv4-address'),
        AAAA('@', 'your-server-ipv6-address'),
        AAAA('www', 'your-server-ipv6-address'),
        AAAA('mail', 'your-server-ipv6-address'),
        MX('@', 10, 'mail.your_domain.'),
        TXT('@', 'v=spf1 -all'),
        TXT('_dmarc', 'v=DMARC1; p=reject; rua=mailto:abuse@your_domain; aspf=s; adkim=s;')
      );
      

      После завершения начальной настройки DNS следует сохранить и закрыть файл.

      На этом шаге мы можем настроить начальный файл конфигурации DNS, содержащий наши записи DNS. Далее нам нужно будет протестировать конфигурацию и развернуть ее.

      Шаг 5 — Тестирование и развертывание конфигурации DNS

      На этом шаге мы проведем проверку локального синтаксиса нашей конфигурации DNS, а затем внесем изменения на рабочий сервер/провайдер DNS.

      Вначале мы перейдем в директорию dnscontrol:

      Затем мы используем функцию preview в DNSControl для проверки синтаксиса файла и вывода вносимых изменений (без их фактического внесения):

      Если файл конфигурации DNS имеет правильный синтаксис, DNSControl выведет обзор изменений, которые будут произведены. Результат должен выглядеть примерно так:

      Output

      ******************** Domain: your_domain ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE A your_domain your-server-ipv4-address ttl=300 #2: CREATE A www.your_domain your-server-ipv4-address ttl=300 #3: CREATE A mail.your_domain your-server-ipv4-address ttl=300 #4: CREATE AAAA your_domain your-server-ipv6-address ttl=300 #5: CREATE TXT _dmarc.your_domain "v=DMARC1; p=reject; rua=mailto:abuse@your_domain; aspf=s; adkim=s;" ttl=300 #6: CREATE AAAA www.your_domain your-server-ipv6-address ttl=300 #7: CREATE AAAA mail.your_domain your-server-ipv6-address ttl=300 #8: CREATE MX your_domain 10 mail.your_domain. ttl=300 ----- Registrar: none...0 corrections Done. 8 corrections.

      Если вы увидите предупреждение об ошибке в составе результатов, DNSControl даст дополнительные данные о сущности ошибки и ее расположении в файле.

      Предупреждение. Следующая команда вносит изменения в рабочие записи DNS и возможно в другие параметры. Необходимо убедиться, что мы готовы к этому. В частности, следует сделать резервную копию существующий конфигурации DNS на случай, если потребуется произвести откат.

      В заключение мы можем передать изменения на рабочий провайдер DNS:

      Результат будет выглядеть примерно так:

      Output

      ******************** Domain: your_domain ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE TXT _dmarc.your_domain "v=DMARC1; p=reject; rua=mailto:abuse@your_domain; aspf=s; adkim=s;" ttl=300 SUCCESS! #2: CREATE A your_domain your-server-ipv4-address ttl=300 SUCCESS! #3: CREATE AAAA your_domain your-server-ipv6-address ttl=300 SUCCESS! #4: CREATE AAAA www.your_domain your-server-ipv6-address ttl=300 SUCCESS! #5: CREATE AAAA mail.your_domain your-server-ipv6-address ttl=300 SUCCESS! #6: CREATE A www.your_domain your-server-ipv4-address ttl=300 SUCCESS! #7: CREATE A mail.your_domain your-server-ipv4-address ttl=300 SUCCESS! #8: CREATE MX your_domain 10 mail.your_domain. ttl=300 SUCCESS! ----- Registrar: none...0 corrections Done. 8 corrections.

      Если теперь мы проверим параметры DNS нашего домена на панели управления DigitalOcean, мы увидим изменения.

      Снимок экрана панели управления DigitalOcean, показывающий некоторые изменения DNS, которые были внесены DNSControl.

      Также мы можем проверить создание записи, отправив запрос DNS для нашего домена или делегированной зоны с помощью команды dig.

      Если команда dig не установлена, необходимо установить пакет dnsutils:

      • sudo apt install dnsutils

      После установки команды dig мы сможем использовать ее для запроса DNS нашего домена. Мы увидим, что записи обновлены соответствующим образом:

      В результатах выводится IP-адрес и запись DNS из вашей зоны, которая была развернута с помощью DNSControl. Распространение записей DNS может занять некоторое время, поэтому можно подождать и запустить команду чуть позже.

      На этом заключительном шаге мы выполнили проверку локального синтаксиса файла конфигурации DNS, развернули его на рабочем провайдере DNS и убедились, что изменения были внесены успешно.

      Заключение

      В этом обучающем руководстве мы выполнили настройку DNSControl и развертывание конфигурации DNS на рабочем провайдере. Теперь мы можем управлять изменениями конфигурации DNS и тестировать их в безопасной автономной среде, прежде чем внедрять их в производственную среду.

      Если вы хотите узнать об этом больше, DNSControl предусматривает интеграцию с конвейером CI/CD, что позволяет проводить детальные испытания и обеспечивает дополнительный контроль над развертыванием в производственной среде. Также можно интегрировать DNSControl в процессы сборки и развертывания инфраструктуры, что позволит развертывать серверы и добавлять их в службу DNS в полностью автоматическом режиме.

      Если вас интересует дополнительная информация о DNSControl, следующие материалы DigitalOcean содержат описание дальнейших шагов по интеграции DNSControl в рабочие процессы управления изменениями и развертывания инфраструктуры:



      Source link