Google Kubernetes Engine で Django を実行する

GKE で実行される Django アプリは、トラフィックに応じて動的にスケーリングされます。

このチュートリアルは、Django ウェブ開発の知識があることを前提としています。Django 開発を初めて使用する場合は、続行する前に最初の Django アプリを作成するを実施することをおすすめします。

このチュートリアルでは Django について具体的に説明しますが、このデプロイ プロセスは WagtailDjango CMS などの他の Django ベースのフレームワークでも使用できます。

また、Docker もインストールする必要があります。

目標

このチュートリアルの内容は次のとおりです。

  • Cloud SQL データベースを作成して接続する。
  • Kubernetes Secret 値を作成して使用する。
  • Google Kubernetes Engine に Django アプリをデプロイする。

料金

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  3. Google Cloud プロジェクトで課金が有効になっていることを確認します

  4. Cloud SQL, GKE and Compute Engine API を有効にします。

    API を有効にする

  5. Google Cloud CLI をインストールします。
  6. gcloud CLI を初期化するには:

    gcloud init
  7. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  8. Google Cloud プロジェクトで課金が有効になっていることを確認します

  9. Cloud SQL, GKE and Compute Engine API を有効にします。

    API を有効にする

  10. Google Cloud CLI をインストールします。
  11. gcloud CLI を初期化するには:

    gcloud init

環境を準備する

サンプルアプリのクローンを作成する

Django サンプルアプリのコードは、GitHub の GoogleCloudPlatform/python-docs-samples リポジトリにあります。

  1. ZIP ファイルとしてサンプルをダウンロードして展開するか、ローカルマシンにリポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    
  2. サンプルコードのあるディレクトリに移動します。

    Linux / macOS

    cd python-docs-samples/kubernetes_engine/django_tutorial
    

    Windows

    cd python-docs-samples\kubernetes_engine\django_tutorial
    

Python の設定を確認する

このチュートリアルでは、Python を使用してサンプル アプリケーションをマシン上で実行します。サンプルコードでは依存関係もインストールする必要があります。

詳細については、Python 開発環境ガイドをご覧ください。

  1. Python のバージョンが 3.7 以降であることを確認します。

     python -V
    

    Python 3.7.3 以上が表示される必要があります。

  2. Python 仮想環境を作成し、依存関係をインストールします。

    Linux / macOS

    python -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

    Windows

    python -m venv env
    venv\scripts\activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

ローカルマシンから Cloud SQL Auth プロキシをダウンロードして Cloud SQL に接続する

デプロイされると、アプリは Google Kubernetes Engine 環境に組み込まれている Cloud SQL Auth プロキシを使用して Cloud SQL インスタンスと通信します。ただし、アプリをローカルでテストするには、プロキシのローカルコピーを開発環境にインストールして使用する必要があります。 詳しくは、Cloud SQL Auth プロキシガイドをご覧ください。

Cloud SQL Auth プロキシは、Cloud SQL API を使用して SQL インスタンスとやり取りします。これを行うには、gcloud でアプリケーションの認証を行う必要があります。

  1. API の認証情報を取得して認証します。

    gcloud auth application-default login
    
  2. Cloud SQL Auth プロキシをダウンロードしてローカルマシンにインストールします。

    Linux 64 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
      
    2. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    Linux 32 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.386 -O cloud_sql_proxy
      
    2. wget コマンドが見つからない場合は、sudo apt-get install wget を実行してダウンロード コマンドを繰り返します。
    3. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    macOS 64 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
      
    2. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    macOS 32 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.386
      
    2. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    Mac M1

    1. Cloud SQL Auth Proxy をダウンロードします。
        curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.arm64
        
    2. Cloud SQL Auth Proxy を動作可能にします。
        chmod +x cloud_sql_proxy
        

    Windows 64 ビット

    https://dl.google.com/cloudsql/cloud_sql_proxy_x64.exe を右クリックして [名前を付けてリンク先を保存] を選択し、Cloud SQL Auth Proxy をダウンロードします。ファイル名を cloud_sql_proxy.exe に変更します。

    Windows 32 ビット

    https://dl.google.com/cloudsql/cloud_sql_proxy_x86.exe を右クリックして [名前を付けてリンク先を保存] を選択し、Cloud SQL Auth Proxy をダウンロードします。ファイル名を cloud_sql_proxy.exe に変更します。

    Cloud SQL Auth Proxy Docker イメージ

    便宜上、Cloud SQL Auth プロキシを含む複数のコンテナ イメージは、GitHub で Cloud SQL Auth プロキシ リポジトリから入手できます。次のコマンドを使用して、最新のイメージをローカルマシンに Docker で pull できます。
    docker pull gcr.io/cloudsql-docker/gce-proxy:1.30.1
    

    その他の OS

    ここに記載されていないその他のオペレーティング システムの場合は、ソースから Cloud SQL Auth Proxy をコンパイルできます。

    ダウンロード先は、PATH の場所やホーム ディレクトリなど、一般的な場所に移動できます。これを行う場合は、チュートリアルの後半で Cloud SQL Auth プロキシを起動する際の cloud_sql_proxy コマンド使用時に、選択したロケーションを必ず参照してください。

