教程:使用 Azure Database for PostgreSQL 灵活服务器在 AKS 上部署 Django 应用

适用于: Azure Database for PostgreSQL 灵活服务器

本快速入门介绍如何使用 Azure CLI 通过 Azure Database for PostgreSQL 灵活服务器在 Azure Kubernetes 服务 (AKS) 群集上部署 Django 应用程序。

AKS 是可用于快速部署和管理群集的托管式 Kubernetes 服务。 Azure Database for PostgreSQL 灵活服务器是一种完全托管的数据库服务,旨在针对数据库管理功能和配置设置提供更精细的控制和更大的灵活性。

注意

本快速入门假设读者基本了解 Kubernetes 的概念以及 Django 和 PostgreSQL。

先决条件

如果没有 Azure 试用版订阅,请在开始前创建一个试用版订阅

  • 可以在本地计算机上安装 Azure CLI。 通过 Azure CLI 使用 az login 命令登录。 若要完成身份验证过程,请遵循终端中显示的步骤。
  • 运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。 本文需要 Azure CLI 的最新版本。

创建资源组

Azure 资源组是一个逻辑组,用于部署和管理 Azure 资源。 我们使用 az group create 命令在 chinanorth3 位置创建资源组 django-project。

az group create --name django-project --location chinanorth3

注意

此位置是资源组元数据的存储位置。 如果你在创建资源期间未指定另一个区域,则它还是你的资源在 Azure 中的运行位置。

以下示例输出显示已成功创建资源组:

{
  "id": "/subscriptions/<guid>/resourceGroups/django-project",
  "location": "chinanorth3",
  "managedBy": null,
  
  "name": "django-project",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null
}

创建 AKS 群集

使用 az aks create 命令创建 AKS 群集。 以下示例创建包含一个节点的名为 djangoappcluster 的群集。 此操作将需要几分钟才能完成。

az aks create --resource-group django-project --name djangoappcluster --node-count 1 --generate-ssh-keys

片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

注意

创建 AKS 群集时,会自动创建另一个资源组来存储 AKS 资源。 请参阅为什么使用 AKS 创建两个资源组?

连接到群集

若要管理 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl

注意

请运行 az aks install-cli 命令来安装 kubectl

若要将 kubectl 配置为连接到 Kubernetes 群集,请使用 az aks get-credentials 命令。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。

az aks get-credentials --resource-group django-project --name djangoappcluster

若要验证到群集的连接,请使用 kubectl get 命令返回群集节点列表。

kubectl get nodes

以下示例输出显示在上一步创建的单个节点。 请确保节点的状态为 Ready

NAME                       STATUS   ROLES   AGE     VERSION
aks-nodepool1-31718369-0   Ready    agent   6m44s   v1.12.8

创建 Azure Database for PostgreSQL 灵活服务器实例

使用 az postgreSQL flexible-server create 命令创建 Azure Database for PostgreSQL 灵活服务器实例。 以下命令使用服务默认值和 Azure CLI 本地上下文中的值创建服务器:

az postgres flexible-server create --public-access all

创建的服务器具有以下属性:

  • 首次预配服务器时,将创建一个新的空数据库 postgres。 在本快速入门中,我们使用此数据库。
  • 自动生成的服务器名称、管理员用户名、管理员密码、资源组名称(如果尚未在本地上下文中指定),并且与资源组位于同一位置。
  • 使用 public-access 参数可以创建对任何具有正确用户名和密码的客户端具有公共访问权限的服务器。
  • 由于该命令使用本地上下文,因此它会在资源组 django-project 和区域 chinanorth3 中创建该服务器。

生成 Django Docker 映像

新建 Django 应用程序,或使用现有的 Django 项目。 确保代码位于该文件夹结构中。

└───my-djangoapp
    └───views.py
    └───models.py
    └───forms.py
    ├───templates
          . . . . . . .
    ├───static
         . . . . . . .
└───my-django-project
    └───settings.py
    └───urls.py
    └───wsgi.py
        . . . . . . .
    └─── Dockerfile
    └─── requirements.txt
    └─── manage.py

更新 settings.py 中的 ALLOWED_HOSTS确保 Django 应用程序使用分配给 kubernetes 应用的外部 IP。

ALLOWED_HOSTS = ['*']

更新 settings.py 文件中的 DATABASES={ } 部分。 以下代码片段从 Kubernetes 清单文件读取数据库主机、用户名和密码。

DATABASES={
   'default':{
      'ENGINE':'django.db.backends.postgresql_psycopg2',
      'NAME':os.getenv('DATABASE_NAME'),
      'USER':os.getenv('DATABASE_USER'),
      'PASSWORD':os.getenv('DATABASE_PASSWORD'),
      'HOST':os.getenv('DATABASE_HOST'),
      'PORT':'5432',
      'OPTIONS': {'sslmode': 'require'}
   }
}

生成 requirements.txt 文件

创建 requirements.txt 文件以列出 Django 应用程序的依赖项。 下面是一个示例 requirements.txt 文件。 你可以使用 pip freeze > requirements.txt 来为现有应用程序生成 requirements.txt 文件。

Django==2.2.17
postgres==3.0.0
psycopg2-binary==2.8.6
psycopg2-pool==1.1
pytz==2020.4

