Kubernetesを使用してスケーラブルで安全なDjangoアプリケーションをデプロイする方法
序章
このチュートリアルでは、コンテナ化されたDjangoポーリングアプリケーションをKubernetesクラスターにデプロイします。
Django は、Pythonアプリケーションをすばやく立ち上げるのに役立つ強力なWebフレームワークです。 これには、オブジェクトリレーショナルマッパー、ユーザー認証、アプリケーション用のカスタマイズ可能な管理インターフェイスなど、いくつかの便利な機能が含まれています。 また、キャッシングフレームワークが含まれており、URLディスパッチャーおよびテンプレートシステムを通じてクリーンなアプリの設計を促進します。
Docker を使用してDjangoおよびGunicornアプリケーションを構築する方法では、 Django Tutorial Pollsアプリケーションが、スケーラブルなクラウドを構築するためのTwelve-Factor方法論に従って変更されました。ネイティブWebアプリ。 このコンテナ化されたセットアップは、 Docker、Nginx、およびLet’s Encrypt を使用してDjangoアプリケーションをスケーリングおよび保護する方法で、NginxリバースプロキシおよびLet’sEncryptで署名されたTLS証明書を使用してスケーリングおよび保護されました。 コンテナからDjangoを使用したKubernetesへシリーズのこの最後のチュートリアルでは、最新のDjangoポーリングアプリケーションがKubernetesクラスターにデプロイされます。
Kubernetes は、コンテナー化されたアプリケーションのデプロイ、スケーリング、管理を自動化する強力なオープンソースのコンテナーオーケストレーターです。 ConfigMapsやSecretsなどのKubernetesオブジェクトを使用すると、構成を一元化してコンテナから切り離すことができます。一方、Deploymentsなどのコントローラは、失敗したコンテナを自動的に再起動し、コンテナレプリカの迅速なスケーリングを可能にします。 TLS暗号化は、Ingressオブジェクトとingress-nginxオープンソースのIngressコントローラーで有効になります。 cert-manager Kubernetesアドオンは、無料の Let’sEncrypt認証局を使用して証明書を更新および発行します。
前提条件
このチュートリアルに従うには、次のものが必要です。
- ロールベースのアクセス制御(RBAC)が有効になっているKubernetes1.15+クラスター。 このセットアップではDigitalOceanKubernetes クラスターを使用しますが、別の方法を使用してクラスターを自由に作成できます。
- The
kubectl
ローカルマシンにインストールされ、クラスターに接続するように構成されたコマンドラインツール。 インストールについてもっと読むことができますkubectl
公式ドキュメント。 DigitalOcean Kubernetesクラスターを使用している場合は、 DigitalOcean Kubernetesクラスターへの接続方法を参照して、を使用してクラスターに接続する方法を確認してください。kubectl
. - 登録されたドメイン名。 このチュートリアルでは、
your_domain.com
全体を通して。 Freenom で無料で入手するか、選択したドメインレジストラを使用できます。 - ingress-nginx IngressControllerとcert-manager TLS証明書マネージャーがクラスターにインストールされ、TLS証明書を発行するように構成されています。 cert-managerを使用してIngressをインストールおよび構成する方法については、 DigitalOceanKubernetesでCert-Managerを使用してNginxIngressを設定する方法を参照してください。
- アン
A
DNSレコードyour_domain.com
IngressLoadBalancerのパブリックIPアドレスを指しています。 DigitalOceanを使用してドメインのDNSレコードを管理している場合は、DNSレコードの管理方法を参照して作成方法を確認してください。A
記録 - DigitalOcean Space などのS3オブジェクトストレージバケット。Djangoプロジェクトの静的ファイルと、このスペースのアクセスキーのセットを保存します。 スペースの作成方法については、スペースの作成方法の製品ドキュメントを参照してください。 スペースのアクセスキーを作成する方法については、アクセスキーを使用したスペースへのアクセスの共有を参照してください。 マイナーな変更により、django-storagesプラグインがサポートする任意のオブジェクトストレージサービスを使用できます。
- DjangoアプリのPostgreSQLサーバーインスタンス、データベース、およびユーザー。 小さな変更を加えるだけで、Djangoがサポートするのデータベースを使用できます。
- PostgreSQLデータベースはpolls(または以下の構成ファイルに入力する別の覚えやすい名前)と呼ばれる必要があり、このチュートリアルでは、Djangoデータベースユーザーの名前はsammyになります。 これらを作成するためのガイダンスについては、Dockerを使用してDjangoおよびGunicornアプリケーションを構築する方法のステップ1に従ってください。 これらの手順は、ローカルマシンから実行する必要があります。
- このチュートリアルでは、DigitalOceanマネージドPostgreSQLクラスターを使用します。 クラスタの作成方法については、DigitalOcean管理対象データベースの製品ドキュメントを参照してください。
- 独自のPostgreSQLインスタンスをインストールして実行することもできます。 UbuntuサーバーにPostgreSQLをインストールして管理するためのガイダンスについては、 Ubuntu18.04にPostgreSQLをインストールして使用する方法を参照してください。
- DockerHubアカウントとパブリックリポジトリ。 これらの作成の詳細については、Dockerドキュメントのリポジトリを参照してください。
- ローカルマシンにインストールされているDockerエンジン。 詳細については、 Ubuntu18.04にDockerをインストールして使用する方法を参照してください。
これらのコンポーネントを設定したら、このガイドを開始する準備が整います。
ステップ1—アプリケーションのクローン作成と構成
このステップでは、GitHubからアプリケーションコードを複製し、データベースのクレデンシャルやオブジェクトストレージキーなどの設定を構成します。
アプリケーションコードとDockerfileは、 polls-docker
Django Tutorial Polls AppGitHubリポジトリのブランチ。 このリポジトリには、Djangoドキュメントのサンプルポーリングアプリケーションのコードが含まれています。このコードは、ポーリングアプリケーションを最初から作成する方法を示しています。
The polls-docker
ブランチには、このPollsアプリのDocker化バージョンが含まれています。 コンテナ化された環境で効果的に機能するようにPollsアプリがどのように変更されたかについては、Dockerを使用してDjangoおよびGunicornアプリケーションを構築する方法を参照してください。
使用することから始めます 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
このディレクトリには、DjangoアプリケーションのPythonコードが含まれています。 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は、公式のPython 3.7.4 Docker image をベースとして使用し、DjangoとGunicornのPythonパッケージ要件をインストールします。 django-polls/requirements.txt
ファイル。 次に、不要なビルドファイルをいくつか削除し、アプリケーションコードをイメージにコピーして、実行を設定します。 PATH
. 最後に、そのポートを宣言します 8000
着信コンテナ接続を受け入れるために使用され、実行されます gunicorn
3人の労働者と一緒に、港で聞いています 8000
.
このDockerfileの各ステップの詳細については、Dockerを使用してDjangoおよびGunicornアプリケーションを構築する方法のステップ6を参照してください。
次に、を使用してイメージを作成します 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 docs で詳しく説明されているように、これを一意の予測できない値に設定します。 このキーを生成する1つの方法は、 Scalable DjangoAppチュートリアルのAppSettingsの調整にあります。DJANGO_ALLOWED_HOSTS
:この変数はアプリを保護し、HTTPホストヘッダー攻撃を防ぎます。 テスト目的で、これをに設定します*
、すべてのホストに一致するワイルドカード。 本番環境では、これを次のように設定する必要がありますyour_domain.com
. このDjango設定の詳細については、Djangoドキュメントのコア設定を参照してください。DATABASE_USERNAME
:前提条件の手順で作成したPostgreSQLデータベースユーザーに設定します。DATABASE_NAME
:これをに設定しますpolls
または、前提条件の手順で作成されたPostgreSQLデータベースの名前。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
領域。
編集が終了したら、ファイルを保存して閉じます。
次のステップでは、構成されたコンテナーをローカルで実行し、データベーススキーマを作成します。 また、スタイルシートや画像などの静的アセットをオブジェクトストレージにアップロードします。
ステップ2—データベーススキーマの作成とオブジェクトストレージへのアセットのアップロード
コンテナを構築および構成した状態で、 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はno-opを実行します。
次に、アプリコンテナーの別のインスタンスを実行し、その中のインタラクティブシェルを使用して、Djangoプロジェクトの管理ユーザーを作成します。
- docker run -i -t --env-file env polls sh
これにより、実行中のコンテナ内にシェルプロンプトが表示され、Djangoユーザーの作成に使用できます。
- python manage.py createsuperuser
ユーザーのユーザー名、メールアドレス、パスワードを入力し、ユーザーを作成したら、 CTRL+D
コンテナを終了して強制終了します。
最後に、アプリの静的ファイルを生成し、を使用してDigitalOceanSpaceにアップロードします。 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
次のように入力して、Webブラウザを使用するアプリ http://localhost
URLバーにあります。 ルートが定義されていないため、 /
パス、あなたはおそらく受け取るでしょう 404 Page Not Found
予想されるエラー。
案内する http://localhost/polls
投票アプリのインターフェースを表示するには:
管理インターフェースを表示するには、次のWebサイトにアクセスしてください。 http://localhost/admin
. Pollsアプリの管理者認証ウィンドウが表示されます。
で作成した管理ユーザー名とパスワードを入力します createsuperuser
指図。
認証後、Pollsアプリの管理インターフェースにアクセスできます。
の静的アセットに注意してください admin
と polls
アプリはオブジェクトストレージから直接配信されています。 これを確認するには、テストスペースの静的ファイル配信を参照してください。
探索が終了したら、 CTRL+C
Dockerコンテナを実行しているターミナルウィンドウで、コンテナを強制終了します。
DjangoアプリのDockerイメージをテストし、静的アセットをオブジェクトストレージにアップロードし、データベーススキーマを構成してアプリで使用できるようになったら、DjangoアプリのイメージをDockerHubなどのイメージレジストリにアップロードする準備が整います。
ステップ3—DjangoアプリイメージをDockerHubにプッシュする
Kubernetesでアプリをロールアウトするには、アプリの画像を DockerHubなどのレジストリにアップロードする必要があります。 Kubernetesは、リポジトリからアプリイメージをプルしてから、クラスターにデプロイします。
DigitalOcean Container Registry のようなプライベートDockerレジストリを使用できます。これは、現在早期アクセスで無料です。または、DockerHubのようなパブリックDockerレジストリを使用できます。 Docker Hubでは、プライベートDockerリポジトリを作成することもできます。 パブリックリポジトリを使用すると、誰でもコンテナイメージを表示およびプルできますが、プライベートリポジトリを使用すると、自分とチームメンバーへのアクセスを制限できます。
このチュートリアルでは、前提条件で作成されたパブリックDockerHubリポジトリにDjangoイメージをプッシュします。 イメージをプライベートリポジトリにプッシュすることもできますが、プライベートリポジトリからイメージをプルすることはこの記事の範囲を超えています。 Docker Hubを使用したKubernetesの認証とプライベートイメージのプルについて詳しくは、Kubernetesドキュメントのプライベートレジストリからイメージをプルするをご覧ください。
まず、ローカルマシンのDockerHubにログインします。
- 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:
DockerHubのユーザー名とパスワードを入力してログインします。
Djangoイメージには現在 polls:latest
鬼ごっこ。 Docker Hubリポジトリにプッシュするには、DockerHubのユーザー名とリポジトリ名でイメージにタグを付け直します。
- docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest
画像をリポジトリにプッシュします。
- docker push sammy/sammy-django:latest
このチュートリアルでは、DockerHubのユーザー名はsammy で、リポジトリ名はsammy-djangoです。 これらの値を独自のDockerHubユーザー名とリポジトリ名に置き換える必要があります。
画像レイヤーがDockerHubにプッシュされると更新される出力が表示されます。
これで、Docker Hub上のKubernetesでイメージを利用できるようになったので、クラスターでイメージのロールアウトを開始できます。
ステップ4—ConfigMapを設定する
Djangoコンテナをローカルで実行すると、 env
ファイルに docker run
構成変数をランタイム環境に挿入します。 Kubernetesでは、ConfigMapsおよびSecretsを使用して構成変数を挿入できます。
ConfigMapsは、アプリ設定などの機密でない構成情報を格納するために使用する必要があり、Secretsは、APIキーやデータベースクレデンシャルなどの機密情報に使用する必要があります。 どちらも同様の方法でコンテナに挿入されますが、シークレットには、保存時の暗号化などの追加のアクセス制御とセキュリティ機能があります。 シークレットはbase64にもデータを保存しますが、ConfigMapsはデータをプレーンテキストで保存します。
まず、というディレクトリを作成します 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を作成したら、次のステップでアプリが使用するシークレットを作成します。
ステップ5—秘密を設定する
シークレット値はbase64エンコードである必要があります。つまり、クラスターでのシークレットオブジェクトの作成は、ConfigMapの作成よりも少し複雑です。 シークレット値を手動で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で使用したのと同じ値を使用してください。 完了したら、ファイルを保存して閉じます。
を使用してクラスターにシークレットを作成します kubectl create secret
:
- kubectl create secret generic polls-secret --from-env-file=poll-secrets
Outputsecret/polls-secret created
ここでは、というシークレットオブジェクトを作成します polls-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
この時点で、SecretオブジェクトタイプとConfigMapオブジェクトタイプを使用して、アプリの構成をKubernetesクラスターに保存しました。 これで、アプリをクラスターにデプロイする準備が整いました。
ステップ6—デプロイメントを使用してDjangoアプリをロールアウトする
このステップでは、Djangoアプリのデプロイを作成します。 Kubernetes Deploymentは、クラスター内のステートレスアプリケーションを管理するために使用できるコントローラーです。 コントローラは、ワークロードをスケールアップまたはスケールダウンすることによってワークロードを調整する制御ループです。 コントローラも再起動し、障害が発生したコンテナをクリアします。
デプロイは、Kubernetesクラスター内のデプロイ可能な最小ユニットである1つ以上のポッドを制御します。 ポッドは1つ以上のコンテナを囲みます。 起動できるさまざまなタイプのワークロードの詳細については、Kubernetesの概要をご覧ください。
と呼ばれるファイルを開くことから始めます polls-deployment.yaml
お気に入りのエディターで:
- nano polls-deployment.yaml
次のデプロイメントマニフェストに貼り付けます。
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
ステップ2でDockerHubにプッシュしたDjangoPollsイメージを参照して、適切なコンテナーイメージ名を入力します。
ここでは、Kubernetesデプロイメントを定義します。 polls-app
キーと値のペアでラベルを付けます app: polls
. 以下に定義されているポッドの2つのレプリカを実行することを指定します。 template
分野。
使用する envFrom
と secretRef
と configMapRef
、からのすべてのデータを指定します polls-secret
秘密と polls-config
ConfigMapは、環境変数としてコンテナーに挿入する必要があります。 ConfigMapキーとSecretキーが環境変数名になります。
最後に、公開します containerPort
8000
名前を付けます gunicorn
.
Kubernetesデプロイの設定の詳細については、Kubernetesドキュメントのデプロイを参照してください。
ファイルの編集が完了したら、ファイルを保存して閉じます。
を使用してクラスターにデプロイメントを作成します kubectl apply -f
:
- kubectl apply -f polls-deployment.yaml
- deployment.apps/polls-app created
を使用して展開が正しく展開されたことを確認します kubectl get
:
- kubectl get deploy polls-app
OutputNAME READY UP-TO-DATE AVAILABLE AGE
polls-app 2/2 2 2 6m38s
エラーが発生した場合、または何かがうまく機能していない場合は、次を使用できます kubectl describe
失敗したデプロイメントを検査するには:
- kubectl describe deploy
を使用して2つのポッドを検査できます 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アプリの2つのレプリカがクラスターで稼働しています。 アプリにアクセスするには、Kubernetesサービスを作成する必要があります。これを次に行います。
ステップ7—サービスを使用した外部アクセスの許可
このステップでは、Djangoアプリのサービスを作成します。 Kubernetesサービスは、実行中のポッドのセットをネットワークサービスとして公開できるようにする抽象化です。 サービスを使用すると、ポッドが停止して再作成されても変更されない、アプリの安定したエンドポイントを作成できます。
クラスター内部IPでサービスを公開するClusterIPサービス、NodePortと呼ばれる静的ポートで各ノードのサービスを公開するNodePortサービス、クラウドロードバランサーをプロビジョニングするLoadBalancerサービスなど、複数のサービスタイプがあります。外部トラフィックをクラスター内のポッドに転送します(NodePortsを介して自動的に作成されます)。 これらの詳細については、Kubernetesドキュメントのサービスをご覧ください。
最終的なセットアップでは、このガイドの前提条件でセットアップされたIngressとIngressControllerを使用して公開されるClusterIPサービスを使用します。 今のところ、すべてが正しく機能していることをテストするために、Djangoアプリにアクセスするための一時的なNodePortサービスを作成します。
と呼ばれるファイルを作成することから始めます polls-svc.yaml
お気に入りのエディターを使用する:
- nano polls-svc.yaml
次のサービスマニフェストに貼り付けます。
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
ポート。
ファイルの編集が完了したら、ファイルを保存して閉じます。
を使用してサービスを展開する 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
Webブラウザーで、任意のノードの外部IPアドレスとNodePortを使用してPollsアプリにアクセスします。 上記の出力を考えると、アプリのURLは次のようになります。 http://203.0.113.1:32654/polls
.
手順1でローカルにアクセスしたものと同じPollsアプリのインターフェースが表示されます。
を使用して同じテストを繰り返すことができます /admin
ルート: http://203.0.113.1:32654/admin
. 以前と同じ管理インターフェースが表示されます。
この段階で、Deploymentを使用してDjangoPollsアプリコンテナーの2つのレプリカをロールアウトしました。 また、これら2つのレプリカ用の安定したネットワークエンドポイントを作成し、NodePortサービスを使用して外部からアクセスできるようにしました。
このチュートリアルの最後のステップは、HTTPSを使用してアプリへの外部トラフィックを保護することです。 これを行うには、 ingress-nginx
前提条件にインストールされているIngressControllerを使用して、外部トラフィックをにルーティングするIngressオブジェクトを作成します。 polls
Kubernetesサービス。
ステップ8—NginxIngressとcert-managerを使用したHTTPSの構成
Kubernetes Ingresses を使用すると、Kubernetesクラスターの外部からクラスター内のサービスにトラフィックを柔軟にルーティングできます。 これは、HTTPおよびHTTPSトラフィックをKubernetesサービスにルーティングするためのルールを定義するIngressオブジェクトと、トラフィックを負荷分散して適切なバックエンドサービスにルーティングすることでルールを実装するIngress Controllersを使用して実現されます。
前提条件で、 ingress-nginx IngressControllerとcert-managerTLS証明書自動化アドオンをインストールしました。 また、Let’s Encrypt認証局を使用して、ドメインのステージングおよび本番ClusterIssuersを設定し、2つのダミーバックエンドサービスへの証明書発行とTLS暗号化をテストするためのIngressを作成しました。 この手順を続行する前に、を削除する必要があります echo-ingress
前提条件のチュートリアルで作成された入力:
- kubectl delete ingress echo-ingress
必要に応じて、を使用してダミーのサービスとデプロイメントを削除することもできます kubectl delete svc
と kubectl delete deploy
、ただし、これはこのチュートリアルを完了するために必須ではありません。
DNSも作成しておく必要があります A
で記録する your_domain.com
IngressLoadBalancerのパブリックIPアドレスを指しています。 DigitalOceanロードバランサーを使用している場合、このIPアドレスはコントロールパネルのロードバランサーセクションにあります。 DigitalOceanを使用してドメインのDNSレコードも管理している場合は、DNSレコードの管理方法を参照して作成方法を確認してください。 A
記録。
DigitalOcean Kubernetesを使用している場合は、 DigitalOceanKubernetesでCert-Managerを使用してNginxIngressを設定する方法のステップ5で説明されている回避策を実装していることも確認してください。
あなたが持ったら A
Ingress Controller Load Balancerを指すレコード、次の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-nginxIngressControllerとステージングClusterIssuerを使用するように指示します。 また、TLSを有効にします your_domain.com
証明書と秘密鍵をという秘密に保存します polls-tls
. 最後に、トラフィックをルーティングするルールを定義します。 your_domain.com
のホスト polls
ポートでのサービス 8000
.
ファイルの編集が完了したら、ファイルを保存して閉じます。
を使用してクラスタに入力を作成します 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を使用したことを考えると、ほとんどのWebブラウザーは、発行した偽の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>
この出力は、 /polls
インターフェイスページ。スタイルシートがオブジェクトストレージから提供されていることも確認します。
ステージングClusterIssuerを使用して証明書の発行を正常にテストしたので、本番ClusterIssuerを使用するようにIngressを変更できます。
開ける 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
完了したら、ファイルを保存して閉じます。 を使用して入力を更新します 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"
上記の出力は、新しい本番証明書が正常に発行され、に保存されたことを確認します。 polls-tls
ひみつ。
案内する your_domain.com/polls
Webブラウザーで、HTTPS暗号化が有効になっていて、すべてが期待どおりに機能していることを確認します。 Pollsアプリのインターフェースが表示されます。
WebブラウザでHTTPS暗号化がアクティブになっていることを確認します。 Google Chromeを使用している場合、エラーなしで上記のページにアクセスすると、すべてが正しく機能していることが確認されます。 さらに、URLバーに南京錠が表示されます。 南京錠をクリックすると、Let’sEncrypt証明書の詳細を調べることができます。
最後のクリーンアップタスクとして、オプションで 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
を使用してサービスが変更されたことを確認します 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
この出力は、サービスタイプがClusterIPになったことを示しています。 アクセスする唯一の方法は、ドメインとこのステップで作成したIngressを経由することです。
結論
このチュートリアルでは、HTTPSで保護されたスケーラブルなDjangoアプリをKubernetesクラスターにデプロイしました。 静的コンテンツはオブジェクトストレージから直接提供され、実行中のポッドの数は、 replicas
のフィールド polls-app
展開マニフェスト。
DigitalOcean Spaceを使用している場合は、コンテンツ配信ネットワークを介した静的アセットの配信を有効にして、Spaceのカスタムサブドメインを作成することもできます。 詳細については、 DigitalOceanマネージドデータベースとスペースを使用してスケーラブルなDjangoアプリをセットアップする方法から、CDNを有効にするを参照してください。
シリーズの残りの部分を確認するには、コンテナからKuberneteswithDjangoシリーズページにアクセスしてください。