Google Kubernetes Engine で Node.js Bookshelf アプリを実行する

このチュートリアルでは、Google Kubernetes Engine(GKE)Node.js Bookshelf サンプルアプリを実行する方法を説明します。既存の Node.js ウェブアプリを GKE にコンテナ化しデプロイします。App Engine スタンダード環境のチュートリアルの一部として、Bookshelf アプリのドキュメントを参照することをおすすめします。

目標

  • GKE クラスタを作成する。
  • Node.js アプリをコンテナ化する。
  • Bookshelf アプリ用のレプリケート済みのフロントエンドを作成する。
  • Bookshelf アプリ用のレプリケート済みのバックエンドを作成する。
  • HTTP トラフィックを Bookshelf アプリのフロントエンドに転送する、負荷分散サービスを作成する。

料金

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

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

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

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

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

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

  4. Datastore、GKE、Cloud Storage、Pub/Sub API を有効にします。

    API を有効にする

  5. Cloud SDK をインストールし、初期化します
  6. Docker をインストールします。Docker はコンテナ イメージをローカルでビルドします。
  7. kubectl をインストールします。
    gcloud components install kubectl

GKE クラスタの作成

GKE クラスタは、単一の GKE クラスタとして動作する Compute Engine 仮想マシン(VM)のマネージド セットです。このチュートリアルでは、2 つ以上のノードから構成されるクラスタを使用します。このようなノードでは、すべての Google API へのアクセス権が必要です。

  1. クラスタを作成します。[YOUR_GCP_ZONE] は、クラスタをホストする Google Cloud ゾーンで置き換えます。

    gcloud container clusters create bookshelf \
        --scopes "cloud-platform" \
        --num-nodes 2 \
        --enable-basic-auth \
        --issue-client-certificate \
        --enable-ip-alias \
        --zone [YOUR_GCP_ZONE]
    
  2. クラスタに対するアクセス権があることを確認します。次のコマンドは、コンテナ クラスタ内のノードを一覧表示し、コンテナ クラスタが実行中でそのコンテナ クラスタに対するアクセス権があることを示します。

    kubectl get nodes
    

GKE クラスタでリソースを作成するには、kubectl コマンドを使用します。kubectl の詳細については、GKE クラスタの操作をご覧ください。通常、gcloud を使用して Google Cloud プロジェクトのリソースを管理し、kubectl を使用して GKE クラスタのリソースを管理します。1 つのプロジェクトに複数のクラスタを含めることができます。これにより、さまざまなニーズに合わせて異なるマシンタイプから構成されるクラスタを作成できます。

gcloud でクラスタを作成する場合は、認証は自動的に kubectl に設定されます。Google Cloud Consoleを使用してクラスタを作成する場合は、gcloud container clusters get-credentials コマンドを使用して認証を設定します。

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

サンプルアプリは GitHub の GoogleCloudPlatform/nodejs-getting-started で入手できます。

  1. リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/nodejs-getting-started.git
    
  2. サンプル ディレクトリに移動します。

    cd nodejs-getting-started/optional-kubernetes-engine
    
  3. git ブランチを確認します。

    git checkout 6ac2954e07c15dcf032a18d2f757b736d6a6f50c
    

データストアの初期化

Bookshelf アプリは Datastore を使用して書籍データを保存します。プロジェクト内の Datastore を初めて初期化するには、次の手順に従います。

  1. Cloud Console で [Datastore] ページを開きます。

    [データストア] ページに移動

  2. データストアのリージョンを選択します。

  3. [続行] をクリックし、[エンティティの作成] ページが表示されたらウィンドウを閉じます。これで、Bookshelf アプリでデータストア内のエンティティを作成する準備ができました。

Cloud Storage バケットの作成

Bookshelf アプリは Cloud Storage を使用して画像ファイルを保存します。

以下では、Cloud Storage バケットの作成方法を詳しく説明します。バケットとは、Cloud Storage 内でデータを保持する基本のコンテナです。

  1. 次のコマンドを実行して、ターミナル ウィンドウで Cloud Storage バケットを作成します。YOUR_BUCKET_NAME は、作成するバケットの名前を表します。

    gsutil mb gs://YOUR_BUCKET_NAME
    
  2. Bookshelf アプリでアップロードした画像を表示するには、バケットのデフォルトのアクセス制御リスト(ACL)を public-read に設定します。

    gsutil defacl set public-read gs://YOUR_BUCKET_NAME
    