创建 Dockerfile

新建名为 Dockerfile 的文件,然后复制以下代码片段。 此 Dockerfile 用于设置 Python 3.8 和安装 requirements.txt 文件中列出的所有要求。

# Use the official Python image from the Docker Hub

FROM python:3.8.2

# Make a new directory to put our code in.

RUN mkdir /code

# Change the working directory.

WORKDIR /code

# Copy to code folder

COPY . /code/

# Install the requirements.

RUN pip install -r requirements.txt

# Run the application:

CMD python manage.py runserver 0.0.0.0:8000

生成映像

使用 cd 命令确保你位于终端的目录 my-django-app 中。 运行以下命令以生成公告板映像:

docker build --tag myblog:latest .

将映像部署到 Docker HubAzure 容器注册表

重要

如果你使用 Azure 容器注册表 (ACR),那么运行 az aks update 命令,将 ACR 帐户附加到 AKS 群集。

az aks update --name djangoappcluster --resource-group django-project --attach-acr <your-acr-name>

创建 Kubernetes 清单文件

Kubernetes 清单文件定义群集的所需状态,例如,要运行哪些容器映像。 我们来创建名为 djangoapp.yaml 的清单文件,并将其复制到以下 YAML 定义中。

重要

使用 Azure Database for PostgreSQL 灵活服务器实例的 SERVERNAMEYOUR-DATABASE-USERNAMEYOUR-DATABASE-PASSWORD 更新下面的 env 部分。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: django-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: django-app
  template:
    metadata:
      labels:
        app: django-app
    spec:
      containers:
      - name: django-app
        image: [DOCKER-HUB-USER-OR-ACR-ACCOUNT]/[YOUR-IMAGE-NAME]:[TAG]
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_HOST
          value: "SERVERNAME.postgres.database.chinacloudapi.cn"
        - name: DATABASE_USER
          value: "YOUR-DATABASE-USERNAME"
        - name: DATABASE_PASSWORD
          value: "YOUR-DATABASE-PASSWORD"
        - name: DATABASE_NAME
          value: "postgres"
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                    - django-app
              topologyKey: "kubernetes.io/hostname"
---
apiVersion: v1
kind: Service
metadata:
  name: python-svc
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
  selector:
    app: django-app

将 Django 部署到 AKS 群集

使用 kubectl apply 命令部署应用程序,并指定 YAML 清单的名称:

kubectl apply -f djangoapp.yaml

以下示例输出显示已成功创建了部署和服务:

deployment "django-app" created
service "python-svc" created

使用部署 django-app 可说明部署的详细信息,例如应用要使用的映像、Pod 的数量和 Pod 配置。 创建服务 python-svc 通过外部 IP 公开应用程序。

测试应用程序

应用程序运行时,Kubernetes 服务将向 Internet 公开应用程序前端。 此过程可能需要几分钟才能完成。

若要监视进度,请将 kubectl get service 命令与 --watch 参数配合使用。

kubectl get service python-svc --watch

最初,django-app 服务的 EXTERNAL-IP 显示为“挂起” 。

NAME               TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
django-app   LoadBalancer   10.0.37.27   <pending>     80:30572/TCP   6s

EXTERNAL-IP 地址从 pending 更改为实际公共 IP 地址时,请使用 CTRL-C 停止 kubectl 监视进程。 以下示例输出显示向服务分配了有效的公共 IP 地址:

django-app  LoadBalancer   10.0.37.27   52.179.23.131   80:30572/TCP   2m

现在,打开 Web 浏览器,转到服务 (http://<service-external-ip-address>) 的外部 IP 地址,查看 Django 应用程序。

注意

运行数据库迁移

对于任何 django 应用程序,需运行数据库迁移或收集静态文件。 可以使用 $ kubectl exec <pod-name> -- [COMMAND] 运行这些 django shell 命令。 在运行命令之前,需使用 kubectl get pods 查找 Pod 名称。

$ kubectl get pods

你将看到如下所示的输出:

NAME                             READY   STATUS          RESTARTS   AGE
django-app-5d9cd6cd8-l6x4b     1/1     Running              0       2m

找到 Pod 名称后,可以使用命令 $ kubectl exec <pod-name> -- [COMMAND] 运行 django 数据库迁移。 请注意,/code/ 是上面 Dockerfile 中所定义项目的工作目录。

$ kubectl exec django-app-5d9cd6cd8-l6x4b -- python /code/manage.py migrate

输出可能如下所示

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, 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
  . . . . . . 

如果遇到问题,请运行 kubectl logs <pod-name> 以查看应用程序引发的异常。 如果应用程序成功运行,你将在运行 kubectl logs 时看到如下输出。

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
December 08, 2020 - 23:24:14
Django version 2.2.17, using settings 'django_postgres_app.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

清理资源

若要避免 Azure 费用,应清除不需要的资源。 如果不再需要群集,可以使用 az group delete 命令删除资源组、容器服务及所有相关资源。

az group delete --name django-project --yes --no-wait

注意

删除群集时,AKS 群集使用的 Microsoft Entra 服务主体不会被删除。 有关如何删除服务主体的步骤,请参阅 AKS 服务主体的注意事项和删除。 如果你使用了托管标识,则该标识由平台托管,不需要删除。

后续步骤