Rails開発用のDockerComposeワークフローをKubernetesに移行する方法

提供:Dev Guides
移動先:案内検索

序章

最新のステートレスアプリケーションを構築する場合、アプリケーションのコンポーネントをコンテナ化するは、分散プラットフォームでのデプロイとスケーリングの最初のステップです。 開発でDockerCompose を使用したことがある場合は、次の方法でアプリケーションを最新化およびコンテナー化できます。

  • コードから必要な構成情報を抽出します。
  • アプリケーションの状態をオフロードします。
  • 繰り返し使用するためにアプリケーションをパッケージ化します。

また、コンテナイメージの実行方法を指定するサービス定義も作成します。

Kubernetes などの分散プラットフォームでサービスを実行するには、Composeサービス定義をKubernetesオブジェクトに変換する必要があります。 これにより、アプリケーションを復元力でスケーリングできます。 Kubernetesへの変換プロセスを高速化できるツールの1つは、 kompose です。これは、開発者がComposeワークフローをKubernetesやOpenShiftなどのコンテナーオーケストレーターに移動するのに役立つ変換ツールです。

このチュートリアルでは、komposeを使用してComposeサービスをKubernetesオブジェクトに変換します。 komposeが提供するオブジェクト定義を開始点として使用し、セットアップで SecretsServices 、およびPersistentVolumeClaimsが使用されるように調整します。 Kubernetesが期待していること。 チュートリアルが終了すると、Kubernetesクラスターで実行されているPostgreSQLデータベースを備えたシングルインスタンスRailsアプリケーションが完成します。 このセットアップは、DockerComposeを使用した開発用のRubyonRailsアプリケーションのコンテナー化で説明されているコードの機能を反映し、ニーズに合わせて拡張できる本番環境に対応したソリューションを構築するための良い出発点になります。

前提条件

  • ロールベースのアクセス制御(RBAC)が有効になっているKubernetes1.19+クラスター。 このセットアップではDigitalOceanKubernetesクラスターを使用しますが、別の方法を使用してクラスターを自由に作成できます。
  • kubectlコマンドラインツールがローカルマシンまたは開発サーバーにインストールされ、クラスターに接続するように構成されています。 kubectlのインストールの詳細については、公式ドキュメントを参照してください。
  • Dockerがローカルマシンまたは開発サーバーにインストールされています。 Ubuntu 20.04を使用している場合は、 Ubuntu20.04にDockerをインストールして使用する方法の手順1と2に従ってください。 それ以外の場合は、他のオペレーティングシステムへのインストールについて、公式ドキュメントに従ってください。 リンクされたチュートリアルのステップ2で説明されているように、root以外のユーザーをdockerグループに必ず追加してください。
  • DockerHubアカウント。 これを設定する方法の概要については、DockerHubのこの紹介を参照してください。

ステップ1—komposeをインストールする

komposeの使用を開始するには、プロジェクトのGitHubリリースページに移動し、現在のリリース(この記事の執筆時点ではバージョン 1.22.0 )へのリンクをコピーします。 このリンクを次のcurlコマンドに貼り付けて、最新バージョンのkomposeをダウンロードします。

curl -L https://github.com/kubernetes/kompose/releases/download/v1.22.0/kompose-linux-amd64 -o kompose

Linux以外のシステムへのインストールの詳細については、インストール手順を参照してください。

バイナリを実行可能にします。

chmod +x kompose

PATHに移動します:

sudo mv ./kompose /usr/local/bin/kompose

正しくインストールされていることを確認するには、バージョンチェックを実行します。

kompose version

インストールが成功すると、次のような出力が表示されます。

Output1.22.0 (955b78124)

komposeがインストールされ、使用できる状態になったら、Kubernetesに変換するNode.jsプロジェクトコードのクローンを作成できます。

ステップ2—アプリケーションのクローン作成とパッケージ化

アプリケーションをKubernetesで使用するには、プロジェクトコードのクローンを作成し、アプリケーションをパッケージ化して、kubeletサービスがイメージをプルできるようにする必要があります。

最初のステップは、 DigitalOceanCommunityGitHubアカウントからrails-sidekiqリポジトリのクローンを作成することです。 このリポジトリには、DockerComposeを使用した開発用のRubyonRailsアプリケーションのコンテナ化で説明されているセットアップのコードが含まれています。このコードは、デモRailsアプリケーションを使用してDockerComposeを使用して開発環境をセットアップする方法を示しています。 アプリケーション自体の詳細については、シリーズ Rails onContainersを参照してください。

