В этом учебном модуле мы развернем контейнеризованное приложение Django polls в кластере Kubernetes.
Django — это мощная веб-структура, позволяющая быстро развернуть ваше приложение Python с нуля. Она включает ряд удобных функций, в том числе реляционную карту объектов, аутентификацию пользователей и настраиваемый административный интерфейс для вашего приложения. Также она включает систему кэширования и помогает проектировать оптимизированные приложения с помощью диспетчера URL и системы шаблонов.
В учебном модуле Создание приложения Django и Gunicorn с помощью Docker мы изменили приложение Polls из учебного модуля Django согласно методологии Двенадцать факторов, предназначенной для построения масштабируемых веб-приложений, оптимизированных для работы в облаке. Для масштабирования и защиты контейнера использовался обратный прокси-сервер Nginx и подписанный Let’s Encrypt сертификат TLS (см. описание в учебном модуле Масштабирование и защита приложения Django с помощью Docker, Nginx и Let’s Encrypt). В этом последнем учебном модуле из серии От контейнеров к Kubernetes с Django мы покажем, как развернуть модернизированное приложение Django polls в кластере Kubernetes.
Kubernetes — мощная система оркестрации контейнеров с открытым исходным кодом, помогающая автоматизировать развертывание, масштабирование и управление контейнеризованными приложениями. Такие объекты Kubernetes как ConfigMaps и Secrets позволяют централизовать конфигурацию и отсоединить ее от контейнеров, а такие контроллеры как Deployments автоматически перезагружают неработающие контейнеры и позволяют быстро масштабировать реплики контейнеров. Шифрование TLS активируется с помощью объекта Ingress и контроллера ingress-nginx с открытым исходным кодом. Надстройка Kubernetes cert-manager проверяет и выпускает сертификаты, используя бесплатный центр сертификации Let’s Encrypt.
Для данного обучающего модуля вам потребуется следующее:
kubectl
, установленный на локальном компьютере и настроенный для подключения к вашему кластеру. Дополнительную информацию об установке kubectl
можно найти в официальной документации. Если вы используете кластер DigitalOcean Kubernetes, ознакомьтесь с руководством Подключение к кластеру DigitalOcean Kubernetes, чтобы узнать, как подключиться к кластеру с помощью kubectl
.your_domain.com
. Вы можете получить бесплатный домен на Freenom или зарегистрировать доменное имя по вашему выбору.A
для your_domain.com
, указывающая на публичный IP-адрес балансировщика нагрузки Ingress. Если вы используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A
.Проверив наличие этих компонентов, вы можете начать прохождение этого обучающего модуля.
На этом шаге мы клонируем код приложения с GitHub и настроим такие параметры, как учетные данные БД и ключи хранения объектов.
Код приложения и файл Dockerfile можно найти в ветви polls-docker
репозитория Django Tutorial Polls App на GitHub. Этот репозиторий содержит код приложения Polls, используемого в документации по Django в качестве образца, на примере которого показывается, как создать приложение для опросов с нуля.
Ветвь polls-docker
содержит размещенную в контейнере Docker версию приложения Polls. Более подробную информацию об изменениях, внесенных в приложение Polls для эффективной работы в контейнеризированной среде, можно найти в руководстве Создание приложения Django и Gunicorn с помощью Docker.
Для начала используйте git
, чтобы клонировать ветвь polls-docker
репозитория Django Tutorial Polls App на GitHub на локальном компьютере:
- git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git
Перейдите в каталог django-polls
:
- 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 используется официальный образ Docker Python 3.7.4, который устанавливает требуемые пакеты Python для Django и Gunicorn в соответствии с файлом django-polls/requirements.txt
. Затем он удаляет некоторые ненужные файлы сборки, копирует код приложения в образ и устанавливает параметр выполнения PATH
. И в заключение заявляет, что порт 8000
будет использоваться для принятия входящих подключений контейнера, и запускает gunicorn
с тремя рабочими элементами, прослушивающими порт 8000
.
Дополнительную информацию о каждом этапе в Dockerfile см. в шаге 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.DJANGO_ALLOWED_HOSTS
: эта переменная защищает приложение и предотвращает атаки через заголовки хоста HTTP. С целью тестирования установите *
как подстановочный символ, подходящий для всех хостов. В производственной среде следует использовать значение your_domain.com
. Дополнительную информацию об этой настройке Django см. в разделе Core Settings (Базовые настройки) документации Django.DATABASE_USERNAME
: задает пользователя базы данных PostgreSQL, созданного на предварительных этапах.DATABASE_NAME
: задает polls
или имя базы данных, созданной на предварительных этапах.DATABASE_PASSWORD
: задает пароль пользователя базы данных PostgreSQL, созданного на предварительных этапах.DATABASE_HOST
: задает имя хоста базы данных.DATABASE_PORT
: укажите порт вашей базы данных.STATIC_ACCESS_KEY_ID
: укажите ключ доступа своего пространства или хранилища объектов.STATIC_SECRET_KEY
: укажите секретный ключ своего пространства или хранилища объектов.STATIC_BUCKET_NAME
: укажите имя своего пространства или корзину хранилища объектов.STATIC_ENDPOINT_URL
: укажите URL соответствующего пространства или конечного пункта хранилища объектов, например https://your_space_name.nyc3.digitaloceanspaces.com
, если ваше пространство находится в области nyc3
.После завершения редактирования сохраните и закройте файл.
На следующем шаге мы запустим настроенный контейнер в локальной среде и создадим схему базы данных. Также мы выгрузим в хранилище объектов статические ресурсы, такие как таблицы стилей и изображения.
После построения и настройки контейнера используйте 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 Страница не найдена
.
Введите в адресную строку http://localhost/polls
, чтобы увидеть интерфейс приложения Polls:
Чтобы открыть интерфейс администрирования, введите адрес http://localhost/admin
. Вы должны увидеть окно аутентификации администратора приложения «Опросы»:
Введите имя администратора и пароль, которые вы создали с помощью команды createsuperuser
.
После аутентификации вы сможете получить доступ к административному интерфейсу приложения «Опросы»:
Обратите внимание, что статические активы приложений admin
и polls
поступают напрямую из хранилища объекта. Чтобы убедиться в этом, ознакомьтесь с материалами Тестирование доставки статических файлов пространства.
После завершения изучения данных нажмите CTRL+C
в окне терминала, где запущен контейнер Docker, чтобы удалить контейнер.
Когда образ Docker приложения Django будет протестирован, статичные ресурсы будут выгружены в хранилище объектов, а схема базы данных будет настроена и готова к выгрузке образа приложения Django в реестр образов, например в Docker Hub.
Чтобы развернуть приложение в Kubernetes, необходимо будет выгрузить образ приложения в реестр, например, в Docker Hub. Kubernetes извлечет образ приложения из репозитория, а затем развернет его в кластере.
Вы можете использовать частный реестр Docker, например, реестр контейнеров DigitalOcean Container Registry, предварительная версия которого в настоящее время предоставляется бесплатно, или публичный реестр Docker, такой как Docker Hub. Docker Hub также позволяет создавать частные репозитории Docker. Публичный репозиторий позволяет любому пользователю видеть и извлекать образы контейнеров, а в частном репозитории доступ имеется только у вас и у членов вашей команды.
В этом учебном модуле мы разместим образ Django в публичном репозитории Docker Hub, созданном на этапе предварительных требований. Также вы можете перенести образ в частный репозиторий, однако извлечение образов из частного репозитория в этой статье не описывается. Чтобы получить более подробную информацию об аутентификации Kubernetes с Docker Hub и извлечении образов из частного репозитория, ознакомьтесь со статьей Pull an Image from a Private Registry (Извлечение образа из частного реестра) в документации по Kubernetes.
Для начала выполните вход в Docker Hub на локальном компьютере:
- 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, и вы можете начать его развертывание в своем кластере.
При локальном запуске контейнера Django мы передали файл env
в docker run
для вставки переменных конфигурации в среду исполнения. Для вставки переменных конфигурации в Kubernetes используются элементы ConfigMap и Secret.
Элементы ConfigMap следует использовать для сохранения неконфиденциальной информации о конфигурации, такой как параметры приложения, а элементы Secret следует использовать для хранения важной информации, такой как ключи API и учетные данные для входа в базу данных. Они вставляются в контейнеры примерно одинаково, но у элементов Secret имеются дополнительные функции контроля доступа и безопасности, такие как шифрование в состоянии покоя. Элементы Secret хранят данные в формате base64, а элементы ConfigMap хранят данные в формате обычного текста.
Для начала необходимо создать каталог 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, а на следующем шаге мы создадим элемент Secret, который будет использоваться нашим приложением.
Значения Secret должны иметь кодировку base64, то есть создавать объекты Secret в кластере немного сложнее, чем объекты ConfigMaps. Вы можете повторить описанную на предыдущем шаге процедуру, выполнив кодирование значений 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. Закончив, сохраните и закройте файл.
Создайте в кластере объект Secret, используя kubectl create secret
:
- kubectl create secret generic polls-secret --from-env-file=poll-secrets
Outputsecret/polls-secret created
Здесь мы создадим объект Secret с именем polls-secret
и передадим в него созданный нами файл secrets.
Вы можете проинспектировать объект Secret, используя kubectl describe
:
- 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. Мы готовы развернуть приложение в кластере.
На этом шаге мы создадим Deployment для вашего приложения Django. Kubernetes Deployment — контроллер, который можно использовать для управления приложениями без состояния в вашем кластере. Контроллер — это контур управления, регулирующий рабочие задачи посредством вертикального масштабирования. Контроллеры также перезапускают и очищают неисправные контейнеры.
Контроллеры Deployment контролируют один или несколько подов. Под — это наименьшая развертываемая единица в кластере Kubernetes. Поды содержат один или несколько контейнеров. Чтобы узнать о различных типах рабочих задач, ознакомьтесь с учебным модулем Введение в Kubernetes.
Для начала откройте файл polls-deployment.yaml
в предпочитаемом текстовом редакторе:
- nano polls-deployment.yaml
Вставьте в него следующий манифест Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: polls-app
labels:
app: polls
spec:
replicas: 2
selector:
matchLabels:
app: polls
template:
metadata:
labels:
app: polls
spec:
containers:
- image: your_dockerhub_username/app_repo_name:latest
name: polls
envFrom:
- secretRef:
name: polls-secret
- configMapRef:
name: polls-config
ports:
- containerPort: 8000
name: gunicorn
Введите соответствующее имя образа контейнера, ссылаясь на образ Django Polls, который вы разместили в Docker Hub на шаге 2.
Здесь мы определяем контроллер Kubernetes Deployment с именем polls-app
и присваиваем ему пару ключ-значение app: polls
. Мы указываем, что хотим запустить две реплики пода, определенного под полем template
.
Используя envFrom
с secretRef
и configMapRef
, мы указываем, что все данные из объектов polls-secret
и polls-config
следует вставить в контейнеры как переменные среды. Ключи ConfigMap и Secret становятся именами переменных среды.
В заключение мы откроем порт containerPort
8000
и назовем его gunicorn
.
Чтобы узнать больше о настройке контроллеров Kubernetes Deployment, ознакомьтесь с разделом Deployments в документации по Kubernetes.
Когда вы завершите редактирование файла, сохраните и закройте его.
Создайте в кластере контроллер Deployment, используя kubectl apply -f
:
- kubectl apply -f polls-deployment.yaml
- deployment.apps/polls-app created
Убедитесь, что контроллер Deployment развернут правильно, используя kubectl get
:
- kubectl get deploy polls-app
OutputNAME READY UP-TO-DATE AVAILABLE AGE
polls-app 2/2 2 2 6m38s
Если вы столкнетесь с ошибкой или что-то не будет работать, вы можете использовать kubectl describe
для проверки неработающего контроллера Deployment:
- 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 Service, и мы сделаем это на следующем шаге.
На этом шаге мы создаем Service для нашего приложения Django. Kubernetes Service — это абстракция, позволяющая предоставить доступ к набору работающих подов как к сетевой службе. Используя Service, вы можете создать для вашего приложения стабильный конечный пункт, который не будет изменяться по мере уничтожения и воссоздания подов.
Существует несколько типов служб Service, в том числе службы ClusterIP, открывающие доступ к Service через внутренний IP-адрес кластера, службы NodePort, открывающие доступ к Service на каждом узле статического порта NodePort, и службы LoadBalancer, предоставляющие облачный балансировщик нагрузки для управления внешним трафиком подов вашего кластера (через порты NodePort, которые он создает автоматически). Чтобы узнать больше об этом, ознакомьтесь с разделом Service в документации по Kubernetes.
На заключительном шаге настройки мы используем службу ClusterIP Service, доступ к которой открыт через Ingress и контроллер Ingress, настроенный на этапе подготовки к этому учебному модулю. Сейчас мы убедимся, что все элементы работают корректно. Для этого мы создадим временную службу NodePort Service для доступа к приложению Django.
Для начала создайте файл с именем polls-svc.yaml
в предпочитаемом редакторе:
- nano polls-svc.yaml
Вставьте в него следующий манифест Service:
apiVersion: v1
kind: Service
metadata:
name: polls
labels:
app: polls
spec:
type: NodePort
selector:
app: polls
ports:
- port: 8000
targetPort: 8000
Здесь мы создаем службу NodePort под названием polls
и присваиваем ей ярлык app: polls
. Мы выберем поды серверной части с ярлыком app: polls
и установим в качестве цели порты 8000
.
Когда вы завершите редактирование файла, сохраните и закройте его.
Разверните Service с помощью команды kubectl apply
:
- kubectl apply -f polls-svc.yaml
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-адрес кластера службы и номер порта NodePort (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
Откройте в браузере приложение Polls, используя внешний IP-адрес и порт NodePort любого узла. С учетом приведенного выше вывода URL приложения будет выглядеть так: http://203.0.113.1:32654/polls
.
Вы должны увидеть тот же интерфейс приложения Polls, который вы открыли локально на шаге 1:
Вы можете повторить ту же проверку, используя маршрут /admin
: http://203.0.113.1:32654/admin
. Вы увидите тот же интерфейс администрирования, что и раньше:
Мы развернули две реплики контейнера приложения Django Polls, используя Deployment. Также мы создали стабильный конечный пункт сети для этих двух реплик и обеспечили внешний доступ к ним через службу NodePort.
Заключительный шаг этого учебного модуля заключается в том, чтобы защитить внешний трафик нашего приложения, используя HTTPS. Для этого мы используем контроллер ingress-nginx
, установленный на этапе предварительных требований, и создадим объект Ingress для перенаправления внешнего трафика в службу Kubernetes polls
.
Сущности Ingress в Kubernetes обеспечивают гибкую маршрутизацию внешнего трафика кластера Kubernetes среди служб внутри кластера. Это достигается с помощью ресурсов Ingress, которые определяют правила маршрутизации трафика HTTP и HTTPS для служб Kubernetes, и контроллеров Ingress, которые реализуют правила посредством балансировки нагрузки трафика и его перенаправления на соответствующие службы серверной части.
На этапе предварительных требований мы установили контроллер ingress-nginx и надстройку cert-manager для автоматизации сертификатов TLS. Также мы настроили испытательную и производственную среду ClusterIssuers для вашего домена, используя центр сертификации Let’s Encrypt, и создали объект Ingress для проверки выдачи сертификатов и шифрования TLS для двух фиктивных серверных служб. Прежде чем продолжить выполнение этого шага, удалите объект echo-ingress
, созданный в подготовительном учебном модуле:
- kubectl delete ingress echo-ingress
При желании вы также можете удалить фиктивные службы и развертывания, используя команды kubectl delete svc
и kubectl delete deploy
, но для прохождения этого учебного модуля это не обязательно.
Также вы должны были создать запись DNS типа A
для your_domain.com
, указывающую на публичный IP-адрес балансировщика нагрузки Ingress. Если вы используете балансировщик нагрузки DigitalOcean, вы можете найти этот IP-адрес в разделе Load Balancers панели управления. Если вы также используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A
.
Если вы используете DigitalOcean Kubernetes, убедитесь, что вы внедрили обходное решение, описанное в шаге 5 учебного модуля Настройка Nginx Ingress с помощью Cert-Manager в DigitalOcean Kubernetes.
Когда у вас будет запись A
, указывающая на балансировщик нагрузки контроллера Ingress, вы можете создать Ingress для your_domain.com
и службы polls
.
Откройте файл с именем polls-ingress.yaml
в предпочитаемом текстовом редакторе:
- 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-nginx и размещение ClusterIssuer. Также мы включаем TLS для домена your_domain.com
и сохраняем сертификат и закрытый ключ в объекте Secret с именем polls-tls
. В заключение мы определяем правило перенаправления трафика для хоста your_domain.com
в службу polls
через порт 8000
.
Когда вы завершите редактирование файла, сохраните и закройте его.
Создайте в кластере объект Ingress, используя kubectl apply
:
- kubectl apply -f polls-ingress.yaml
Outputingress.networking.k8s.io/polls-ingress created
Вы можете использовать kubectl describe
для отслеживания состояния только что созданного объекта 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 describe certificate polls-tls
и kubectl describe ingress polls-ingress
для отслеживания статуса выдачи сертификата:
- kubectl describe ingress polls-ingress
Output. . .
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 23m nginx-ingress-controller Ingress default/polls-ingress
Normal CreateCertificate 23m cert-manager Successfully created Certificate "polls-tls"
Normal UPDATE 76s (x2 over 22m) nginx-ingress-controller Ingress default/polls-ingress
Normal UpdateCertificate 76s cert-manager Successfully updated Certificate "polls-tls"
Приведенный выше вывод подтверждает, что новый производственный сертификат успешно выдан и сохранен в объекте Secret polls-tls
.
Откройте в браузере адрес your_domain.com/polls
, чтобы убедиться, что шифрование HTTPS включено, и все работает ожидаемым образом. Вы должны увидеть интерфейс приложения Polls:
Убедитесь, что в браузере включено шифрование HTTPS. Если вы используете Google Chrome, то если вышеуказанная страница откроется без ошибок, это будет означать, что все работает правильно. Кроме того, на панели URL должно быть изображение замка. Нажав на замок, вы сможете просмотреть детали сертификата Let’s Encrypt.
Для окончательной очистки вы можете переключить тип службы polls
с NodePort на внутренний тип ClusterIP.
Отредактируйте файл polls-svc.yaml
в текстовом редакторе:
- 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
Убедитесь, что служба Service была изменена, используя 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
Этот вывод показывает, что тип Service — ClusterIP. Для доступа можно использовать только домен и Ingress, созданный на этом шаге.
В этом учебном модуле мы развернули масштабируемое приложение Django с защитой HTTPS в кластере Kubernetes. Статичный контент выдается напрямую из хранилища объектов, а количество работающих подов можно быстро увеличивать или уменьшать, используя поле replicas
в манифесте Deployment polls-app
.
Если вы используете пространство DigitalOcean Space, вы также можете включить доставку статичных ресурсов через сеть доставки контента и создать настраиваемый субдомен для своего пространства. Дополнительную информацию можно найти в разделе Включение CDN учебного модуля Настройка масштабируемого приложения Django с управляемыми базами данных и пространствами DigitalOcean.
С остальными частями серии можно ознакомиться на странице От контейнеров к Kubernetes с Django.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.