バッキング サービスを作成する

このチュートリアルでは、さまざまな Google Cloud サービスを使用して、デプロイ済みの Django プロジェクトをサポートするデータベース、メディア ストレージ、シークレット ストレージを準備します。これらのサービスは、特定のリージョンにデプロイされます。サービス間の効率を高めるために、すべてのサービスを同じリージョンにデプロイすることをおすすめします。最も近いリージョンの詳細については、リージョン別に提供されるプロダクトをご覧ください。

Cloud SQL for PostgreSQL インスタンスを設定する

Django は正式に複数のリレーショナル データベースに対応していますが、PostgreSQL に最も対応しています。PostgreSQL は Cloud SQL でサポートされているため、このチュートリアルではそのようなタイプのデータベースを使用します。

次のセクションでは、アプリ用の PostgreSQL インスタンス、データベース、データベース ユーザーの作成について説明します。

  1. PostgreSQL インスタンスを作成します。

    Console

    1. Cloud Console で、[Cloud SQL インスタンス] ページに移動します。

      Cloud SQL インスタンス ページに移動

    2. [インスタンスを作成] をクリックします。

    3. [PostgreSQL] をクリックします。

    4. [インスタンス ID] フィールドに「INSTANCE_NAME」と入力します。

    5. postgres ユーザーのパスワードを入力します。

    6. 他のフィールドはデフォルト値を使用します。

    7. [作成] をクリックします。

    インスタンスの作成と使用準備が完了するまでに数分かかります。

    gcloud

    • PostgreSQL インスタンスを作成します。

      gcloud sql instances create INSTANCE_NAME \
          --project PROJECT_ID \
          --database-version POSTGRES_13 \
          --tier db-f1-micro \
          --region REGION
      

    以下を置き換えます。

    インスタンスの作成と使用準備が完了するまでに数分かかります。

  2. 作成したインスタンス内に、データベースを作成します。

    Console

    1. インスタンス ページで、[データベース] タブに移動します。
    2. [データベースを作成] をクリックします。
    3. [データベース名] ダイアログで「DATABASE_NAME」と入力します。
    4. [作成] をクリックします。

    gcloud

    • 最近作成したインスタンス内にデータベースを作成します。

      gcloud sql databases create DATABASE_NAME \
          --instance INSTANCE_NAME
      

      DATABASE_NAME を、このインスタンス内のデータベースの名前に置き換えます。

  3. データベース ユーザーを作成するには:

    Console

    1. インスタンス ページで、[ユーザー] タブに移動します。
    2. [ユーザー アカウントを追加] をクリックします。
    3. [ユーザー アカウントをインスタンスに追加] ダイアログの [組み込みアルゴリズム] で次の操作を行います。
    4. DATABASE_USERNAME というユーザー名を入力します。
    5. DATABASE_PASSWORD というパスワードを入力します。
    6. [追加] をクリックします。

    gcloud

    • 最近作成したインスタンス内にデータベースを作成します。

      gcloud sql users create DATABASE_USERNAME \
          --instance INSTANCE_NAME \
          --password DATABASE_PASSWORD
      

      PASSWORD を安全なパスワードに置き換えます。

サービス アカウントを作成する