リポジトリをrails_projectというディレクトリに複製します。

git clone https://github.com/do-community/rails-sidekiq.git rails_project

rails_projectディレクトリに移動します。

cd rails_project

次に、compose-workflowブランチからこのチュートリアルのコードをチェックアウトします。

git checkout compose-workflow
OutputBranch 'compose-workflow' set up to track remote branch 'compose-workflow' from 'origin'.
Switched to a new branch 'compose-workflow'

rails_projectディレクトリには、ユーザー入力で動作するサメ情報アプリケーションのファイルとディレクトリが含まれています。 コンテナで動作するように最新化されました。機密性の高い特定の構成情報がアプリケーションコードから削除され、実行時に注入されるようにリファクタリングされ、アプリケーションの状態がPostgreSQLデータベースにオフロードされました。

最新のステートレスアプリケーションの設計の詳細については、Kubernetes用アプリケーションのアーキテクチャおよびKubernetes用アプリケーションの最新化を参照してください。

プロジェクトディレクトリには、アプリケーションイメージを構築するための手順が記載されたDockerfileが含まれています。 今すぐイメージをビルドして、Docker Hubアカウントにプッシュし、Kubernetesセットアップで使用できるようにします。

docker build コマンドを使用して、-tフラグを使用してイメージをビルドします。これにより、覚えやすい名前でイメージにタグを付けることができます。 この場合、イメージにDocker Hubユーザー名のタグを付け、rails-kubernetesまたは自分で選択した名前を付けます。

docker build -t your_dockerhub_user/rails-kubernetes .

コマンドの.は、ビルドコンテキストが現在のディレクトリであることを指定します。

イメージの作成には1〜2分かかります。 完了したら、画像を確認します。

docker images

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

OutputREPOSITORY                                TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_user/rails-kubernetes     latest              24f7e88b6ef2        2 days ago          606MB
alpine                                    latest              d6e46aa2470d        6 weeks ago         5.57MB

次に、前提条件で作成したDockerHubアカウントにログインします。

docker login -u your_dockerhub_user

プロンプトが表示されたら、DockerHubアカウントのパスワードを入力します。 この方法でログインすると、DockerHubのクレデンシャルを使用してユーザーのホームディレクトリに~/.docker/config.jsonファイルが作成されます。

dockerpushコマンドを使用してアプリケーションイメージをDockerHubにプッシュします。 your_dockerhub_userを独自のDockerHubユーザー名に置き換えることを忘れないでください。

docker push your_dockerhub_user/rails-kubernetes

これで、Kubernetesでアプリケーションを実行するためにプルできるアプリケーションイメージができました。 次のステップは、アプリケーションサービス定義をKubernetesオブジェクトに変換することです。

ステップ3—komposeを使用してComposeサービスをKubernetesオブジェクトに変換する

ここではdocker-compose.ymlと呼ばれるDockerComposeファイルは、Composeでサービスを実行する定義をレイアウトします。 Composeのserviceは実行中のコンテナーであり、サービス定義には、各コンテナーイメージの実行方法に関する情報が含まれています。 このステップでは、komposeを使用してyamlファイルを作成することにより、これらの定義をKubernetesオブジェクトに変換します。 これらのファイルには、目的の状態を記述するKubernetesオブジェクトのspecsが含まれます。

これらのファイルを使用して、さまざまなタイプのオブジェクトを作成します。 Services 。これにより、コンテナを実行しているPodsに引き続きアクセスできるようになります。 展開。ポッドの望ましい状態に関する情報が含まれます。 PersistentVolumeClaim を使用して、データベースデータのストレージをプロビジョニングします。 実行時に注入される環境変数のConfigMap。 アプリケーションのデータベースユーザーとパスワード用のSecret。 これらの定義のいくつかは、komposeが作成するファイルに含まれ、その他の定義は自分で作成する必要があります。

まず、Kubernetesで機能するように、docker-compose.ymlファイルの定義の一部を変更する必要があります。 新しく作成したアプリケーションイメージへの参照をappサービス定義に含め、バインドマウントボリューム、および追加のコマンドを削除します]Composeを使用して開発中のアプリケーションコンテナを実行するために使用しました。 さらに、両方のコンテナの再起動ポリシーをKubernetesが期待する動作に一致するように再定義します。