アプリの構成

  1. サンプル ディレクトリで、config.json ファイルを作成し、次の内容を含めます。

    { "GCLOUD_PROJECT": "[YOUR_PROJECT_ID]", "CLOUD_BUCKET": "[YOUR_CLOUD_BUCKET]", "DATA_BACKEND": "datastore" }

    • [YOUR_PROJECT_ID] を Google Cloud プロジェクト ID に置き換えます。

    • [YOUR_CLOUD_BUCKET] を Cloud Storage バケットの名前に置き換えます。

  2. config.json ファイルを保存して閉じます。

アプリのコンテナ化

サンプルアプリには Dockerfile が含まれています。これはアプリの Docker イメージの作成に使用します。この Docker イメージによって GKE でアプリが実行されます。

# Dockerfile extending the generic Node image with application files for a
# single application.
FROM gcr.io/google_appengine/nodejs

# Check to see if the the version included in the base runtime satisfies
# '>=8.12.0', if not then do an npm install of the latest available
# version that satisfies it.
RUN /usr/local/bin/install_node '>=8.12.0'
COPY . /app/

# You have to specify "--unsafe-perm" with npm install
# when running as root.  Failing to do this can cause
# install to appear to succeed even if a preinstall
# script fails, and may have other adverse consequences
# as well.
# This command will also cat the npm-debug.log file after the
# build, if it exists.
RUN npm install --unsafe-perm || \
  ((if [ -f npm-debug.log ]; then \
      cat npm-debug.log; \
    fi) && false)
CMD npm start
サンプルアプリには、Docker コンテナに格納されていないファイルパスを一覧表示する .dockerignore ファイルも含まれています。通常、このファイルにはビルド アーティファクトとローカル依存関係のインストールが含まれます。

# Copyright 2018 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

node_modules
.dockerignore
Dockerfile
npm-debug.log
.git
.hg
.svn
  1. アプリの Docker イメージをビルドします。

    docker build -t gcr.io/[YOUR_PROJECT_ID]/bookshelf .
    
  2. クラスタがイメージにアクセスできるように、イメージを Container Registry に push します。

    gcloud docker -- push gcr.io/[YOUR_PROJECT_ID]/bookshelf
    

Bookshelf フロントエンドのデプロイ

Bookshelf アプリにはウェブ リクエストを処理するフロントエンド サーバーと、書籍情報を処理して詳細情報を追加するバックエンド ワーカーがあります。

フロントエンドの実行に必要なクラスタ リソースは、bookshelf-frontend-datastore.yaml ファイルに定義されています。これらのリソースは GKE Deployment と呼ばれます。Deployment を使用すると、レプリカセットとそれに関連付けられたポッドを作成し、更新できます。

# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License

# This file configures the bookshelf application frontend. The frontend serves
# public web traffic.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: bookshelf-frontend
  labels:
    app: bookshelf
# The bookshelf frontend replica set ensures that at least 3
# instances of the bookshelf app are running on the cluster.
# For more info about Pods see:
#   https://cloud.google.com/container-engine/docs/pods/
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: bookshelf
        tier: frontend
    spec:
      containers:
      - name: bookshelf-app
        # Replace [GCLOUD_PROJECT] with your project ID or use `make template`.
        image: gcr.io/[GCLOUD_PROJECT]/bookshelf
        # 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
        # The bookshelf process listens on port 8080 for web traffic by default.
        ports:
        - name: http-server
          containerPort: 8080
        env:
          - name: PROJECT_ID
            value: [GCLOUD_PROJECT]
  1. bookshelf-frontend-datastore.yaml ファイルで、[GCLOUD_PROJECT] を実際のプロジェクト ID で置き換えます。bookshelf-frontend-datastore.yaml ファイルを保存して閉じます。

  2. リソースをクラスタにデプロイします。

    kubectl create -f bookshelf-frontend-datastore.yaml
    
  3. デプロイのステータスを確認します。

    kubectl get deployments
    

    必要な数の利用可能なポッドが作成されたら、デプロイが完了です。

    デプロイで問題が発生した場合は、削除してやり直すことができます。

    kubectl delete deployments bookshelf-frontend
    
  4. デプロイが完了すると、デプロイによって作成されたポッドが表示されます。

    kubectl get pods
    

