チュートリアル:Azure Database for PostgreSQL - フレキシブル サーバーを使用して Django アプリを AKS にデプロイする

適用対象: Azure Database for PostgreSQL - フレキシブル サーバー

このクイックスタートでは、Azure CLI を使って、Azure Database for PostgreSQL フレキシブル サーバーを含む Azure Kubernetes Service (AKS) クラスターに Django アプリケーションをデプロイします。

AKS は、クラスターをすばやくデプロイして管理できるマネージド Kubernetes サービスです。 Azure Database for PostgreSQL フレキシブル サーバーは、データベース管理機能と構成設定に対してよりきめ細かな制御と柔軟性を提供するように設計されたフル マネージド データベース サービスです。

Note

このクイックスタートは、Kubernetes の概念、Django、PostgreSQL に関する基礎知識があることを前提としています。

前提条件

Azure サブスクリプションをお持ちでない場合は、開始する前に Azure 無料アカウントを作成してください。

  • 新しいブラウザー ウィンドウで Azure Cloud Shell を起動します。 ローカル コンピューターに Azure CLI をインストールすることもできます。 ローカル インストールを使用する場合は、az login コマンドを使用して Azure CLI でログインします。 認証プロセスを完了するには、ターミナルに表示される手順に従います。
  • az version を実行し、インストールされているバージョンおよび依存ライブラリを検索します。 最新バージョンにアップグレードするには、az upgrade を実行します。 この記事では、Azure CLI の最新バージョンが必要です。 Azure Cloud Shell を使用している場合は、最新バージョンが既にインストールされています。

リソース グループを作成する

Azure リソース グループは、Azure リソースが展開され管理される論理グループです。 az-group-create コマンドを使用して、eastus の場所に django-project というリソース グループを作成しましょう。

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

注意

リソース グループの場所は、リソース グループのメタデータが保存される場所です。 また、リソースの作成時に別のリージョンを指定しない場合に、Azure でリソースが実行される場所でもあります。

次の出力例では、正常に作成されたリソース グループが示されています。

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

AKS クラスターの作成

AKS クラスターを作成するには、az aks create コマンドを使用します。 次の例では、djangoappcluster という名前のクラスターを 1 つのノードで作成します。 これは完了までに数分かかる場合があります。

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

数分後、コマンドが完了し、クラスターに関する情報が JSON 形式で返されます。

注意

AKS クラスターを作成すると、AKS リソースを保存するための 2 つ目のリソース グループが自動的に作成されます。 「AKS と一緒にリソース グループが 2 つ作成されるのはなぜでしょうか?」を参照してください。

クラスターに接続する

Kubernetes クラスターを管理するには、Kubernetes のコマンドライン クライアントである kubectl を使用します。 Azure Cloud Shell を使用している場合、kubectl は既にインストールされています。

Note

Azure CLI をローカル環境で実行している場合は、az aks install-cli コマンドを実行して kubectl をインストールしてください。

Kubernetes クラスターに接続するように kubectl を構成するには、az aks get-credentials コマンドを使用します。 このコマンドは、資格情報をダウンロードし、それを使用するように Kubernetes CLI を構成します。

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

クラスターへの接続を確認するには、クラスター ノードの一覧を返す kubectl get コマンドを使用します。

kubectl get nodes

次の出力例は、前の手順で作成した単一ノードを示しています。 ノードの状態が "準備完了" であることを確認します。

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 引数を使うと、正しいユーザー名とパスワードで任意のクライアントにパブリック アクセスできるサーバーを作成できます。
  • このコマンドはローカル コンテキストを使っているため、eastus リージョンの django-project リソース グループにサーバーが作成されます。

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

Django アプリケーションが、kubernetes アプリに割り当てられている外部 IP を使用するように、settings.pyALLOWED_HOSTS を更新します。

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 ファイルを生成する

Django アプリケーションの依存関係を示す requirements.txt ファイルを作成します。 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 Hub または Azure Container Registry にイメージをデプロイします。

重要

Azure Container Registry (ACR) を使用している場合は、az aks update コマンドを実行して ACR アカウントを AKS クラスターに接続します。

az aks update -n djangoappcluster -g django-project --attach-acr <your-acr-name>

Kubernetes マニフェスト ファイルを作成する

Kubernetes のマニフェスト ファイルでは、どのコンテナー イメージを実行するかなど、クラスターの望ましい状態を定義します。 djangoapp.yaml という名前のマニフェスト ファイルを作成し、次の YAML 定義をコピーしましょう。

重要

以下の env セクションを、お使いの Azure Database for PostgreSQL フレキシブル サーバー インスタンスの SERVERNAMEYOUR-DATABASE-USERNAMEYOUR-DATABASE-PASSWORD で更新します。

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.azure.com"
        - 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 を使うと、アプリに使うイメージ、ポッドの数、ポッド構成など、デプロイの詳細を指定できます。 外部 IP を介してアプリケーションを公開するために、python-svc サービスが作成されます。

アプリケーションをテストする

アプリケーションが実行されると、Kubernetes サービスによってアプリケーション フロント エンドがインターネットに公開されます。 このプロセスが完了するまでに数分かかることがあります。

進行状況を監視するには、kubectl get service コマンドを --watch 引数と一緒に使用します。

kubectl get service python-svc --watch

最初は、django-app サービスの EXTERNAL-IPpending (保留中) として表示されます。

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

EXTERNAL-IP アドレスが "保留中" から実際のパブリック IP アドレスに変わったら、CTRL-C を使用して kubectl ウォッチ プロセスを停止します。 次の出力例は、サービスに割り当てられている有効なパブリック IP アドレスを示しています。

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

次に、サービスの外部 IP アドレス (http://<service-external-ip-address>) を Web ブラウザーで開き、Django アプリケーションを表示します。

Note

データベースの移行を実行する

Django アプリケーションの場合、データベースの移行を実行するか、静的ファイルを収集する必要があります。 $ kubectl exec <pod-name> -- [COMMAND] を使用して、これらの django シェル コマンドを実行できます。 コマンドを実行する前に、kubectl get pods を使用してポッド名を確認する必要があります。

$ kubectl get pods

次のような出力が表示されます。

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

ポッド名を確認したら、$ 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

Note

クラスターを削除したとき、AKS クラスターで使用される Microsoft Entra サービス プリンシパルは削除されません。 サービス プリンシパルを削除する手順については、AKS のサービス プリンシパルに関する考慮事項と削除に関するページを参照してください。 マネージド ID を使用した場合、ID はプラットフォームによって管理されるため、削除する必要はありません。

次のステップ