このチュートリアルの手順に従い、gitでcompose-workflowブランチをチェックアウトした場合は、作業ディレクトリにdocker-compose.ymlファイルがあるはずです。

docker-compose.ymlをお持ちでない場合は、このシリーズの前のチュートリアルDockerComposeを使用した開発用のRubyonRailsアプリケーションのコンテナー化にアクセスし、リンクされたコンテンツを貼り付けてください。新しいdocker-compose.ymlファイルへのセクション。

nanoまたはお気に入りのエディターでファイルを開きます。

nano docker-compose.yml

appアプリケーションサービスの現在の定義は次のようになります。

〜/ rails_project / docker-compose.yml

. . .
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - database
      - redis
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - gem_cache:/usr/local/bundle/gems
      - node_modules:/app/node_modules
    env_file: .env
    environment:
      RAILS_ENV: development
. . .

サービス定義を次のように編集します。

  • build:行をimage: your_dockerhub_user/rails-kubernetesに置き換えます
  • 次のcontext: .、およびdockerfile: Dockerfile行を削除します。
  • volumesリストを削除します。

完成したサービス定義は次のようになります。

〜/ rails_project / docker-compose.yml

. . .
services:
  app:
    image: your_dockerhub_user/rails-kubernetes
    depends_on:
      - database
      - redis
    ports:
      - "3000:3000"
    env_file: .env
    environment:
      RAILS_ENV: development
. . .

次に、databaseサービス定義まで下にスクロールして、次の編集を行います。

  • - ./init.sql:/docker-entrypoint-initdb.d/init.sqlボリュームラインを削除します。 ローカルSQLファイルの値を使用する代わりに、ステップ4 で作成するシークレットを使用して、POSTGRES_USERおよびPOSTGRES_PASSWORDの値をデータベースコンテナーに渡します。
  • ports:セクションを追加して、ポート5432のKubernetesクラスター内でPostgreSQLを使用できるようにします。
  • /var/lib/postgresql/data内のディレクトリを指すPGDATA変数を含むenvironment:セクションを追加します。 この設定は、PostgreSQLがブロックストレージを使用するように構成されている場合に必要です。データベースエンジンは、サブディレクトリでデータファイルを見つけることを想定しているためです。

databaseサービス定義は、編集が終了すると次のようになります。

〜/ rails_project / docker-compose.yml

. . .
  database:
    image: postgres:12.1
    volumes:
      - db_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
. . .

次に、redisサービス定義を編集して、デフォルトの6379ポートを持つports:セクションを追加することにより、デフォルトのTCPポートを公開します。 ports:セクションを追加すると、Kubernetesクラスター内でRedisを利用できるようになります。 編集したredisサービスは、次のようになります。

〜/ rails_project / docker-compose.yml

. . .
  redis:
    image: redis:5.0.7
    ports:
      - "6379:6379"

ファイルのredisセクションを編集した後、sidekiqサービス定義に進みます。 appサービスと同様に、ローカルのDockerイメージの構築からDockerHubからのプルに切り替える必要があります。 sidekiqサービス定義を次のように編集します。

  • build:行をimage: your_dockerhub_user/rails-kubernetesに置き換えます
  • 次のcontext: .、およびdockerfile: Dockerfile行を削除します。
  • volumesリストを削除します。

〜/ rails_project / docker-compose.yml

. . .
  sidekiq:
    image: your_dockerhub_user/rails-kubernetes
    depends_on:
      - app
      - database
      - redis
    env_file: .env
    environment:
        RAILS_ENV: development
    entrypoint: ./entrypoints/sidekiq-entrypoint.sh

最後に、ファイルの下部で、gem_cacheおよびnode_modulesボリュームをトップレベルのvolumesキーから削除します。 キーは次のようになります。

〜/ rails_project / docker-compose.yml

. . .
volumes:
  db_data:

編集が終了したら、ファイルを保存して閉じます。

参考までに、完成したdocker-compose.ymlファイルには次のものが含まれている必要があります。

〜/ rails_project / docker-compose.yml

version: '3'

