Поиск по сайту:

Как развернуть масштабируемое и безопасное приложение Django с помощью Kubernetes


Введение

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

Система шаблонов.

В серии From Containers to Kubernetes with Django модернизированное приложение опросов Django будет развернуто в кластере Kubernetes.

Давайте зашифруем центр сертификации.

Предпосылки

Чтобы следовать этому руководству, вам понадобятся:

  • Кластер Kubernetes 1.15+ с другим методом.
  • Инструмент командной строки kubectl, установленный на вашем локальном компьютере и настроенный для подключения к вашему кластеру. Вы можете прочитать больше об установке kubectl Как подключиться к кластеру DigitalOcean Kubernetes, чтобы узнать, как подключиться к вашему кластеру с помощью kubectl.
  • Зарегистрированное доменное имя. В этом руководстве везде будет использоваться your_domain.com. Вы можете получить его бесплатно на сайте Freenom или воспользоваться услугами регистратора домена по вашему выбору.
  • Как настроить Nginx Ingress с Cert-Manager в DigitalOcean Kubernetes.
  • DNS-запись A с your_domain.com, указывающая на общедоступный IP-адрес Ingress Load Balancer. Если вы используете DigitalOcean для управления записями DNS вашего домена, ознакомьтесь с разделом «Как управлять записями DNS», чтобы узнать, как создавать записи A
  • Поддерживается сегмент хранилища объектов S3, такой как подключаемый модуль django-storages.
  • Экземпляр сервера PostgreSQL, база данных и пользователь для вашего приложения Django. С небольшими изменениями вы можете использовать любую базу данных, которую поддерживает Django.
    • База данных PostgreSQL должна называться polls (или другое запоминающееся имя, которое нужно ввести в файлы конфигурации ниже), а в этом руководстве пользователя базы данных Django зовут sammy. Чтобы получить рекомендации по их созданию, следуйте шагу 1 раздела Как создать приложение Django и Gunicorn с помощью Docker. Вы должны выполнить эти шаги с вашего локального компьютера.
    • Документация по управляемым базам данных DigitalOcean.
    • Вы также можете установить и запустить собственный экземпляр PostgreSQL. Руководство по установке и администрированию PostgreSQL на сервере Ubuntu см. в разделе Установка и использование PostgreSQL в Ubuntu 18.04.

    После настройки этих компонентов вы готовы начать работу с этим руководством.

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

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

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

    Ветка polls-docker содержит Dockerized версию этого приложения для опросов. Чтобы узнать, как было изменено приложение «Опросы» для эффективной работы в контейнерной среде, см. раздел «Как создать приложение Django и Gunicorn с помощью Docker».

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

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

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

    1. cd django-polls

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

    1. cat 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 использует официальный образ Python 3.7.4 Docker в качестве основы и устанавливает требования к пакетам Python для Django и Gunicorn, как определено в файле django-polls/requirements.txt. Затем он удаляет некоторые ненужные файлы сборки, копирует код приложения в образ и устанавливает PATH выполнения. Наконец, он объявляет, что порт 8000 будет использоваться для приема входящих подключений к контейнеру, и запускает gunicorn с 3 рабочими процессами, прослушивая порт 8000.

    Чтобы узнать больше о каждом из шагов в этом файле Docker, см. Шаг 6 в разделе Как создать приложение Django и Gunicorn с помощью Docker.

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

    1. docker build -t polls .

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

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

    1. 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 или вашего любимого редактора:

    1. nano 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_ALLOWED_HOSTS: эта переменная защищает приложение и предотвращает атаки на HTTP-заголовки узла. В целях тестирования установите для этого параметра значение *, подстановочный знак, который будет соответствовать всем хостам. В производственной среде вы должны установить это значение your_domain.com. Чтобы узнать больше об этом параметре Django, обратитесь к основным параметрам в документации по Django.
    • DATABASE_USERNAME: укажите пользователя базы данных PostgreSQL, созданного на предварительных этапах.
    • DATABASE_NAME: задайте для этого параметра значение polls или имя базы данных PostgreSQL, созданной на предварительных этапах.
    • DATABASE_PASSWORD: укажите пароль пользователя PostgreSQL, созданный на предварительных этапах.
    • DATABASE_HOST: укажите имя хоста вашей базы данных.
    • DATABASE_PORT: укажите порт вашей базы данных.
    • STATIC_ACCESS_KEY_ID: укажите ключ доступа к пространству или хранилищу объектов.
    • STATIC_SECRET_KEY: задайте для этого секретный ключ доступа к пространству или хранилищу объектов.
    • STATIC_BUCKET_NAME: задайте для этого имя пространства или сегмент хранилища объектов.
    • STATIC_ENDPOINT_URL: укажите соответствующий URL-адрес конечной точки Spaces или хранилища объектов, например https://your_space_name.nyc3.digitaloceanspaces.com если ваше пространство находится в регионе nyc3.

    Закончив редактирование, сохраните и закройте файл.

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

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

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

    1. 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.

    1. docker run -i -t --env-file env polls sh

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

    1. python manage.py createsuperuser

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

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

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

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

    Output
    121 static files copied.

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

    1. 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 Page Not Found, чего и следовало ожидать.

    Перейдите к http://localhost/polls, чтобы увидеть интерфейс приложения «Опросы»:

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

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

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

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

    Когда вы закончите исследование, нажмите 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 и извлечении личных образов, см. раздел Извлечение образа из частного реестра в документации Kubernetes.

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

    1. docker login
    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:

    1. docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest

    Отправьте изображение в репозиторий:

    1. 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 переменные конфигурации можно внедрять с помощью секретов.

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

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

    1. mkdir yaml
    2. cd

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

    1. nano polls-configmap.yaml

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

    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:

    1. kubectl apply -f polls-configmap.yaml
    Output
    configmap/polls-config created

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

    Шаг 5 — Настройка секрета

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

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

    1. cp ../env ./polls-secrets

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

    1. nano 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. Когда вы закончите, это должно выглядеть так:

    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. Когда вы закончите, сохраните и закройте файл.

    Создайте секрет в своем кластере с помощью kubectl create secret:

    1. kubectl create secret generic polls-secret --from-env-file=poll-secrets
    Output
    secret/polls-secret created

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

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

    1. 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 с помощью развертывания

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

    Развертывания контролируют один или несколько подов, наименьшую развертываемую единицу в кластере Kubernetes. Поды заключают в себе один или несколько контейнеров. Чтобы узнать больше о различных типах рабочих нагрузок, которые вы можете запускать, ознакомьтесь с An Introduction to Kubernetes.

    Начните с открытия файла polls-deployment.yaml в вашем любимом редакторе:

    1. nano 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 с именем polls-app и помечаем его парой ключ-значение app: polls. Мы указываем, что хотим запустить две реплики пода, определенные под полем template.

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

    Наконец, мы открываем containerPort 8000 и называем его gunicorn.

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

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

    Создайте развертывание в своем кластере с помощью kubectl apply -f:

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

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

    1. kubectl get deploy polls-app
    Output
    NAME READY UP-TO-DATE AVAILABLE AGE polls-app 2/2 2 2 6m38s

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

    1. kubectl describe deploy

    Вы можете проверить два модуля с помощью kubectl get pod:

    1. 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, что мы и сделаем дальше.

    Шаг 7 — Разрешение внешнего доступа с помощью службы

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

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

    В нашей окончательной настройке мы будем использовать службу ClusterIP, которая предоставляется с помощью Ingress и Ingress Controller, настроенных в предварительных условиях для этого руководства. А пока, чтобы проверить, что все работает правильно, мы создадим временную службу NodePort для доступа к приложению Django.

    Начните с создания файла polls-svc.yaml с помощью вашего любимого редактора:

    1. nano 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.

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

    Разверните службу с помощью kubectl apply:

    1. kubectl apply -f polls-svc.yaml
    Output
    service/polls created

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

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

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

    1. kubectl get node -o wide
    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

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

    Вы должны увидеть тот же интерфейс приложения «Опросы», к которому вы обращались локально на шаге 1:

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

    На данном этапе вы развернули две реплики контейнера приложения Django Polls с помощью файла Deployment. Вы также создали стабильную сетевую конечную точку для этих двух реплик и сделали ее доступной извне с помощью службы NodePort.

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

    Шаг 8 — Настройка HTTPS с помощью Nginx Ingress и cert-manager

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

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

    1. kubectl delete ingress echo-ingress

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

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

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

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

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

    1. nano 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 Controller ingress-nginx и промежуточный ClusterIssuer. Мы также включаем TLS для your_domain.com и сохраняем сертификат и закрытый ключ в секрете под названием polls-tls. Наконец, мы определяем правило для маршрутизации трафика для хоста your_domain.com в службу polls через порт 8000.

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

    Создайте Ingress в своем кластере с помощью kubectl apply:

    1. kubectl apply -f polls-ingress.yaml
    Output
    ingress.networking.k8s.io/polls-ingress created

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

    1. 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, чтобы дополнительно подтвердить его успешное создание:

    1. 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 из командной строки:

    1. 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, чтобы обойти проверку сертификата:

    1. 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 для редактирования:

    1. nano 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:

    1. kubectl apply -f polls-ingress.yaml
    Output
    ingress.networking.k8s.io/polls-ingress configured

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

    1. 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"

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

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

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

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

    Измените polls-svc.yaml с помощью вашего редактора:

    1. nano polls-svc.yaml

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

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

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

    Внесите изменения с помощью kubectl apply:

    1. kubectl apply -f polls-svc.yaml --force
    Output
    service/polls configured

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

    1. kubectl get svc polls
    Output
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls ClusterIP 10.245.203.186 <none> 8000/TCP 22s

    Эти выходные данные показывают, что тип службы теперь ClusterIP. Единственный способ получить к нему доступ — через ваш домен и Ingress, созданный на этом шаге.

    Заключение

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

    Если вы используете пространство DigitalOcean, вы также можете включить доставку статических ресурсов через сеть доставки контента и создать собственный субдомен для своего пространства. Чтобы узнать больше, обратитесь к разделу «Включение CDN» из статьи «Как настроить масштабируемое приложение Django с базами данных и пространствами, управляемыми DigitalOcean».

    Чтобы просмотреть остальную часть серии, посетите нашу страницу серии From Containers to Kubernetes с Django.