プロキシには、Cloud SQL インスタンスに対する編集者の権限を持つサービス アカウントが必要です。サービス アカウントの詳細については、Google Cloud 認証の概要をご覧ください。

  1. Cloud Console で [サービス アカウント] ページに移動します。

    [サービス アカウント] に移動

  2. Cloud SQL インスタンスを含むプロジェクトを選択します。
  3. [サービス アカウントを作成] をクリックします。
  4. [サービス アカウント名] フィールドに、サービス アカウントのわかりやすい名前を入力します。
  5. [サービス アカウント ID] を一意のわかりやすい値に変更し、[作成して続行] をクリックします。
  6. [ロールを選択] フィールドをクリックして、以下のいずれかのロールを選択します。
    • [Cloud SQL] > [Cloud SQL クライアント]
    • [Cloud SQL] > [Cloud SQL 編集者]
    • [Cloud SQL] > [Cloud SQL 管理者]
  7. [完了] をクリックして、サービス アカウントの作成を完了します。
  8. 新しいサービス アカウントの操作メニューをクリックし、[鍵を管理] を選択します。
  9. [鍵を追加] プルダウン メニューをクリックして、[新しい鍵を作成] をクリックします。
  10. 鍵のタイプが JSON であることを確認し、[作成] をクリックします。

    秘密鍵ファイルがマシンにダウンロードされます。秘密鍵ファイルは、別の場所に移動できます。安全な場所に鍵ファイルを保管してください。

データベースを構成する

データベースにアクセスするための環境変数を設定するには、次のコマンドを使用します。 これらの環境変数はローカルテストに使用されます。

Linux / macOS

export DATABASE_NAME=DATABASE_NAME
export DATABASE_USER=DATABASE_USERNAME
export DATABASE_PASSWORD=DATABASE_PASSWORD

Windows

set DATABASE_USER=DATABASE_USERNAME
set DATABASE_PASSWORD=DATABASE_PASSWORD

GKE の構成を設定する

  1. このアプリケーションは、polls という名前の単一の Kubernetes 構成で表されます。polls.yaml で、<your-project-id> を実際の Google Cloud プロジェクト ID (PROJECT_ID)に置き換えます。

  2. 次のコマンドを実行して、connectionName の値をメモします。

    gcloud sql instances describe INSTANCE_NAME --format "value(connectionName)"
    
  3. polls.yaml ファイルで、<your-cloudsql-connection-string>connectionName 値に置き換えます。

ローカル コンピュータでアプリを実行する

バッキング サービスを設定したら、パソコン上でアプリを実行できます。この設定により、ローカルでの開発、スーパーユーザーの作成、データベース移行の適用が可能になります。

  1. 別のターミナルで Cloud SQL Auth プロキシを起動します。

    Linux / macOS

    ./cloud_sql_proxy -instances="PROJECT_ID:REGION:INSTANCE_NAME"=tcp:5432
    

    Windows

    cloud_sql_proxy.exe -instances="PROJECT_ID:REGION:INSTANCE_NAME"=tcp:5432
    

    このステップで、ローカル パソコンから Cloud SQL インスタンスへのローカルテスト用接続が確立されます。ローカルでのアプリのテストが終了するまで、Cloud SQL Auth プロキシ を実行したままにしてください。このプロセスを別のターミナルで実行すると、このプロセスの実行中も作業を継続できます。

  2. 新しいターミナルで、プロジェクト ID をローカルに設定します。

    Linux / macOS

      export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    

    Windows

      set GOOGLE_CLOUD_PROJECT=PROJECT_ID
    
  3. Django の移行を実行してモデルとアセットを設定します。

    python manage.py makemigrations
    python manage.py makemigrations polls
    python manage.py migrate
    python manage.py collectstatic
    
  4. Django ウェブサーバーを起動します。

    python manage.py runserver
    
  5. ブラウザで、http://localhost:8000 にアクセスします。

    「Hello, world. You're at the polls index.」というテキストを含む簡単なウェブページが表示されます。コンピュータで実行されている Django ウェブサーバーは、サンプルアプリのページを配信します。

  6. Ctrl/Cmd+C キーを押して、ローカル ウェブサーバーを停止します。

Django 管理コンソールを使用する

Django の管理コンソールにログインするには、スーパー ユーザーを作成する必要があります。データベースにはローカルにアクセスできるため、管理コマンドを実行できます。

  1. スーパーユーザーを作成します。ユーザー名、メールアドレス、パスワードの入力を求められます。

    python manage.py createsuperuser
    
  2. ローカル ウェブサーバーを起動します。

    python manage.py runserver
    
  3. ブラウザで、http://localhost:8000/admin にアクセスします。

  4. createsuperuser の実行時に使用したユーザー名とパスワードで管理サイトにログインします。