services:
  app:
    image: your_dockerhub_user/rails-kubernetes
    depends_on:
        - database
        - redis
    ports:
        - "3000:3000"
    env_file: .env
    environment:
        RAILS_ENV: development

  database:
    image: postgres:12.1
    volumes:
        - db_data:/var/lib/postgresql/data
    ports:
        - "5432:5432"
    environment:
        PGDATA: /var/lib/postgresql/data/pgdata

  redis:
    image: redis:5.0.7
    ports:
        - "6379:6379"

  sidekiq:
    image: your_dockerhub_user/rails-kubernetes
    depends_on:
        - app
        - database
        - redis
    env_file: .env
    environment:
        RAILS_ENV: development
    entrypoint: ./entrypoints/sidekiq-entrypoint.sh

volumes:
  db_data:

サービス定義を変換する前に、komposeが機密情報を使用してConfigMapを作成するために使用する.envファイルを作成する必要があります。 このファイルの詳細については、DockerComposeを使用した開発用のRubyonRailsアプリケーションのコンテナ化ステップ2を参照してください。

そのチュートリアルでは、.env.gitignoreファイルに追加して、バージョン管理にコピーされないようにしました。 これは、このチュートリアルステップ2でrails-sidekiqリポジトリのクローンを作成したときにコピーされなかったことを意味します。 したがって、今すぐ再作成する必要があります。

ファイルを作成します。

nano .env

komposeはこのファイルを使用して、アプリケーションのConfigMapを作成します。 ただし、Composeファイルのappサービス定義からすべての変数を割り当てる代わりに、PostgreSQLとRedisの設定のみを追加します。 ステップ4でシークレットオブジェクトを手動で作成するときに、データベース名、ユーザー名、およびパスワードを個別に割り当てます。

次のポートとデータベース名の情報を.envファイルに追加します。 必要に応じて、データベースの名前を自由に変更してください。

〜/ rails_project / .env

DATABASE_HOST=database
DATABASE_PORT=5432
REDIS_HOST=redis
REDIS_PORT=6379

編集が終了したら、ファイルを保存して閉じます。

これで、オブジェクトの仕様を使用してファイルを作成する準備が整いました。 komposeは、リソースを翻訳するための複数のオプションを提供します。 あなたはできる:

  • kompose convertを使用して、docker-compose.ymlファイルのサービス定義に基づいてyamlファイルを作成します。
  • kompose upを使用してKubernetesオブジェクトを直接作成します。
  • kompose convert -cを使用してHelmチャートを作成します。

今のところ、サービス定義をyamlファイルに変換してから、komposeが作成するファイルを追加および修正します。

次のコマンドを使用して、サービス定義をyamlファイルに変換します。

kompose convert

このコマンドを実行すると、komposeは作成したファイルに関する情報を出力します。

OutputINFO Kubernetes file "app-service.yaml" created   
INFO Kubernetes file "database-service.yaml" created
INFO Kubernetes file "redis-service.yaml" created
INFO Kubernetes file "app-deployment.yaml" created
INFO Kubernetes file "env-configmap.yaml" created
INFO Kubernetes file "database-deployment.yaml" created
INFO Kubernetes file "db-data-persistentvolumeclaim.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
INFO Kubernetes file "sidekiq-deployment.yaml" created

これには、RailsアプリケーションのService、Deployment、ConfigMap、およびdb-dataPersistentVolumeClaimとPostgreSQLデータベースのDeploymentの仕様を含むyamlファイルが含まれます。 それぞれRedisとSidekiqのファイルも含まれています。

これらのマニフェストをRailsプロジェクトのメインディレクトリから除外するには、k8s-manifestsという名前の新しいディレクトリを作成し、mvコマンドを使用して生成されたファイルをそのディレクトリに移動します。

mkdir k8s-manifests
mv *.yaml k8s-manifests

最後に、cdk8s-manifestsディレクトリに入れます。 これからは、このディレクトリ内から作業を進めて、物事を整頓します。

cd k8s-manifests

これらのファイルは良い出発点ですが、アプリケーションの機能をDockerComposeを使用した開発用のRubyonRailsアプリケーションのコンテナー化で説明されているセットアップと一致させるには、いくつかの追加と変更を行う必要があります。 komposeが生成したファイル。

ステップ4—Kubernetesシークレットを作成する

