One place for hosting & domains

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

      Развертывание 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

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


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

      Введение

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

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

      Инструмент OctoDNS аналогичен инструменту DNSControl, созданному Stack Exchange и написанному на Go. В отличие от OctoDNS, в DNSControl для определения зон DNS используется язык конфигурации на базе JavaScript, что позволяет использовать различные функции программирования (например циклы) для определения нескольких похожих записей в одной зоне. Статья Развертывание и управление DNS с помощью DNSControl в Debian 10 рассказывает об основах настройки и конфигурации DNSControl.

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

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

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

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

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

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

      OctoDNS распространяется как пакет Python pip и выполняется в виртуальной среде Python (virtualenv), так что мы начнем этот шаг с установки необходимых пакетов. virtualenv — это изолированная среда Python, которая может иметь собственные библиотеки и конфигурацию, отдельные от основной версии Python в системе. Python и virtualenv доступны в репозиториях программного обеспечения Debian по умолчанию, и поэтому их можно установить с помощью стандартных инструментов управления пакетами.

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

      Затем мы установим пакеты python и virtualenv:

      • sudo apt install python virtualenv

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

      Затем мы создадим необходимые для OctoDNS директории, где будут храниться конфигурации DNS и программы. Для начала создадим директории ~/octodns и ~/octodns/config:

      • mkdir ~/octodns ~/octodns/config

      Теперь перейдем в директорию ~/octodns:

      Теперь нам нужно создать виртуальную среду Python. Это изолированная среда Python с собственными библиотеками и конфигурацией, где будет работать OctoDNS:

      Активируем среду с помощью следующей команды:

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

      Output

      Running virtualenv with interpreter /usr/bin/python2 New python executable in /home/user/octodns/env/bin/python2 Also creating executable in /home/user/octodns/env/bin/python Installing setuptools, pkg_resources, pip, wheel...done.

      Строка оболочки Bash будет иметь префикс с именем виртуальной среды. Это показывает, что мы работаем в среде virtualenv:

      (env) user@digitalocean:~/octodns$
      

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

      Теперь вы установили и настроили Python и среду virtualenv и можете выполнить установку OctoDNS. OctoDNS распространяется как пакет Python pip (стандартный инструмент управления пакетами и библиотеками Python).

      Мы можем установить пакет OctoDNS pip с помощью команды в среде virtualenv:

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

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

      Output

      octoDNS 0.9.9

      Если будет выведено сообщение об ошибке octodns-sync: command not found, необходимо повторно убедиться, что мы находимся в среде virtualenv.

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

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

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

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

      Вначале нам нужно настроить файл config.yaml, который определит зоны DNS для управления OctoDNS и позволит проводить аутентификацию у провайдера DNS и вносить изменения.

      Формат файла config.yaml может немного отличаться в зависимости от используемого провайдера DNS. Ознакомьтесь со списком поддерживаемых провайдеров в официальной документации OctoDNS, чтобы найти конфигурацию для вашего провайдера. При просмотре этой гиперссылки детали конфигурации выводятся как комментарий к коду в фактическом коде Python нашего провайдера, привязанного в столбце Provider в таблице. Когда мы найдем код Python нашего провайдера, например cloudflare.py или route53.py, соответствующий комментарий к коду можно будет найти в классе ProviderNameProvider. Например:

      Excerpt of octodns/provider/route53.py

      class Route53Provider(BaseProvider):
        '''
        AWS Route53 Provider
        route53:
            class: octodns.provider.route53.Route53Provider
            # The AWS access key id
            access_key_id:
            # The AWS secret access key
            secret_access_key:
            # The AWS session token (optional)
            # Only needed if using temporary security credentials
            session_token:
      

      Перейдите в директорию ~/octodns/config:

      Создайте файл config.yaml и откройте его для редактирования:

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

      ~/octodns/config/config.yaml

      ---
      providers:
        config:
          class: octodns.provider.yaml.YamlProvider
          directory: ./config
          default_ttl: 300
          enforce_order: True
        digitalocean:
          class: octodns.provider.digitalocean.DigitalOceanProvider
          token: your-digitalocean-oauth-token
      
      zones:
        your-domain.:
          sources:
            - config
          targets:
            - digitalocean
      

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

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

      Если вы не хотите хранить токен доступа в текстовой форме в файле конфигурации, вы можете передать его в переменную среды при запуске программы. Для этого нужно использовать следующую строку token: в файле config.yaml:

      ~/octodns/config/config.yaml

      token: env/DIGITALOCEAN_OAUTH_TOKEN
      

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

      • export DIGITALOCEAN_OAUTH_TOKEN=your-digitalocean-oauth-token

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

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

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

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

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

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

      Для каждой зоны DNS, управляемой с помощью OctoDNS, должен существовать собственный файл, например your-domain.yaml. В этом файле записи DNS для зоны определяются с помощью YAML.

      Для начала перейдем в директорию ~/octodns/config:

      Затем создадим файл your-domain.yaml и откроем его для редактирования:

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

      ~/octodns/config/your-domain.yaml

      ---
      '':
        - type: A
          value: your-server-ipv4-address
      
      www:
        - type: A
          value: your-server-ipv4-address
      

      В этом файле образца определяется зона DNS для your-domain с двумя записями A, указывающими на адрес IPv4, на котором размещен домен или сайт. Одна запись A предназначена для корневого домена (например, your-domain), а другая — для субдомена www (например, www.your-domain).

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

      Мы настроили базовый файл конфигурации зоны DNS для OctoDNS с двумя базовыми записями A, указывающими на адрес IPv4 вашего домена или сайта. Далее мы заполним файл полезными записями DNS.

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

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

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

      Ключ 'name' обычно является ключом верхнего уровня, то есть идентификатором записи. Ключи www, subdomain1 и mail являются примерами ключа name службы DNS. В OctoDNS имеется два имени специального назначения: " для корневой записи (обычно @), и '*' для записей с подстановочными символами. Для каждого ключа (записи DNS) требуется значение type. Оно определяет, какой тип записей DNS мы определяем ключом YAML верхнего уровня. Значение type существует для каждого из стандартных типов записей DNS, в том числе A, AAAA, MX, TXT, NS, CNAME и т. д. Полный список доступных типов записей можно найти в разделе Записи в документации по OctoDNS.

      Значения записей DNS определяются напрямую как значения ключей верхнего уровня (если используется только одно значение) или в форме списка (если используется несколько значений, например несколько IP-адресов или адресов MX).

      Например, для определения одного значения можно использовать следующую конфигурацию:

      ~/octodns/config/your-domain.yaml

      'www':
        type: A
        value: 203.0.113.1
      

      Также можно определить несколько значений для одной записи:

      ~/octodns/config/your-domain.yaml

      'www':
        type: A
        values:
        - 203.0.113.1
        - 203.0.113.2
      

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

      Записи A:

      Назначение: указывают на адрес IPv4.

      Синтаксис:

      'name':
        type: A
        value: ipv4-address
      

      Пример:

      'www':
        type: A
        value: your-server-ipv4-address
      

      Записи AAAA:

      Назначение: указывают на адрес IPv6.

      Синтаксис:

      'name':
        type: AAAA
        value: ipv6-address
      

      Пример:

      'www':
        type: AAAA
        value: your-server-ipv6-address
      

      Записи CNAME:

      Назначение: делают домен или субдомен псевдонимом другого домена или субдомена.

      Синтаксис:

      'name':
        type: CNAME
        value: fully-qualified-domain-name
      

      Пример:

      'www':
        type: CNAME
        value: www.example.org
      

      Записи MX:

      Назначение: направляют электронную почту на определенные серверы или адреса.

      Синтаксис:

      'name':
        type: MX
        value:
          exchange: mail-server
          preference: priority-value
      

      Следует отметить, что если в значении MX содержатся точки, завершающий символ . обязательно должен быть указан в конце строки.

      Пример:

      '':
        type: MX
        value:
          exchange: mail.your-domain.
          preference: 10
      

      Записи TXT:

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

      Синтаксис:

      'name':
        type: TXT
        value: content
      

      Пример:

      '':
        type: TXT
        value: This is a TXT record.
      

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

      • cd ~/octodns/config
      • nano your-domain.yaml

      Далее мы можем начать заполнение зоны DNS, используя синтаксис, описанный в предыдущем списке и в разделе Записи официальной документации по OctoDNS.

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

      ~/octodns/config/your-domain.yaml

      ---
      '':
        - type: A
          value: your-server-ipv4-address
      
        - type: AAAA
          value: your-server-ipv6-address
      
        - type: MX
          value:
            exchange: mail.your-domain.
            preference: 10
      
        - type: TXT
          value: v=spf1 -all
      
      _dmarc:
        type: TXT
        value: v=DMARC1; p=reject; rua=mailto:abuse@your-domain; aspf=s; adkim=s;
      
      mail:
        - type: A
          value: your-server-ipv4-address
      
        - type: AAAA
          value: your-server-ipv6-address
      
      www:
        - type: A
          value: your-server-ipv4-address
      
        - type: AAAA
          value: your-server-ipv6-address
      

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

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

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

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

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

      Еще раз проверим, что мы работаем в среде Python virtualenv, посмотрев на имя перед Bash в командной строке:

      (env) user@digitalocean:~/octodns$
      

      Затем используем команду octodns-validate для проверки синтаксиса файла или файлов конфигурации. Также необходимо указать путь к файлу конфигурации:

      • octodns-validate --config=./config/config.yaml

      Если синтаксис YAML конфигурации DNS правильный, OctoDNS не выводит никаких результатов. Если вы увидите предупреждение об ошибке в составе результатов, OctoDNS даст дополнительные данные о сущности ошибки и ее местонахождении в файле YAML.

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

      • octodns-sync --config=./config/config.yaml

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

      Output

      ******************************************************************************** * your-domain. ******************************************************************************** * digitalocean (DigitalOceanProvider) * Create <ARecord A 300, mail.your-domain., ['your-server-ipv4-address']> (config) * Create <AaaaRecord AAAA 300, mail.your-domain., ['your-server-ipv6-address']> (config) * Create <TxtRecord TXT 300, your-domain., ['v=spf1 -all']> (config) * Create <AaaaRecord AAAA 300, your-domain., ['your-server-ipv6-address']> (config) * Create <ARecord A 300, your-domain., ['your-server-ipv4-address']> (config) * Create <ARecord A 300, www.your-domain., ['your-server-ipv4-address']> (config) * Create <MxRecord MX 300, your-domain., [''10 mail.your-domain.'']> (config) * Create <TxtRecord TXT 300, _dmarc.your-domain., ['v=DMARC1; p=reject; rua=mailto:abuse@your-domain; aspf=s; adkim=s;']> (config) * Create <AaaaRecord AAAA 300, www.your-domain., ['your-server-ipv6-address']> (config) * Summary: Creates=9, Updates=0, Deletes=0, Existing Records=2 ********************************************************************************

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

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

      • octodns-sync --config=./config/config.yaml --doit

      Примечание. В некоторых случаях OctoDNS может отказаться применять изменения, если количество модификаций значительно. Это функция автоматической защиты, которая позволит предотвратить случайные ошибки конфигурации. В случае такого отклонения можно повторно запустить octodns-sync с опцией --force, но при этом нужно быть уверенным в правильности этого шага.

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

      Output

      2019-07-07T23:17:27 INFO DigitalOceanProvider[digitalocean] apply: making changes 2019-07-07T23:17:30 INFO Manager sync: 9 total changes

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

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

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

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

      • sudo apt install dnsutils

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

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

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

      Заключение

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

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

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



      Source link