GKE にアプリをデプロイする

アプリが Google Cloud にデプロイされると、Gunicorn サーバーが使用されます。Gunicorn は静的コンテンツを処理しないため、アプリは Cloud Storage を使用して静的コンテンツを処理します。

静的リソースの収集とアップロード

  1. Cloud Storage バケットを作成して、一般公開します。

    gsutil mb gs://PROJECT_ID_MEDIA_BUCKET
    gsutil defacl set public-read gs://PROJECT_ID_MEDIA_BUCKET
    
  2. すべての静的コンテンツをローカルで 1 つのフォルダにまとめます。

    python manage.py collectstatic
    
  3. 静的コンテンツを Cloud Storage にアップロードします。

    gsutil -m rsync -r ./static gs://PROJECT_ID_MEDIA_BUCKET/static
    
  4. mysite/settings.py で、STATIC_URL の値を次の URL に設定します。[YOUR_GCS_BUCKET] は実際のバケット名に置き換えます。

    http://storage.googleapis.com/PROJECT_ID_MEDIA_BUCKET/static/
    

GKE の設定

  1. GKE を初期化するには、[クラスタ] ページに移動します。

    [クラスタ] ページに移動

    プロジェクトで初めて GKE を使用する場合は、[Kubernetes Engine is getting ready. This may take a minute or more] というメッセージが消えるまで待ちます。

  2. GKE クラスタを作成します。

    gcloud container clusters create polls \
      --scopes "https://www.googleapis.com/auth/userinfo.email","cloud-platform" \
      --num-nodes 4 --zone "us-central1-a"
    

    Project [PROJECT_ID] is not fully initialized with the default service accounts.」というエラーが表示されましたか。

    GKE の初期化

    エラーが表示された場合は、Google Cloud Console に移動してプロジェクトの GKE を初期化します。

    [クラスタ] ページに移動

    [Kubernetes Engine is getting ready. This can take a minute or more」というメッセージが消えるまで待ちます。

  3. クラスタを作成したら、gcloud と統合されている kubectl コマンドライン ツールを使用して、GKE クラスタとやり取りします。gcloudkubectl は別々のツールであるため、kubectl が適切なクラスタとやり取りするように構成されていることを確認してください。

    gcloud container clusters get-credentials polls --zone "us-central1-a"
    

Cloud SQL の設定

  1. GKE アプリを Cloud SQL インスタンスに接続できるようにするには、いくつかのシークレットが必要です。1 つはインスタンスレベルのアクセス(接続)に必要となり、他の 2 つはデータベース アクセスに必要となります。この 2 つのレベルのアクセス制御の詳細については、インスタンスのアクセス制御をご覧ください。

    1. インスタンス レベルのアクセス用のシークレットを作成するには、サービス アカウントの作成時にダウンロードした JSON サービス アカウント キーの場所([PATH_TO_CREDENTIAL_FILE])を指定します(サービス アカウントの作成を参照)。

      kubectl create secret generic cloudsql-oauth-credentials \
        --from-file=credentials.json=[PATH_TO_CREDENTIAL_FILE]
      
    2. データベース アクセスのシークレットを作成するには、Cloud SQL インスタンスの初期化の手順 2 で定義した SQL データベース、ユーザー名、パスワードを使用します。

      kubectl create secret generic cloudsql \
        --from-literal=database=DATABASE_NAME \
        --from-literal=username=DATABASE_USERNAME \
        --from-literal=password=DATABASE_PASSWORD
      
  2. Cloud SQL プロキシのパブリック Docker イメージを取得します。

    docker pull b.gcr.io/cloudsql-docker/gce-proxy
    
  3. Docker イメージをビルドします。<your-project-id> は実際のプロジェクト ID に置き換えます。

    docker build -t gcr.io/PROJECT_ID/polls .
    
  4. 認証ヘルパーとして gcloud を使用するように Docker を構成します。これにより、イメージを Container Registry に push できます。

    gcloud auth configure-docker
    
  5. Docker イメージを push します。<your-project-id> を実際のプロジェクト ID に置き換えます。

    docker push gcr.io/PROJECT_ID/polls
    
  6. GKE リソースを作成します。

    kubectl create -f polls.yaml
    

GKE にアプリをデプロイする

リソースを作成すると、クラスタ上に polls ポッドが 3 つ生成されます。ポッドのステータスを確認します。

kubectl get pods

ポッドのステータスが Running と表示されるまで数分待ちます。ポッドの準備ができていない場合や再起動が発生した場合は、特定のポッドのログを取得して問題を確認できます。[YOUR-POD-ID] は、前の kubectl get pods コマンドで返された出力の一部です。

kubectl logs [YOUR_POD_ID]

Google Cloud でアプリ実行を確認する

ポッドの準備ができたら、ロードバランサのパブリック IP アドレスを取得します。

kubectl get services polls

EXTERNAL-IP アドレスをメモしてブラウザで http://[EXTERNAL-IP] に移動し、Django ポーリング ランディング ページを表示して管理コンソールにアクセスします。

コードを理解する

サンプル アプリケーション

Django サンプルアプリは、Django の標準ツールを使用して作成されています。次のコマンドは、プロジェクトとアンケート アプリを作成します。

django-admin startproject mysite
python manage.py startapp polls

ベースビュー、モデル、ルート構成は、最初の Django アプリを作成するパート 1およびパート 2)からコピーされました。