アプリケーションが期待どおりに機能するためには、komposeが作成したファイルにいくつかの変更を加える必要があります。 これらの変更の最初は、データベースユーザーとパスワードのシークレットを生成し、それをアプリケーションとデータベースの展開に追加することです。 Kubernetesは、環境変数を操作する2つの方法を提供します。ConfigMapsとSecretsです。 komposeは、.envファイルに含めた非機密情報を使用してConfigMapを既に作成しているため、データベース名、ユーザー名、パスワードなどの機密情報を使用してシークレットを作成します。

シークレットを手動で作成する最初のステップは、データを base64 に変換することです。これは、バイナリデータを含むデータを均一に送信できるエンコードスキームです。

まず、データベース名をbase64でエンコードされたデータに変換します。

echo -n 'your_database_name' | base64

エンコードされた値を書き留めます。

次に、データベースのユーザー名を変換します。

echo -n 'your_database_username' | base64

出力に表示される値を再度記録します。

最後に、パスワードを変換します。

echo -n 'your_database_password' | base64

ここでも出力の値に注意してください。

シークレットのファイルを開きます。

nano secret.yaml

注:Kubernetesオブジェクトは通常YAML を使用して定義されます。これはタブを厳密に禁止し、インデントに2つのスペースを必要とします。 yamlファイルのフォーマットを確認したい場合は、 linter を使用するか、kubectl create--dry-runおよび--validateフラグ:

kubectl create -f your_yaml_file.yaml --dry-run --validate=true

一般に、kubectlを使用してリソースを作成する前に、構文を検証することをお勧めします。


次のコードをファイルに追加して、作成したエンコード値を使用してDATABASE_NAMEDATABASE_USER、およびDATABASE_PASSWORDを定義するシークレットを作成します。 ここで強調表示されているプレースホルダーの値を、エンコードされたデータベース名、ユーザー名、およびパスワードに必ず置き換えてください。

〜/ rails_project / k8s-manifests / secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: database-secret
data:
  DATABASE_NAME: your_database_name
  DATABASE_PASSWORD: your_encoded_password
  DATABASE_USER: your_encoded_username

シークレットオブジェクトにはdatabase-secretという名前を付けましたが、好きな名前を付けることができます。

これらのシークレットは、PostgreSQLに接続できるようにRailsアプリケーションで使用されます。 ただし、データベース自体はこれらの同じ値で初期化する必要があります。 次に、3行をコピーして、ファイルの最後に貼り付けます。 最後の3行を編集し、各変数のDATABASEプレフィックスをPOSTGRESに変更します。 最後に、POSTGRES_NAME変数をPOSTGRES_DBに変更します。

最終的なsecret.yamlファイルには、次のものが含まれている必要があります。

〜/ rails_project / k8s-manifests / secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: database-secret
data:
  DATABASE_NAME: your_database_name
  DATABASE_PASSWORD: your_encoded_password
  DATABASE_USER: your_encoded_username
  POSTGRES_DB: your_database_name
  POSTGRES_PASSWORD: your_encoded_password
  POSTGRES_USER: your_encoded_username

編集が終了したら、このファイルを保存して閉じます。 .envファイルの場合と同様に、secret.yaml.gitignoreファイルに追加して、バージョン管理されないようにしてください。

secret.yamlを記述したら、次のステップは、アプリケーションとデータベースの両方のデプロイメントで、ファイルに追加した値を使用するようにすることです。 シークレットへの参照をアプリケーションのデプロイに追加することから始めましょう。

app-deployment.yamlというファイルを開きます。

nano app-deployment.yaml

ファイルのコンテナ仕様には、envキーで定義された次の環境変数が含まれています。

〜/ rails_project / k8s-manifests / app-deployment.yaml

apiVersion: apps/v1
kind: Deployment
. . .
    spec:
      containers:
        - env:
            - name: DATABASE_HOST
              valueFrom:
                configMapKeyRef:
                  key: DATABASE_HOST
                  name: env
            - name: DATABASE_PORT
              valueFrom:
                configMapKeyRef:
                  key: DATABASE_PORT
                  name: env
            - name: RAILS_ENV
              value: development
            - name: REDIS_HOST
              valueFrom:
                configMapKeyRef:
                  key: REDIS_HOST
                  name: env
            - name: REDIS_PORT
              valueFrom:
                configMapKeyRef:
                  key: REDIS_PORT
                  name: env
. . .

アプリケーションがこれらの値にアクセスできるように、シークレットへの参照を追加する必要があります。 既存の値の場合のように、envConfigMapを指すconfigMapKeyRefキーを含める代わりに、の値を指すsecretKeyRefキーを含めます。私たちのdatabase-secretの秘密。

