介绍
在本教程中,您将部署一个集装箱化的Django调查应用程序到Kubernetes集群中。
[Django] (https://www.djangoproject.com/)是一个强大的网络框架,可以帮助您快速地将您的Python应用程序从地上取出. 它包括几个方便的功能,如对象-关系映射器,用户认证,以及您应用程序的自定义的行政界面. 它还包括一个搜索框架,并通过其URL调度机和Template system鼓励清洁应用设计.
在"如何用多克来构建 Django 和 Gunicorn 应用程序"(https://andsky.com/tech/tutorials/how-to-build-a-django-and-gunicorn-application-with-docker)中,Django Tutorial Polls 应用程序被按照 12-Factor方法修改,用于构建可伸缩的,云族的网络应用程序. 这种被装入容器的设置被放大并加装了Nginx倒置代用并加密了 [How To Scale and Secure a Django applications with Docker, Nginx, and Let's Encrypt] (https://andsky.com/tech/tutorials/how-to-scale-and-secure-a-django-application-with-docker-nginx-and-let-s-encrypt) 的由加密签名的TLS证书. 在[从集装箱到与Django的Kubernetes]系列(https://www.digitalocean.com/community/tutorial_series/from-containers-to-kubernetes-with-django)的最后辅导中,现代化的Django民意测验应用将部署到Kubernetes集群.
[Kubernetes] (https://kubernetes.io/)是一个强大的开源集装箱管弦乐器,能使集装箱化应用的部署,缩放和管理自动化. Kubernetes 等对象 ConfigMaps and Secrets 允许您从容器中集中并解析配置,而部署等控制器则自动重启已失效的容器并允许快速缩放容器复制. TLS 加密被启用,有入侵对象和 [engress-nginx] (https://github.com/kubernetes/ingress-nginx) 开源入侵控制器. [Cert-manager] (https://github.com/jetstack/cert-manager). Kubernetes 添加更新并使用免费的 [让我们加密] (https://letsencrypt.org/) 证书权限签发证书.
如果您正在寻找一个管理的Kubernetes托管服务,请查看我们的简单的,用于增长的管理的Kubernetes服务(https://www.digitalocean.com/products/kubernetes)。
前提条件
要遵循本教程,您将需要:
- 具有基于作用的存取控制的Kubernetes 1.15+集群(RBAC)启用. 此设置将使用 [数字Ocean Kubernetes] (https://www.digitalocean.com/products/kubernetes/]] 集群, 但是您可以自由地使用 [另一种方法] (https://andsky.com/tech/tutorials/how-to-create-a-kubernetes-cluster-using-kubeadm-on-ubuntu-18-04) 创建集群 。
- 联合国 在您的本地机器上安装了)。 如果您正在使用 DigitalOcean Kubernetes 集群,请参见[如何连接到 DigitalOcean Kubernetes 集群 (https://www.digitalocean.com/docs/kubernetes/how-to/connect-to-cluster/),学习如何使用
kubectl连接您的集群 。 - 一个已注册域名。 此教程将使用
your_ domain.com整个 您可以在 [Freenom] (http://www.freenom.com/en/index.html] 免费获取, 或者使用您选择的域注册员 。 - [英 (https://github.com/kubernetes/ingress-nginx) 入侵控制员和证书管理员 TLS 证书管理器安装在您的集群中, 并配置为发行 TLS 证书 。 为学习如何安装和配置带有证书管理器的入侵者,请咨询[如何在数字海洋库伯内特斯上安装带有证书管理器的Nginx入侵者(https://andsky.com/tech/tutorials/how-to-set-up-an-nginx-ingress-with-cert-manager-on-digitalocean-kubernetes)。
- A'DNS记录,并有`your_domain.com'指向入侵负载平衡器的公共IP地址。 如果您正在使用 DigitalOcean 来管理域名的 DNS 记录,请查看 [如何管理 DNS 记录 (https://www.digitalocean.com/docs/networking/dns/how-to/manage-records/) 学习如何创建 'A ' 记录
- 联合国 用于存储您 Django 项目的静态文件以及此空间的一组访问密钥的 S3 对象存储桶, 如 [数字海洋空间] (https://www.digitalocean.com/products/spaces/ ) 。 要学习如何创建空间,请查阅如何创建空间产品文档. 要学习如何为空间创建访问密钥,请咨询用访问密钥共享访问空间. 通过小的修改,您可以使用django-storages插件支持的任何对象存储服务.
- 用于您的 Django 应用程序的 PostgreSQL 服务器实例、数据库和用户。 通过小的修改,可以使用任何Django支持的数据库.
- PostgreSQL数据库应称为polls (或下面的配置文件中输入另一个值得纪念的名字),在此教程中,Django数据库用户将命名为** Sammy** 。 关于创建这些应用程序的指导,请遵循[如何用多克来构建Django和Gunicorn应用程序]的第1步(https://andsky.com/tech/tutorials/how-to-build-a-django-and-gunicorn-application-with-docker# step-1-%E2%80%94-creating-the-postgresql-database-and-user)。 你应该从你的本地机器上完成这些步骤。
- 本教程中使用了数字海洋(Managed PostgreSQL集群)(https://www.digitalocean.com/products/managed-databases/). 为学习如何创建集群,请查阅"数字海洋"管理数据库产品文档.
- 也可以安装和运行自己的 PostgreSQL 实例。 关于在 Ubuntu 服务器上安装和管理 PostgreSQL 的指南,请参见[如何安装和使用 Ubuntu 18.04 上的 PostgreSQL (https://andsky.com/tech/tutorials/how-to-install-and-use-postgresql-on-ubuntu-18-04).
- ADocker Hub帐户和公共存放处。 关于创建这些功能的更多信息,请参见Docker文档中的[仓库] (https://docs.docker.com/docker-hub/repos/).
- 安装在您本地机器上的多克引擎。 请参看[如何在Ubuntu 18.04上安装和使用多克 (https://andsky.com/tech/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04)来学习更多. .
一旦您设置了这些组件,您已经准备好开始使用本指南。
步骤1 - 克隆和配置应用程序
在此步骤中,我们将从 GitHub 克隆应用程序代码,并配置数据库凭证和对象存储密钥等设置。
应用程序代码和Dockerfile可以在Django Tutorial Polls App(github.com/do-community/django-polls/tree/polls-docker)的),该重组包含了Django文档的),教你如何从头开始构建投票应用程序。
要了解如何在容器化环境中有效地工作,请参阅 如何使用 Docker 构建 Django 和 Gunicorn 应用程序。
开始使用)到您的本地机器:
1git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git
导航到‘django-polls’目录:
1cd django-polls
该目录包含了Django应用程序Python代码,一个Dockerfile,Docker将用来构建容器图像,以及一个env文件,其中包含一份将环境变量列入容器运行环境的列表。
1cat Dockerfile
1[secondary_label Output]
2FROM python:3.7.4-alpine3.10
3
4ADD django-polls/requirements.txt /app/requirements.txt
5
6RUN set -ex \
7 && apk add --no-cache --virtual .build-deps postgresql-dev build-base \
8 && python -m venv /env \
9 && /env/bin/pip install --upgrade pip \
10 && /env/bin/pip install --no-cache-dir -r /app/requirements.txt \
11 && runDeps="$(scanelf --needed --nobanner --recursive /env \
12 | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
13 | sort -u \
14 | xargs -r apk info --installed \
15 | sort -u)" \
16 && apk add --virtual rundeps $runDeps \
17 && apk del .build-deps
18
19ADD django-polls /app
20WORKDIR /app
21
22ENV VIRTUAL_ENV /env
23ENV PATH /env/bin:$PATH
24
25EXPOSE 8000
26
27CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"]
这个多克文件使用官方的Python 3.7.4 [Docker image] (https://hub.docker.com/_/python)作为底盘,并安装了"django-polls/requiments.txt"文件中定义的Django和Gunicorn的Python包要求. 然后删除一些不必要的构建文件,将应用程序代码复制到图像中,并设置执行"PATH". 最后,它宣布,8000'港将用来接受即将进入的集装箱连接,并用3名工人在8000'港旁听,运行`gunicorn'.
有关此 Dockerfile中的每一个步骤的更多信息,请参阅 如何使用 Docker 构建 Django 和 Gunicorn 应用程序的第 6 步。
现在,使用docker build来构建图像:
1docker build -t polls .
我们使用t旗号命名图像调查,并在当前目录中作为 build context 传输,这是构建图像时要参考的文件集。
在 Docker 构建和标记图像后,使用docker 图像列出可用的图像:
1docker images
你应该看到列出的民意调查图像:
1OutputREPOSITORY TAG IMAGE ID CREATED SIZE
2polls latest 80ec4f33aae1 2 weeks ago 197MB
3python 3.7.4-alpine3.10 f309434dea3a 8 months ago 98.7MB
在运行Django容器之前,我们需要使用当前目录中存在的env文件来配置其运行环境,该文件将传入用于运行容器的docker run命令,Docker将将配置的环境变量注入容器的运行环境。
使用nano或您最喜欢的编辑器打开env文件:
1nano env
1[label django-polls/env]
2DJANGO_SECRET_KEY=
3DEBUG=True
4DJANGO_ALLOWED_HOSTS=
5DATABASE_ENGINE=postgresql_psycopg2
6DATABASE_NAME=polls
7DATABASE_USERNAME=
8DATABASE_PASSWORD=
9DATABASE_HOST=
10DATABASE_PORT=
11STATIC_ACCESS_KEY_ID=
12STATIC_SECRET_KEY=
13STATIC_BUCKET_NAME=
14STATIC_ENDPOINT_URL=
15DJANGO_LOGLEVEL=info
填写以下键的缺失值:
- `DJANGO-SECRET-KEY':将此设定为一个独特的、无法预测的价值,详见Django docs。 生成此密钥的一个方法是在 [可扩展 Django App (https://andsky.com/tech/tutorials/how-to-set-up-a-scalable-django-app-with-digitalocean-managed-databases-and-spaces step-5-%E2%80%94-adjusting-the-app-settings) 教程中的 [调整 App 设置 (https://andsky.com/tech/tutorials/how-to-set-up-a-scalable-django-app-with-digitalocean-managed-databases-and-spaces# step-5-%E2%80%94-adjusting-the-app-settings ) 中提供 。
- `DJANGO_ALLOUED-HOSTS': 这个变量可以保护应用程序,防止HTTP主机头攻击. 为测试目的, 将此设定为QQ, 一个匹配所有主机的通配符 。 在制作中,您应该将此设定为 )。
- `巴哈马-美国 ' : 设定为在先决条件步骤中创建的 PostgreSQL 数据库用户 。
DATABASE-NAME':将此设定为Polls'或按先决条件步骤创建的PostgreSQL数据库的名称。- `DATABASE-PASSWORD': 设定为先决条件步骤中创建的 PostgreSQL 用户密码 。
- `DATABASE-HOST ' :将其设定为数据库的主机名。
- `DATABASE-PORT ' :将其设置在数据库的端口。
- `统计-ACCESS-KEY-ID': 设置到您的 空间或物体存储的访问密钥.
- `STATIC_SECRET_KEY':将此设定在您的空间或物体存储器的存取密钥上。
- `STIC_BUKET_NAME: 设置到您的 空间名称或物体存储桶。
统计-ENDPOINT-URL': 将其设定为相应的空间或物体存储端点 URL, 例如https://your_space_name.nyc3. digital Oceanspaces.com' 如果您的空间位于nyc3区域。 .
完成编辑后,保存并关闭文件。
在下一步中,我们将本地运行配置的容器并创建数据库方案,我们还将上传静态资产,如风格表和图像到对象存储。
步骤 2 — 创建数据库方案并将资产上传到对象存储
有了集装箱的构建和配置,使用docker run来取代 Dockerfile中的CMD设置,并使用manage.py makemigrations和manage.py migrate命令创建数据库方案:
1docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate"
我们运行polls:latest容器图像,传入我们刚刚修改的环境变量文件,并用sh -c``python manage.py makemigrations && python manage.py迁移来翻译Dockerfile命令,这将创建应用程序代码定义的数据库方案。
如果你第一次使用此功能,你应该看到:
1[secondary_label Output]
2No changes detected
3Operations to perform:
4 Apply all migrations: admin, auth, contenttypes, polls, sessions
5Running migrations:
6 Applying contenttypes.0001_initial... OK
7 Applying auth.0001_initial... OK
8 Applying admin.0001_initial... OK
9 Applying admin.0002_logentry_remove_auto_add... OK
10 Applying admin.0003_logentry_add_action_flag_choices... OK
11 Applying contenttypes.0002_remove_content_type_name... OK
12 Applying auth.0002_alter_permission_name_max_length... OK
13 Applying auth.0003_alter_user_email_max_length... OK
14 Applying auth.0004_alter_user_username_opts... OK
15 Applying auth.0005_alter_user_last_login_null... OK
16 Applying auth.0006_require_contenttypes_0002... OK
17 Applying auth.0007_alter_validators_add_error_messages... OK
18 Applying auth.0008_alter_user_username_max_length... OK
19 Applying auth.0009_alter_user_last_name_max_length... OK
20 Applying auth.0010_alter_group_name_max_length... OK
21 Applying auth.0011_update_proxy_permissions... OK
22 Applying polls.0001_initial... OK
23 Applying sessions.0001_initial... OK
这表明数据库方案已成功创建。
如果您在随后的时间运行迁移,Django 将执行禁令,除非数据库架构发生了变化。
接下来,我们将运行应用程序容器的另一个实例,并使用其内部的交互式壳创建 Django 项目的管理用户。
1docker run -i -t --env-file env polls sh
这将为您提供运行容器内部的壳提示,您可以使用它来创建Django用户:
1python manage.py createsuperuser
输入您的用户的用户名、电子邮件地址和密码,然后创建用户后,点击CTRL+D,离开容器并杀死它。
最后,我们将生成应用程序的静态文件,并使用collectstatic将其上传到DigitalOcean Space。
1docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"
这些文件被生成和上传后,您将收到以下输出。
1[secondary_label Output]
2121 static files copied.
现在我们可以运行应用程序:
1docker run --env-file env -p 80:8000 polls
1[secondary_label Output]
2[2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0
3[2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
4[2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync
5[2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7
6[2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8
7[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。
您现在应该能够通过在URL栏中键入http://localhost来导航到调查应用程序,因为没有定义的路径,您可能会收到一个404页未找到错误,这是预期的。
导航到http://localhost/polls,以查看调查应用程序界面:

要查看管理界面,请访问http://localhost/admin。你应该看到调查应用程序管理员身份验证窗口:

输入您用createsuperuser命令创建的管理用户名和密码。
验证后,您可以访问 Polls 应用程序的管理界面:

请注意,对)。
当你完成探索时,在运行 Docker 容器的终端窗口中按CTRL + C来杀死容器。
有了 Django 应用程序 Docker 图像测试,将静态资产上传到对象存储中,以及配置并准备与您的应用程序一起使用的数据库架构,您可以将 Django 应用程序图像上传到像 Docker Hub 这样的图像注册表中。
步骤 3 — 将 Django 应用程序图像推到 Docker Hub
要在 Kubernetes 上运行应用程序,必须将应用程序图像上传到像 [Docker Hub] 这样的注册表(https://hub.docker.com/). Kubernetes 会将应用程序图像从其存储库中提取,然后部署到您的集群中。
您可以使用私人 Docker 注册表,如 DigitalOcean Container Registry,目前在 Early Access 中免费使用,或者使用公共 Docker 注册表,如 Docker Hub。 Docker Hub 还允许您创建私人 Docker 存储库。 公共存储库允许任何人查看和提取容器图像,而私人存储库允许您限制对您和您的团队成员的访问。
在本教程中,我们将将Django图像推到在前提条件下创建的公共Docker Hub存储库中。您还可以将图像推到私人存储库,但从私人存储库中提取图像超出了本文的范围。 有关使用Docker Hub验证Kubernetes和提取私人图像的更多信息,请参阅 从私人注册库提取图像从Kubernetes文件库。
首先,请在本地计算机上登录 Docker Hub:
1docker login
1[secondary_label Output]
2Login 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.
3Username:
输入您的 Docker Hub 用户名和密码来登录。
Django 图像目前有 polls:latest 标签. 要将其推到您的 Docker Hub 复印件,请用您的 Docker Hub 用户名和复印件名重新标签图像:
1docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest
将图像推到 Repo:
1docker push sammy/sammy-django:latest
在本教程中,Docker Hub 用户名为 sammy 和 Repo 名为** sammy-django** . 您应该用自己的 Docker Hub 用户名和 Repo 名更换这些值。
您将看到一些输出更新,因为图像层被推到Docker Hub。
现在,您的图像在Docker Hub上可用于Kubernetes,您可以开始在集群中滚动它。
步骤4 - 设置 ConfigMap
当我们在本地运行Django容器时,我们将)和)注入配置变量。
ConfigMaps 应该用于存储非机密配置信息,如应用设置,Secrets 应该用于敏感信息,如 API 密钥和数据库凭证。它们都以类似的方式注入到容器中,但Secrets 具有额外的访问控制和安全功能,如 安静加密.Secrets 也将数据存储在 base64中,而 ConfigMaps 将数据存储在简单的文本中。
首先,创建一个名为yaml的目录,在其中我们将存储我们的Kubernetes宣言。
1mkdir yaml
2cd
在nano或您喜爱的文本编辑器中打开名为polls-configmap.yaml的文件:
1nano polls-configmap.yaml
插入以下 ConfigMap 宣言:
1[label polls-configmap.yaml]
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: polls-config
6data:
7 DJANGO_ALLOWED_HOSTS: "*"
8 STATIC_ENDPOINT_URL: "https://your_space_name.space_region.digitaloceanspaces.com"
9 STATIC_BUCKET_NAME: "your_space_name"
10 DJANGO_LOGLEVEL: "info"
11 DEBUG: "True"
12 DATABASE_ENGINE: "postgresql_psycopg2"
我们从 [步骤 1] 修改的 env 文件中提取了非敏感的配置(https://andsky.com/tech/tutorials/how-to-deploy-a-scalable-and-secure-django-application-with-kubernetes# step-1-%E2%80%94-cloning-and-configuring-the-application)并将其粘贴到 ConfigMap 宣言中。 ConfigMap 对象被称为 polls-config. 在上一步中将输入 `env' 文件的相同值复制。
为了测试,将DJANGO_ALLOWED_HOSTS放置为* ,以禁用基于主机标题的过滤。
当你完成编辑文件时,保存并关闭它。
在您的集群中使用kubectl应用创建 ConfigMap:
1kubectl apply -f polls-configmap.yaml
1[secondary_label Output]
2configmap/polls-config created
随着 ConfigMap 创建,我们将在下一步创建应用程序使用的秘密。
第5步:设定秘密
秘密值必须是 base64-coded,这意味着在您的群集中创建秘密对象比创建 ConfigMaps 更重要。您可以重复从前一步的过程,手动 base64-coding 秘密值并粘贴到一个显而易见的文件中。您还可以使用环境变量文件, kubectl create 和 --from-env-file 旗帜创建它们,我们将在本步中完成。
我们将再次使用从 Step 1的 env 文件,删除插入 ConfigMap 的变量。在 yaml 目录中创建一个名为 env 文件的副本:
1cp ../env ./polls-secrets
在您喜爱的编辑器中编辑文件:
1nano polls-secrets
1[label polls-secrets]
2DJANGO_SECRET_KEY=
3DEBUG=True
4DJANGO_ALLOWED_HOSTS=
5DATABASE_ENGINE=postgresql_psycopg2
6DATABASE_NAME=polls
7DATABASE_USERNAME=
8DATABASE_PASSWORD=
9DATABASE_HOST=
10DATABASE_PORT=
11STATIC_ACCESS_KEY_ID=
12STATIC_SECRET_KEY=
13STATIC_BUCKET_NAME=
14STATIC_ENDPOINT_URL=
15DJANGO_LOGLEVEL=info
删除 ConfigMap 演示文中插入的所有变量. 完成后,它应该看起来像这样:
1[label polls-secrets]
2DJANGO_SECRET_KEY=your_secret_key
3DATABASE_NAME=polls
4DATABASE_USERNAME=your_django_db_user
5DATABASE_PASSWORD=your_django_db_user_password
6DATABASE_HOST=your_db_host
7DATABASE_PORT=your_db_port
8STATIC_ACCESS_KEY_ID=your_space_access_key
9STATIC_SECRET_KEY=your_space_access_key_secret
请确保在 [步骤 1] 中使用相同的值(https://andsky.com/tech/tutorials/how-to-deploy-a-scalable-and-secure-django-application-with-kubernetes# step-1-%E2%80%94-cloning-and-configuring-the-application)。
在您的集群中使用kubectl创建秘密创建秘密:
1kubectl create secret generic polls-secret --from-env-file=poll-secrets
1[secondary_label Output]
2secret/polls-secret created
在这里,我们创建了一个名为polls-secret的秘密对象,并通过我们刚刚创建的秘密文件。
您可以使用「kubectl 描述」檢查秘密:
1kubectl describe secret polls-secret
1[secondary_label Output]
2Name: polls-secret
3Namespace: default
4Labels: <none>
5Annotations: <none>
6
7Type: Opaque
8
9Data
10====
11DATABASE_PASSWORD: 8 bytes
12DATABASE_PORT: 5 bytes
13DATABASE_USERNAME: 5 bytes
14DJANGO_SECRET_KEY: 14 bytes
15STATIC_ACCESS_KEY_ID: 20 bytes
16STATIC_SECRET_KEY: 43 bytes
17DATABASE_HOST: 47 bytes
18DATABASE_NAME: 5 bytes
此时,您已使用 Secret 和 ConfigMap 对象类型将应用程序的配置存储在您的 Kubernetes 集群中,我们现在已经准备好将应用程序部署到集群中。
步骤 6 — 使用部署将 Django 应用程序滚动
在此步骤中,您将为您的 Django 应用程序创建部署。Kubernetes 部署是可用于管理群集中的无状态应用程序的 _controller。
部署控制一个或多个 Pods,这是 Kubernetes 集群中最小的可部署单元。 Pods 包含一个或多个容器。 若要了解您可以启动的不同类型的工作负载,请查看 An Introduction to Kubernetes。
首先,在您最喜爱的编辑器中打开名为 'polls-deployment.yaml' 的文件:
1nano polls-deployment.yaml
点击下面的部署宣言:
1[label polls-deployment.yaml]
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: polls-app
6 labels:
7 app: polls
8spec:
9 replicas: 2
10 selector:
11 matchLabels:
12 app: polls
13 template:
14 metadata:
15 labels:
16 app: polls
17 spec:
18 containers:
19 - image: your_dockerhub_username/app_repo_name:latest
20 name: polls
21 envFrom:
22 - secretRef:
23 name: polls-secret
24 - configMapRef:
25 name: polls-config
26 ports:
27 - containerPort: 8000
28 name: gunicorn
填写适当的容器图像名称,引用您在 [步骤 2] 中推出的 Django Polls 图像(https://andsky.com/tech/tutorials/how-to-deploy-a-scalable-and-secure-django-application-with-kubernetes# step-2-%E2%80%94-creating-the-database-schema-and-uploading-assets-to-object-storage)。
在这里,我们定义了一个名为Polls-app的Kubernetes部署,并将其标记为关键值对app:polls。
使用envFrom与secretRef和configMapRef,我们指定从polls-secret Secret 和polls-config ConfigMap 的所有数据应该作为环境变量注入到容器中。
最后,我们将容器港``8000曝光,并将其命名为gunicorn。
要了解有关配置 Kubernetes 部署的更多信息,请参阅 Kubernetes 文档中的 Deployments。
当你完成编辑文件时,保存并关闭它。
在您的集群中使用 kubectl apply -f 创建部署:
1kubectl apply -f polls-deployment.yaml
1deployment.apps/polls-app created
检查部署是否使用kubectl get运行正确:
1kubectl get deploy polls-app
1[secondary_label Output]
2NAME READY UP-TO-DATE AVAILABLE AGE
3polls-app 2/2 2 2 6m38s
如果您遇到错误或某些东西不完全工作,您可以使用kubectl 描述来检查失败的部署:
1kubectl describe deploy
您可以使用kubectl get pod检查两个Pod:
1kubectl get pod
1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3polls-app-847f8ccbf4-2stf7 1/1 Running 0 6m42s
4polls-app-847f8ccbf4-tqpwm 1/1 Running 0 6m57s
您的 Django 应用程序的两个复制品现在在集群中运行,要访问该应用程序,您需要创建 Kubernetes 服务,我们将接下来做。
步骤 7 — 使用服务允许外部访问
在此步骤中,您将为您的 Django 应用程序创建一个服务。Kubernetes 服务是一种抽象,允许您将一组运行 Pod 作为网络服务曝光。
有多种服务类型,包括ClusterIP Services,在集成内部IP,NodePort Services上曝光服务,在被称作"NodePort"的静态端口上曝光每个节点上的服务,以及LoadBalancer Services,它提供云负荷平衡器来引导外部流量到您集群中的Pods(通过NodePorts,它自动创建). 欲了解更多这方面的情况,请见Kubernetes文件Service.
在我们的最终设置中,我们将使用使用 Ingress 和 Ingress 控制器在本指南的前提条件中设置的 ClusterIP 服务。
开始使用您最喜欢的编辑器创建名为 `polls-svc.yaml’的文件:
1nano polls-svc.yaml
点击下面的服务宣言:
1[label polls-svc.yaml]
2apiVersion: v1
3kind: Service
4metadata:
5 name: polls
6 labels:
7 app: polls
8spec:
9 type: NodePort
10 selector:
11 app: polls
12 ports:
13 - port: 8000
14 targetPort: 8000
在这里,我们创建了一个名为调查的NodePort服务,并给它app:polls标签,然后选择带有app:polls标签的后端Pod,并瞄准其8000端口。
当你完成编辑文件时,保存并关闭它。
使用「kubectl 應用」發佈服務:
1kubectl apply -f polls-svc.yaml
1[secondary_label Output]
2service/polls created
确认您的服务是使用kubectl get svc创建的:
1kubectl get svc polls
1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3polls NodePort 10.245.197.189 <none> 8000:32654/TCP 59s
此输出显示服务的集群内部IP和NodePort(32654)。 要连接到服务,我们需要我们的集群节点的外部IP地址:
1kubectl get node -o wide
1[secondary_label Output]
2NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
3pool-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
4pool-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
5pool-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
在您的 Web 浏览器中,使用任何 Node 的外部 IP 地址和 NodePort 访问您的 Polls 应用程序. 考虑到上述输出,该应用程序的 URL 将是:http://203.0.113.1:32654/polls`。
您应该看到在步骤 1 中本地访问的相同的调查应用程序界面:

您可以使用 /admin 路線重複同樣的測試: http://203.0.113.1:32654/admin. 您應該看到與之前相同的 Admin 界面:

在此阶段,您使用部署部署了 Django Polls 应用程序容器的两个复制品,并为这两个复制品创建了一个稳定的网络终端,并通过使用 NodePort 服务使其外部可用。
本教程的最后一步是通过HTTPS向您的应用程序提供安全的外部流量. 为了做到这一点,我们将使用在前提条件中安装的ingress-nginx Ingress Controller,并创建一个 Ingress 对象来将外部流量路由到调查的 Kubernetes 服务。
步骤 8 — 使用 Nginx Ingress 和 cert-manager 配置 HTTPS
Kubernetes Ingresses允许您灵活地将流量从您的 Kubernetes 集群以外路由到您的集群内的服务。 这是通过使用 Ingress 对象实现的,这些对象定义了向 Kubernetes 服务路由 HTTP 和 HTTPS 流量的规则,以及 Ingress Controllers 通过负载平衡流量并将其路由到相应的后端服务来执行规则。
在先决条件中您安装了 [engress-nginx] (https://github.com/kubernetes/ingress-nginx) 入侵控制员和核证人-管理人 TLS 证书自动化加载. 您还使用 让我们加密证书 权限为您的域设置了 ClusterIssuers , 并创建了 Ingress 测试证书签发和 TLS 加密到两个假后端服务 。 在继续采取这一步骤之前,你应删除`echo-engress'。 在 [先决条件教程] (https://andsky.com/tech/tutorials/how-to-set-up-an-nginx-ingress-with-cert-manager-on-digitalocean-kubernetes 中创建的入侵 :
1kubectl delete ingress echo-ingress
如果你想,你也可以使用kubectl delete svc和kubectl delete deploy删除虚假服务和部署,但这不是完成本教程所必需的。
您还应该创建一个带有) 学习如何创建 `A' 记录 .
如果您正在使用DigitalOcean Kubernetes,请确保您已执行在 [如何在DigitalOcean Kubernetes上使用Cert-Manager设置 Nginx Ingress 的步骤 5]中描述的解决方案(https://andsky.com/tech/tutorials/how-to-set-up-an-nginx-ingress-with-cert-manager-on-digitalocean-kubernetes# step-5-%E2%80%94-enabling-pod-communication-through-the-load-balancer-(可选))。
一旦您有指向 Ingress 控制器负载平衡器的A记录,您可以为your_domain.com和调查服务创建一个 Ingress。
使用您最喜欢的编辑器打开名为 polls-ingress.yaml 的文件:
1nano polls-ingress.yaml
请在以下 Ingress 宣言中填写:
1[polls-ingress.yaml]
2apiVersion: networking.k8s.io/v1beta1
3kind: Ingress
4metadata:
5 name: polls-ingress
6 annotations:
7 kubernetes.io/ingress.class: "nginx"
8 cert-manager.io/cluster-issuer: "letsencrypt-staging"
9spec:
10 tls:
11 - hosts:
12 - your_domain.com
13 secretName: polls-tls
14 rules:
15 - host: your_domain.com
16 http:
17 paths:
18 - backend:
19 serviceName: polls
20 servicePort: 8000
我们创建了一个名为polls-ingress的 Ingress 对象,并注释它以指示控制平面使用 ingress-nginx Ingress 控制器并设置 ClusterIssuer. 我们还为your_domain.com启用 TLS,并将证书和私钥存储在一个名为polls-tls的秘密中。
当你完成编辑文件时,保存并关闭它。
在您的集群中使用kubectl应用创建 Ingress:
1kubectl apply -f polls-ingress.yaml
1[secondary_label Output]
2ingress.networking.k8s.io/polls-ingress created
您可以使用kubectl 描述来跟踪您刚刚创建的 Ingress 的状态:
1kubectl describe ingress polls-ingress
1[secondary_label Output]
2Name: polls-ingress
3Namespace: default
4Address: workaround.your_domain.com
5Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
6TLS:
7 polls-tls terminates your_domain.com
8Rules:
9 Host Path Backends
10 ---- ---- --------
11 your_domain.com
12 polls:8000 (10.244.0.207:8000,10.244.0.53:8000)
13Annotations: cert-manager.io/cluster-issuer: letsencrypt-staging
14 kubernetes.io/ingress.class: nginx
15Events:
16 Type Reason Age From Message
17 ---- ------ ---- ---- -------
18 Normal CREATE 51s nginx-ingress-controller Ingress default/polls-ingress
19 Normal CreateCertificate 51s cert-manager Successfully created Certificate "polls-tls"
20 Normal UPDATE 25s nginx-ingress-controller Ingress default/polls-ingress
您也可以在polls-tls证书上运行描述,以进一步确认其成功创建:
1kubectl describe certificate polls-tls
1[secondary_label Output]
2. . .
3Events:
4 Type Reason Age From Message
5 ---- ------ ---- ---- -------
6 Normal Issuing 3m33s cert-manager Issuing certificate as Secret does not exist
7 Normal Generated 3m32s cert-manager Stored new private key in temporary Secret resource "polls-tls-v9lv9"
8 Normal Requested 3m32s cert-manager Created new CertificateRequest resource "polls-tls-drx9c"
9 Normal Issuing 2m58s cert-manager The certificate has been successfully issued
这确认了 TLS 证书的成功发行,并且 HTTPS 加密现在对 your_domain.com 是有效的。
鉴于我们使用了嵌入式 ClusterIssuer,大多数网页浏览器不会信任它发行的假 Let's Encrypt 证书,因此导航到 your_domain.com 将导致您到达错误页面。
要发送测试请求,我们将从命令行中使用wget:
1wget -O - http://your_domain.com/polls
1[secondary_label Output]
2. . .
3ERROR: cannot verify your_domain.com's certificate, issued by ‘CN=Fake LE Intermediate X1’:
4 Unable to locally verify the issuer's authority.
5To connect to your_domain.com insecurely, use `--no-check-certificate'.
我们将使用建议的--no-check-certificate旗帜来绕过证书验证:
1wget --no-check-certificate -q -O - http://your_domain.com/polls
1[secondary_label Output]
2
3<link rel="stylesheet" type="text/css" href="https://your_space.nyc3.digitaloceanspaces.com/django-polls/static/polls/style.css">
4
5 <p>No polls are available.</p>
此输出显示了 `/polls’ 界面页面的 HTML,也确认了风格表正在从对象存储中提供服务。
现在,您已经成功测试了使用阶段性 ClusterIssuer 的证书发行,您可以修改 Ingress 以使用生产 ClusterIssuer。
打开polls-ingress.yaml再次编辑:
1nano polls-ingress.yaml
更改集群发送者的注释:
1[polls-ingress.yaml]
2apiVersion: networking.k8s.io/v1beta1
3kind: Ingress
4metadata:
5 name: polls-ingress
6 annotations:
7 kubernetes.io/ingress.class: "nginx"
8 cert-manager.io/cluster-issuer: "letsencrypt-prod"
9spec:
10 tls:
11 - hosts:
12 - your_domain.com
13 secretName: polls-tls
14 rules:
15 - host: your_domain.com
16 http:
17 paths:
18 - backend:
19 serviceName: polls
20 servicePort: 8000
完成后,保存并关闭文件. 使用 kubectl 应用 更新 Ingress:
1kubectl apply -f polls-ingress.yaml
1[secondary_label Output]
2ingress.networking.k8s.io/polls-ingress configured
您可以使用kubectl 描述证书调查结果和kubectl 描述入门调查结果来跟踪证书发行状态:
1kubectl describe ingress polls-ingress
1[secondary_label Output]
2. . .
3Events:
4 Type Reason Age From Message
5 ---- ------ ---- ---- -------
6 Normal CREATE 23m nginx-ingress-controller Ingress default/polls-ingress
7 Normal CreateCertificate 23m cert-manager Successfully created Certificate "polls-tls"
8 Normal UPDATE 76s (x2 over 22m) nginx-ingress-controller Ingress default/polls-ingress
9 Normal UpdateCertificate 76s cert-manager Successfully updated Certificate "polls-tls"
上述结果证实,新生产证书已成功发行并存储在民意调查秘密中。
在您的 Web 浏览器中导航到your_domain.com/polls,以确认 HTTPS 加密已启用,一切按预期运行。

检查 HTTPS 加密是否在您的 Web 浏览器中活跃. 如果您使用 Google Chrome,在上面的页面上没有任何错误,确认一切正常工作。此外,您应该在 URL 栏中看到一个锁定。
作为最后的清理任务,您可以选择将调查服务类型从 NodePort 转换为内部只使用的 ClusterIP 类型。
使用您的编辑器更改 polls-svc.yaml:
1nano polls-svc.yaml
将类型从NodePort改为ClusterIP:
1[label polls-svc.yaml]
2apiVersion: v1
3kind: Service
4metadata:
5 name: polls
6 labels:
7 app: polls
8spec:
9 type: ClusterIP
10 selector:
11 app: polls
12 ports:
13 - port: 8000
14 targetPort: 8000
当你完成编辑文件时,保存并关闭它。
使用kubectl 应用滚动更改:
1kubectl apply -f polls-svc.yaml --force
1[secondary_label Output]
2service/polls configured
确认您的服务已使用kubectl get svc进行修改:
1kubectl get svc polls
1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3polls ClusterIP 10.245.203.186 <none> 8000/TCP 22s
此输出显示服务类型现在是 ClusterIP. 访问它的唯一途径是通过您的域和在此步骤中创建的 Ingress。
结论
在本教程中,您将可扩展的、HTTPS 安全的 Django 应用部署到 Kubernetes 集群中. 静态内容直接从对象存储中提供,并且可以使用调查应用部署宣言中的复制品字段快速扩展运行 Pods 的数量。
如果您正在使用 DigitalOcean Space,您还可以通过内容交付网络启用静态资产交付并为您的 Space 创建自定义子域。 请参阅 Enabling CDN from How to Set Up a Scalable Django App with DigitalOcean Managed Databases and Spaces以获取更多信息。
要查看该系列的其余部分,请访问我们的 从容器到 Kubernetes 与 Django 系列页面。