Bookshelf バックエンドのデプロイ

Bookshelf バックエンドのデプロイはフロントエンドと同じ方法で行います。

# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License

# This file configures the bookshelf task worker. The worker is responsible
# for processing book requests and updating book information.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: bookshelf-worker
  labels:
    app: bookshelf
# The bookshelf worker replica set ensures that at least 2 instances of the
# bookshelf worker pod are running on the cluster.
# For more info about Pods see:
#   https://cloud.google.com/container-engine/docs/pods/
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: bookshelf
        tier: worker
    spec:
      containers:
      - name: bookshelf-app
        # Replace [GCLOUD_PROJECT] with your project ID or use `make template`.
        image: gcr.io/[GCLOUD_PROJECT]/bookshelf
        # 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
        # The SCRIPT environment variable is used by `npm start` to control
        # which script is executed. This tells npm start to use `worker.js`
        # instead of the default `app.js`.
        env:
        - name: SCRIPT
          value: worker.js
        - name: PROJECT_ID
          value: [GCLOUD_PROJECT]
  1. bookshelf-worker-datastore.yaml ファイルで、[GCLOUD_PROJECT] を実際のプロジェクト ID で置き換えます。bookshelf-worker-datastore.yaml ファイルを保存して閉じます。

  2. リソースをクラスタにデプロイします。

    kubectl create -f bookshelf-worker-datastore.yaml
    
  3. ポッドが実行されていることを確認します。

    kubectl get pods
    

Bookshelf サービスの作成

GKE サービスは、一連のポッドへの単一アクセス ポイントを提供します。単一のポッドにアクセスすることも可能ですが、ポッドは存続期間が短いため、単一のエンドポイントからポッドのセットにアクセスする方が便利です。Bookshelf アプリでは、Bookshelf サービスを使用して単一の IP アドレスから複数の Bookshelf フロントエンド ポッドにアクセスできます。このサービスは、bookshelf-service.yaml ファイルに定義されています。

# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License

# The bookshelf service provides a load-balancing proxy over the bookshelf
# frontend pods. By specifying the type as a 'LoadBalancer', Kubernetes Engine
# will create an external HTTP load balancer.
# For more information about Services see:
#   https://cloud.google.com/kubernetes-engine/docs/services/
# For more information about external HTTP load balancing see:
#   https://cloud.google.com/kubernetes-engine/docs/load-balancer
apiVersion: v1
kind: Service
metadata:
  name: bookshelf-frontend
  labels:
    app: bookshelf
    tier: frontend
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: http-server
  selector:
    app: bookshelf
    tier: frontend

ポッドと、ポッドを使用するサービスは別のものです。Kubernetes は、ラベルを使用してサービスのポッドを選択します。ラベルを使用すると、異なるレプリカセットのポッドに対応し、個々のポッドを指す複数のサービスを持つことができます。

  1. Bookshelf サービスを作成します。

    kubectl create -f bookshelf-service.yaml
    
  2. サービスの外部 IP アドレスを取得します。

    kubectl describe service bookshelf
    

    IP アドレスの割り当てには 1 分ほどかかることがあります。外部 IP アドレスは、LoadBalancer Ingress の一覧に表示されます。

Bookshelf アプリへのアクセス

GKE に Bookshelf アプリを実行するために必要なすべてのリソースがデプロイされました。ブラウザでアプリを読み込んで書籍を作成するには、前の手順で外部 IP アドレスを使用します。

ワーカーをデプロイした場合、Google Books API の情報に基づいて書籍情報が自動的に更新されます。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

プロジェクトの削除

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. Cloud Console で [リソースの管理] ページに移動します。

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

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

クラスタの削除

クラスタを削除すると、GKE リソースと Compute Engine リソースはすべて削除されますが、Cloud Storage、Datastore、Pub/Sub のリソースは手動で削除する必要があります。

次のコマンドを使用してクラスタを削除します。[YOUR_PROJECT_ID][YOUR_GCP_ZONE]クラスタを作成する際に使用したプロジェクトとゾーンに置き換えます。

gcloud container clusters delete bookshelf --project [YOUR_PROJECT_ID] --zone [YOUR_GCP_ZONE]

次のステップ