- name: REDIS_PORT変数セクションの後に次のシークレット参照を追加します。

〜/ rails_project / k8s-manifests / app-deployment.yaml

. . .
    spec:
      containers:
        - env:
        . . .  
            - name: REDIS_PORT
              valueFrom:
                configMapKeyRef:
                  key: REDIS_PORT
                  name: env
            - name: DATABASE_NAME
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: DATABASE_NAME
            - name: DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: DATABASE_PASSWORD
            - name: DATABASE_USER
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: DATABASE_USER
. . .

編集が終了したら、ファイルを保存して閉じます。 secrets.yamlファイルと同様に、kubectlを使用して編集内容を検証し、スペース、タブ、インデントに問題がないことを確認してください。

kubectl create -f app-deployment.yaml --dry-run --validate=true
Outputdeployment.apps/app created (dry run)

次に、同じ値をdatabase-deployment.yamlファイルに追加します。

編集用にファイルを開きます。

nano database-deployment.yaml

このファイルでは、次の可変キーのシークレットへの参照を追加します:POSTGRES_DBPOSTGRES_USER、およびPOSTGRES_PASSWORDpostgresイメージにより、これらの変数が使用可能になり、データベースインスタンスの初期化を変更できるようになります。 POSTGRES_DBは、コンテナーの起動時に使用できるデフォルトのデータベースを作成します。 POSTGRES_USERPOSTGRES_PASSWORDは一緒に、作成されたデータベースにアクセスできる特権ユーザーを作成します。

これらの値を使用するということは、作成するユーザーがPostgreSQLでのそのロールのすべての管理特権と操作特権にアクセスできることを意味します。 本番環境で作業する場合は、適切なスコープの特権を持つ専用のアプリケーションユーザーを作成する必要があります。

POSTGRES_DBPOSTGRES_USER、およびPOSTGRES_PASSWORD変数の下に、シークレット値への参照を追加します。

〜/ rails_project / k8s-manifests / database-deployment.yaml

apiVersion: apps/v1
kind: Deployment
. . .
    spec:
      containers:
        - env:
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
            - name: POSTGRES_DB
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: POSTGRES_DB
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: POSTGRES_PASSWORD        
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: POSTGRES_USER
. . .

編集が終了したら、ファイルを保存して閉じます。 ここでも、kubectl--dry-run --validate=true引数を使用して、編集したファイルをリントするようにしてください。

シークレットを設定したら、データベースサービスの作成に進み、アプリケーションコンテナが完全にセットアップされて初期化された後でのみ、データベースへの接続を試行するようにすることができます。

ステップ5—PersistentVolumeClaimを変更してアプリケーションフロントエンドを公開する

アプリケーションを実行する前に、データベースストレージが適切にプロビジョニングされ、LoadBalancerを使用してアプリケーションフロントエンドを公開できるようにするために、2つの最終的な変更を行います。

まず、komposeが作成したPersistentVolumeClaimで定義されているstorage resourceを変更してみましょう。 このクレームにより、アプリケーションの状態を管理するために動的にストレージをプロビジョニングできます。

PersistentVolumeClaimsを使用するには、 StorageClass を作成し、ストレージリソースをプロビジョニングするように構成する必要があります。 この例では、 DigitalOcean Kubernetes を使用しているため、デフォルトのStorageClassprovisionerdobs.csi.digitalocean.com DigitalOcean BlockStorageに設定されています。

これを確認するには、次のように入力します。

kubectl get storageclass

DigitalOceanクラスターを使用している場合は、次の出力が表示されます。

OutputNAME                         PROVISIONER                 RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
do-block-storage (default)   dobs.csi.digitalocean.com   Delete          Immediate           true                   76m

DigitalOceanクラスターを使用していない場合は、StorageClassを作成し、選択したprovisionerを構成する必要があります。 これを行う方法の詳細については、公式ドキュメントを参照してください。

komposedb-data-persistentvolumeclaim.yamlを作成すると、storageresourceprovisionerの最小サイズ要件を満たさないサイズに設定されます。 したがって、最小実行可能DigitalOceanブロックストレージユニット:1GBを使用するように、PersistentVolumeClaimを変更する必要があります。 ストレージ要件に合わせて、これを自由に変更してください。