データベース構成

settings.py には、SQL データベースの構成が含まれています。

DATABASES = {
    'default': {
        # If you are using Cloud SQL for MySQL rather than PostgreSQL, set
        # 'ENGINE': 'django.db.backends.mysql' instead of the following.
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DATABASE_NAME'),
        'USER': os.getenv('DATABASE_USER'),
        'PASSWORD': os.getenv('DATABASE_PASSWORD'),
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

Kubernetes Pod の構成

polls.yaml ファイルには、2 つの Kubernetes リソースが指定されています。1 つ目はServiceで、Django ウェブアプリの一貫した名前とプライベート IP アドレスを定義します。2 つ目は、一般公開される外部 IP アドレスを持つHTTP ロードバランサです。

# The polls service provides a load-balancing proxy over the polls app
# pods. By specifying the type as a 'LoadBalancer', Kubernetes Engine will
# create an external HTTP load balancer.
# For more information about Services see:
#   https://kubernetes.io/docs/concepts/services-networking/service/
# For more information about external HTTP load balancing see:
#   https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: polls

このサービスはネットワーク名と IP アドレスを提供し、GKE ポッドはこのサービスの背後でアプリのコードを実行します。polls.yaml ファイルは、GKE ポッドの宣言型更新を行う deployment を指定します。このサービスは、サービスのセレクタを deployment のラベルと照合し、トラフィックを deployment に送信します。この場合、セレクタ polls はラベル polls と一致します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: polls
  labels:
    app: polls
spec:
  replicas: 3
  selector:
    matchLabels:
      app: polls
  template:
    metadata:
      labels:
        app: polls
    spec:
      containers:
      - name: polls-app
        # Replace  with your project ID or use `make template`
        image: gcr.io/<your-project-id>/polls
        # This setting makes nodes pull the docker image every time before
        # starting the pod. This is useful when debugging, but should be turned
        # off in production.
        imagePullPolicy: Always
        env:
            - name: DATABASE_NAME
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: database
            - name: DATABASE_USER
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: username
            - name: DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: password
        ports:
        - containerPort: 8080

      - image: gcr.io/cloudsql-docker/gce-proxy:1.16
        name: cloudsql-proxy
        command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                  "-instances=<your-cloudsql-connection-string>=tcp:5432",
                  "-credential_file=/secrets/cloudsql/credentials.json"]
        volumeMounts:
          - name: cloudsql-oauth-credentials
            mountPath: /secrets/cloudsql
            readOnly: true
          - name: ssl-certs
            mountPath: /etc/ssl/certs
          - name: cloudsql
            mountPath: /cloudsql
      volumes:
        - name: cloudsql-oauth-credentials
          secret:
            secretName: cloudsql-oauth-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs
        - name: cloudsql
          emptyDir: {}

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトの削除

  1. Google Cloud コンソールで、[リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

個々のリソースの削除

プロジェクトを削除しない場合は、個々のリソースを削除します。

  1. Google Kubernetes Engine クラスタを削除します。

    gcloud container clusters delete polls
    
  2. Container Registry に push した Docker イメージを削除します。

    gcloud container images delete gcr.io/PROJECT_ID/polls
    
  3. Cloud SQL インスタンスを削除します。

    gcloud sql instances delete INSTANCE_NAME
    

次のステップ