Как развернуть масштабируемое и безопасное приложение 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 на локальный компьютер:- git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git
Перейдите в каталог
django-polls
:- cd django-polls
Этот каталог содержит код Python приложения Django, файл
Dockerfile
, который Docker будет использовать для создания образа контейнера, а также файлenv
, содержащий список переменных среды, которые необходимо передается в рабочую среду контейнера. ПроверьтеDockerfile
:- cat Dockerfile
OutputFROM 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
:- docker build -t polls .
Мы называем изображение
polls
, используя флаг-t
, и передаем текущий каталог в качестве контекста сборки, набора файлов, на которые нужно ссылаться при построении. Изображение.После того, как Docker соберет образ и пометит его тегами, выведите список доступных образов с помощью
docker images
:- 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
или вашего любимого редактора:- 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
:- 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
, который создаст схему базы данных, определенную кодом приложения.Если вы запускаете это в первый раз, вы должны увидеть:
OutputNo changes detected Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying polls.0001_initial... OK Applying sessions.0001_initial... OKЭто означает, что схема базы данных успешно создана.
Если вы запустите
migrate
в следующий раз, Django не выполнит операцию, если схема базы данных не изменилась.Далее мы запустим еще один экземпляр контейнера приложения и используем внутри него интерактивную оболочку, чтобы создать пользователя-администратора для проекта Django.
- docker run -i -t --env-file env polls sh
Это предоставит вам приглашение оболочки внутри работающего контейнера, которое вы можете использовать для создания пользователя Django:
- python manage.py createsuperuser
Введите имя пользователя, адрес электронной почты и пароль для своего пользователя, а после создания пользователя нажмите
CTRL+D
, чтобы выйти из контейнера и убить его.Наконец, мы создадим статические файлы для приложения и загрузим их в пространство DigitalOcean с помощью
collectstatic
. Обратите внимание, что это может занять некоторое время.- docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"
После того, как эти файлы будут сгенерированы и загружены, вы получите следующий вывод.
Output121 static files copied.Теперь мы можем запустить приложение:
- docker run --env-file env -p 80:8000 polls
Output[2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0 [2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) [2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync [2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7 [2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8 [2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9Здесь мы запускаем команду по умолчанию, определенную в Dockerfile,
gunicorn --bind :8000 --workers 3 mysite.wsgi:application
, и предоставляем порт контейнера8000
, чтобы порт80
на вашем локальном компьютере сопоставляется с портом8000
контейнераpolls
.Теперь вы сможете перейти к приложению
polls
с помощью веб-браузера, введяhttp://localhost
в адресной строке. Поскольку для пути/
не определен маршрут, вы, скорее всего, получите сообщение об ошибке404 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 на локальном компьютере:
- docker login
OutputLogin with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username:Введите имя пользователя и пароль Docker Hub для входа.
В настоящее время изображение Django имеет тег
polls:latest
. Чтобы отправить его в репозиторий Docker Hub, повторно пометьте образ своим именем пользователя и именем репозитория Docker Hub:- docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest
Отправьте изображение в репозиторий:
- docker push sammy/sammy-django:latest
В этом руководстве имя пользователя Docker Hub — sammy, а имя репозитория — sammy-django. Вы должны заменить эти значения своим собственным именем пользователя Docker Hub и именем репозитория.
Вы увидите некоторый вывод, который обновляется по мере того, как слои изображения отправляются в Docker Hub.
Теперь, когда ваш образ доступен для Kubernetes в Docker Hub, вы можете приступить к его развертыванию в своем кластере.
Шаг 4 — Настройка ConfigMap
Когда мы запускали контейнер Django локально, мы передавали файл
env
вdocker run
, чтобы внедрить переменные конфигурации в среду выполнения. В Kubernetes переменные конфигурации можно внедрять с помощью секретов.ConfigMaps следует использовать для хранения неконфиденциальной информации о конфигурации, такой как настройки приложения, а секреты следует использовать для конфиденциальной информации, такой как ключи API и учетные данные базы данных. Оба они внедряются в контейнеры одинаковым образом, но секреты имеют дополнительные функции контроля доступа и безопасности, такие как шифрование в состоянии покоя. Секреты также хранят данные в формате base64, тогда как ConfigMaps хранят данные в виде обычного текста.
Для начала создайте каталог с именем
yaml
, в котором мы будем хранить наши манифесты Kubernetes. Перейдите в каталог.- mkdir yaml
- cd
Откройте файл с именем
polls-configmap.yaml
вnano
или предпочитаемом вами текстовом редакторе:- 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
:- kubectl apply -f polls-configmap.yaml
Outputconfigmap/polls-config createdСоздав ConfigMap, мы создадим секрет, используемый нашим приложением на следующем шаге.
Шаг 5 — Настройка секрета
Секретные значения должны быть закодированы в base64, что означает, что создание секретных объектов в вашем кластере требует немного больше усилий, чем создание ConfigMap. Вы можете повторить процесс из предыдущего шага, вручную закодировав значения Secret в base64 и вставив их в файл манифеста. Вы также можете создать их с помощью файла переменной среды,
kubectl create
и флага--from-env-file
, что мы и сделаем на этом шаге.Мы снова воспользуемся файлом
env
из шага 1, удалив переменные, вставленные в ConfigMap. Сделайте копию файлаenv
с именемpolls-secrets
в каталогеyaml
:- cp ../env ./polls-secrets
Отредактируйте файл в предпочитаемом вами редакторе:
- 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
:- kubectl create secret generic polls-secret --from-env-file=poll-secrets
Outputsecret/polls-secret createdЗдесь мы создаем секретный объект с именем
polls-secret
и передаем только что созданный файл секретов.Вы можете проверить секрет, используя
kubectl описать
:- kubectl describe secret polls-secret
OutputName: 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
в вашем любимом редакторе:- 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
:- kubectl apply -f polls-deployment.yaml
- deployment.apps/polls-app created
Убедитесь, что развертывание развернуто правильно, используя
kubectl get
:- kubectl get deploy polls-app
OutputNAME READY UP-TO-DATE AVAILABLE AGE polls-app 2/2 2 2 6m38sЕсли вы столкнулись с ошибкой или что-то не работает, вы можете использовать
kubectl описать
для проверки неудачного развертывания:- kubectl describe deploy
Вы можете проверить два модуля с помощью
kubectl get pod
:- kubectl get pod
OutputNAME 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
с помощью вашего любимого редактора:- 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
:- kubectl apply -f polls-svc.yaml
Outputservice/polls createdПодтвердите, что ваша служба была создана с помощью
kubectl get svc
:- kubectl get svc polls
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls NodePort 10.245.197.189 <none> 8000:32654/TCP 59sЭти выходные данные показывают внутренний IP-адрес и порт узла службы (
32654
). Для подключения к сервису нам нужны внешние IP-адреса для узлов нашего кластера:- kubectl get node -o wide
OutputNAME 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, реализующих правила путем балансировки нагрузки и маршрутизации трафика в соответствующие серверные службы.
В предварительных условиях вы установили необходимое руководство:
- 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
в своем любимом редакторе:- 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
:- kubectl apply -f polls-ingress.yaml
Outputingress.networking.k8s.io/polls-ingress createdВы можете использовать
kubectl описать
для отслеживания состояния только что созданного Ingress:- kubectl describe ingress polls-ingress
OutputName: polls-ingress Namespace: default Address: workaround.your_domain.com Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) TLS: polls-tls terminates your_domain.com Rules: Host Path Backends ---- ---- -------- your_domain.com polls:8000 (10.244.0.207:8000,10.244.0.53:8000) Annotations: cert-manager.io/cluster-issuer: letsencrypt-staging kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 51s nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 51s cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 25s nginx-ingress-controller Ingress default/polls-ingressВы также можете запустить
describe
для сертификатаpolls-tls
, чтобы дополнительно подтвердить его успешное создание:- kubectl describe certificate polls-tls
Output. . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 3m33s cert-manager Issuing certificate as Secret does not exist Normal Generated 3m32s cert-manager Stored new private key in temporary Secret resource "polls-tls-v9lv9" Normal Requested 3m32s cert-manager Created new CertificateRequest resource "polls-tls-drx9c" Normal Issuing 2m58s cert-manager The certificate has been successfully issuedЭто подтверждает, что сертификат TLS был успешно выдан и шифрование HTTPS теперь активно для
your_domain.com
.Учитывая, что мы использовали промежуточный ClusterIssuer, большинство веб-браузеров не будут доверять выданному им поддельному сертификату Let’s Encrypt, поэтому при переходе на
your_domain.com
вы попадете на страницу с ошибкой.Чтобы отправить тестовый запрос, мы будем использовать
wget
из командной строки:- wget -O - http://your_domain.com/polls
Output. . . ERROR: cannot verify your_domain.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to your_domain.com insecurely, use `--no-check-certificate'.Мы будем использовать предложенный флаг
--no-check-certificate
, чтобы обойти проверку сертификата:- wget --no-check-certificate -q -O - http://your_domain.com/polls
Output<link rel="stylesheet" type="text/css" href="https://your_space.nyc3.digitaloceanspaces.com/django-polls/static/polls/style.css"> <p>No polls are available.</p>Эти выходные данные показывают HTML для страницы интерфейса
/polls
, а также подтверждают, что таблица стилей обслуживается из хранилища объектов.Теперь, когда вы успешно протестировали выдачу сертификата с помощью промежуточного ClusterIssuer, вы можете изменить Ingress для использования производственного ClusterIssuer.
Еще раз откройте
polls-ingress.yaml
для редактирования:- 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
:- kubectl apply -f polls-ingress.yaml
Outputingress.networking.k8s.io/polls-ingress configuredВы можете использовать
kubectl описать опросы сертификатов-tls
иkubectl описать входящие опросы-ingress
для отслеживания статуса выдачи сертификата:- kubectl describe ingress polls-ingress
Output. . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 23m nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 23m cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 76s (x2 over 22m) nginx-ingress-controller Ingress default/polls-ingress Normal UpdateCertificate 76s cert-manager Successfully updated Certificate "polls-tls"Приведенный выше вывод подтверждает, что новый производственный сертификат был успешно выдан и сохранен в секрете
polls-tls
.Перейдите на страницу
your_domain.com/polls
в веб-браузере, чтобы убедиться, что шифрование HTTPS включено и все работает должным образом. Вы должны увидеть интерфейс приложения «Опросы»:Убедитесь, что шифрование HTTPS активно в вашем веб-браузере. Если вы используете Google Chrome, появление вышеуказанной страницы без каких-либо ошибок подтверждает, что все работает правильно. Кроме того, вы должны увидеть замок в адресной строке. Нажав на замок, вы сможете просмотреть детали сертификата Let’s Encrypt.
В качестве последней задачи по очистке вы можете при желании переключить тип службы
polls
с NodePort на тип ClusterIP только для внутреннего использования.Измените
polls-svc.yaml
с помощью вашего редактора:- 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
:- kubectl apply -f polls-svc.yaml --force
Outputservice/polls configuredПодтвердите, что ваша служба была изменена с помощью
kubectl get svc
:- kubectl get svc polls
OutputNAME 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.