db-data-persistentvolumeclaim.yamlを開きます:

nano db-data-persistentvolumeclaim.yaml

storageの値を1Giに置き換えます。

〜/ rails_project / k8s-manifests / db-data-persistentvolumeclaim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  creationTimestamp: null
  labels:
    io.kompose.service: db-data
  name: db-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
status: {}

accessModeにも注意してください。ReadWriteOnceは、このクレームの結果としてプロビジョニングされたボリュームが単一ノードによってのみ読み取り/書き込みされることを意味します。 さまざまなアクセスモードの詳細については、ドキュメントを参照してください。

終了したら、ファイルを保存して閉じます。

次に、app-service.yamlを開きます。

nano app-service.yaml

DigitalOcean Load Balancer を使用して、このサービスを外部に公開します。 DigitalOceanクラスターを使用していない場合、ロードバランサーについては、クラウドプロバイダーの関連ドキュメントを参照してください。 または、公式の Kubernetesドキュメントに従って、 kubeadm を使用した高可用性クラスターのセットアップを行うこともできますが、この場合、PersistentVolumeClaimsを使用してストレージをプロビジョニングすることはできません。

サービス仕様内で、LoadBalancerをサービスtypeとして指定します。

〜/ rails_project / k8s-manifests / app-service.yaml

apiVersion: v1
kind: Service
. . .
spec:
  type: LoadBalancer
  ports:
. . .

appサービスを作成すると、ロードバランサーが自動的に作成され、アプリケーションにアクセスできる外部IPが提供されます。

編集が終了したら、ファイルを保存して閉じます。

すべてのファイルが揃ったら、アプリケーションを起動してテストする準備が整いました。

注:編集したKubernetesマニフェストを一連の参照ファイルと比較して、変更がこのチュートリアルと一致することを確認する場合は、コンパニオンGithubリポジトリに一連のテスト済みマニフェストが含まれます。 各ファイルを個別に比較することも、ローカルのgitブランチを切り替えてkubernetes-workflowブランチを使用することもできます。

ブランチを切り替える場合は、チュートリアルの前半で.gitignoreに追加したので、必ずsecrets.yamlファイルを新しいチェックアウトバージョンにコピーしてください。


ステップ6—アプリケーションの起動とアクセス

Kubernetesオブジェクトを作成し、アプリケーションが期待どおりに機能していることをテストします。

定義したオブジェクトを作成するには、 kubectl create-fフラグを使用します。これにより、komposeが作成したファイルを指定できます。私たちが書いたファイルと一緒に。 次のコマンドを実行して、RailsアプリケーションとPostgreSQLデータベース、Redisキャッシュ、Sidekiqサービスとデプロイメントを、Secret、ConfigMap、およびPersistentVolumeClaimとともに作成します。

kubectl create -f app-deployment.yaml,app-service.yaml,database-deployment.yaml,database-service.yaml,db-data-persistentvolumeclaim.yaml,env-configmap.yaml,redis-deployment.yaml,redis-service.yaml,secret.yaml,sidekiq-deployment.yaml

オブジェクトが作成されたことを示す次の出力が表示されます。

Outputdeployment.apps/app created
service/app created
deployment.apps/database created
service/database created
persistentvolumeclaim/db-data created
configmap/env created
deployment.apps/redis created
service/redis created
secret/database-secret created
deployment.apps/sidekiq created

ポッドが実行されていることを確認するには、次のように入力します。

kubectl get pods

default名前空間にオブジェクトを作成したので、ここで名前空間を指定する必要はありません。 複数のネームスペースを使用している場合は、このkubectl createコマンドを実行するときに、ネームスペースの名前とともに-nフラグを必ず含めてください。

databaseコンテナの起動中は、次のような出力が表示されます(ステータスはPendingまたはContainerCreatingのいずれかになります)。

OutputNAME                       READY   STATUS    RESTARTS   AGE
app-854d645fb9-9hv7w       1/1     Running   0          23s
database-c77d55fbb-bmfm8   0/1     Pending   0          23s
redis-7d65467b4d-9hcxk     1/1     Running   0          23s
sidekiq-867f6c9c57-mcwks   1/1     Running   0          23s

データベースコンテナが開始されると、次のような出力が得られます。

OutputNAME                       READY   STATUS    RESTARTS   AGE
app-854d645fb9-9hv7w       1/1     Running   0          30s
database-c77d55fbb-bmfm8   1/1     Running   0          30s
redis-7d65467b4d-9hcxk     1/1     Running   0          30s
sidekiq-867f6c9c57-mcwks   1/1     Running   0          30s

Running STATUSは、ポッドがノードにバインドされており、それらのポッドに関連付けられているコンテナーが実行されていることを示します。 READYは、ポッド内で実行されているコンテナーの数を示します。 詳細については、ポッドライフサイクルに関するドキュメントを参照してください。

注: STATUS列に予期しないフェーズが表示された場合は、次のコマンドを使用してポッドのトラブルシューティングを行うことができることに注意してください。

kubectl describe pods your_pod
kubectl logs your_pod

アプリケーションが稼働しているので、必要な最後のステップはRailsのデータベース移行を実行することです。 この手順では、デモアプリケーションのPostgreSQLデータベースにスキーマをロードします。

保留中の移行を実行するには、実行中のアプリケーションポッドにexecしてから、rake db:migrateコマンドを呼び出します。

まず、次のコマンドを使用してアプリケーションポッドの名前を見つけます。

kubectl get pods

次の出力で強調表示されているポッド名のように、アプリケーションに対応するポッドを見つけます。

OutputNAME                       READY   STATUS    RESTARTS   AGE
app-854d645fb9-9hv7w       1/1     Running   0          30s
database-c77d55fbb-bmfm8   1/1     Running   0          30s
redis-7d65467b4d-9hcxk     1/1     Running   0          30s
sidekiq-867f6c9c57-mcwks   1/1     Running   0          30s

そのポッド名を書き留めたら、kubectl execコマンドを実行してデータベースの移行手順を完了することができます。

次のコマンドで移行を実行します。

kubectl exec your_app_pod_name -- rake db:migrate

次のような出力が表示されます。これは、データベーススキーマがロードされたことを示しています。

Output== 20190927142853 CreateSharks: migrating =====================================
-- create_table(:sharks)
   -> 0.0190s
== 20190927142853 CreateSharks: migrated (0.0208s) ============================

== 20190927143639 CreatePosts: migrating ======================================
-- create_table(:posts)
   -> 0.0398s
== 20190927143639 CreatePosts: migrated (0.0421s) =============================

== 20191120132043 CreateEndangereds: migrating ================================
-- create_table(:endangereds)
   -> 0.8359s
== 20191120132043 CreateEndangereds: migrated (0.8367s) =======================

コンテナが実行され、データが読み込まれると、アプリケーションにアクセスできるようになります。 app LoadBalancerのIPを取得するには、次のように入力します。

kubectl get svc

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

OutputNAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
app          LoadBalancer   10.245.73.142   your_lb_ip     3000:31186/TCP   21m
database     ClusterIP      10.245.155.87   <none>           5432/TCP         21m
kubernetes   ClusterIP      10.245.0.1      <none>           443/TCP          21m
redis        ClusterIP      10.245.119.67   <none>           6379/TCP         21m

appサービスに関連付けられているEXTERNAL_IPは、アプリケーションにアクセスできるIPアドレスです。 EXTERNAL_IP列に<pending>ステータスが表示されている場合は、ロードバランサーがまだ作成中であることを意味します。

その列にIPが表示されたら、ブラウザでhttp://your_lb_ip:3000に移動します。

次のランディングページが表示されます。

Get SharkInfoボタンをクリックします。 新しいサメを作成するためのボタンのあるページが表示されます。

それをクリックし、プロンプトが表示されたら、チュートリアルシリーズの前半のユーザー名とパスワードを入力します。 これらの値を変更しなかった場合、デフォルトはそれぞれsammysharkです。

フォームに、選択したサメを追加します。 実例を示すために、Megalodon SharkShark Name フィールドに追加し、AncientSharkCharacterフィールドに追加します。

送信ボタンをクリックします。 このサメの情報が表示されたページが表示されます。

これで、Kubernetesクラスターで実行されているPostgreSQLデータベースを使用したRailsアプリケーションのシングルインスタンスセットアップができました。 また、ユーザーが送信したデータを処理するためのRedisキャッシュとSidekiqワーカーもあります。

結論

このチュートリアルで作成したファイルは、本番環境に移行する際の出発点として適しています。 アプリケーションを開発するときに、次の実装に取り組むことができます。