Running the Node.js Bookshelf app on Google Kubernetes Engine

This tutorial shows how to run the Node.js Bookshelf sample app on Google Kubernetes Engine (GKE). Follow this tutorial to containerize and deploy an existing Node.js web app to GKE. We recommend that you work through the Bookshelf app documentation as part of the tutorial for the App Engine standard environment.

Objectives

  • Create a GKE cluster.
  • Containerize a Node.js app.
  • Create a replicated frontend for the Bookshelf app.
  • Create a replicated backend for the Bookshelf app.
  • Create a load-balanced service to route HTTP traffic to the Bookshelf app frontend.

Costs

This tutorial uses the following billable components of Google Cloud:

To generate a cost estimate based on your projected usage, use the pricing calculator. New Google Cloud users might be eligible for a free trial.

When you finish this tutorial, you can avoid continued billing by deleting the resources you created. For more information, see Cleaning up.

Before you begin

  1. Sign in to your Google Account.

    If you don't already have one, sign up for a new account.

  2. In the Cloud Console, on the project selector page, select or create a Google Cloud project.

    Go to the project selector page

  3. Make sure that billing is enabled for your Google Cloud project. Learn how to confirm billing is enabled for your project.

  4. Enable the Datastore, GKE, Cloud Storage, and Pub/Sub APIs.

    Enable the APIs

  5. Install and initialize the Cloud SDK.
  6. Install Docker. Docker builds container images locally.
  7. Install kubectl.
    gcloud components install kubectl

Creating a GKE cluster

A GKE cluster is a managed set of Compute Engine virtual machines (VMs) that operate as a single GKE cluster. This tutorial needs a cluster with a minimum of two nodes, and these nodes need access to all Google APIs.

  1. Create the cluster. Replace [YOUR_GCP_ZONE] with the Google Cloud zone where you want to host your cluster.

    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. Verify that you have access to the cluster. The following command lists the nodes in your container cluster and indicates that your container cluster is running and that you have access to it.

    kubectl get nodes
    

You use the kubectl command to create resources in a GKE cluster. To learn more about kubectl, see GKE cluster operations. In general, you use gcloud to manage resources in your Google Cloud project, and you use kubectl to manage resources in your GKE cluster. A single project can have multiple clusters, which lets you have clusters made up of different machine types to satisfy different needs.

When you create a cluster with gcloud, authentication is set up automatically for kubectl. If you use the Google Cloud Console to create clusters, you can set up authentication by using the gcloud container clusters get-credentials command.

Cloning the sample app

The sample app is available on GitHub at GoogleCloudPlatform/nodejs-getting-started.

  1. Clone the repository:

    git clone https://github.com/GoogleCloudPlatform/nodejs-getting-started.git
    
  2. Go to the sample directory:

    cd nodejs-getting-started/optional-kubernetes-engine
    
  3. Check out the git branch:

    git checkout 6ac2954e07c15dcf032a18d2f757b736d6a6f50c
    

Initializing Datastore

The Bookshelf app uses Datastore to store book data. To initialize Datastore in your project for the first time, complete the following steps:

  1. In the Cloud Console, open the Datastore page.

    Go to the Datastore page

  2. Select a region for your datastore.

  3. Click Continue until you reach the Create an Entity page, and then close the window. The Bookshelf app is ready to create entities in Datastore.

Creating a Cloud Storage bucket

The Bookshelf app uses Cloud Storage to store image files.

The following instructions detail how to create a Cloud Storage bucket. Buckets are the basic containers that hold your data in Cloud Storage.

  1. In your terminal window, create a Cloud Storage bucket, where YOUR_BUCKET_NAME represents the name of your bucket:

    gsutil mb gs://YOUR_BUCKET_NAME
    
  2. To view uploaded images in the Bookshelf app, set the bucket's default access control list (ACL) to public-read:

    gsutil defacl set public-read gs://YOUR_BUCKET_NAME
    

Configuring the app

  1. In the sample directory, create a config.json file with the following content:

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

    • Replace [YOUR_PROJECT_ID] with your Google Cloud project ID.

    • Replace [YOUR_CLOUD_BUCKET] with the name of your Cloud Storage bucket.

  2. Save and close the config.json file.

Containerizing the app

The sample app includes a Dockerfile, which is used to create the app's Docker image. This Docker image runs the app on 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
The sample app also includes a .dockerignore file that lists file paths that aren't included in the resulting Docker container. Typically, this file includes build artifacts and local dependency installations.

# 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. Build the app's Docker image:

    docker build -t gcr.io/[YOUR_PROJECT_ID]/bookshelf .
    
  2. Push the image to Container Registry so that your cluster can access the image:

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

Deploying the Bookshelf frontend

The Bookshelf app has a frontend server that handles the web requests and a backend worker that processes books and adds information.

The cluster resources needed to run the frontend are defined in the bookshelf-frontend-datastore.yaml file. These resources are described as a GKE deployment. You can use deployments to create and update a replica set and its associated pods.

# 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. In the bookshelf-frontend-datastore.yaml file, replace [GCLOUD_PROJECT] with your project ID. Save and close the bookshelf-frontend-datastore.yaml file.

  2. Deploy the resources to the cluster:

    kubectl create -f bookshelf-frontend-datastore.yaml
    
  3. Track the status of the deployment:

    kubectl get deployments
    

    After the deployment has the number of available pods that you want, the deployment is complete.

    If you run into issues with the deployment, you can delete it and start over:

    kubectl delete deployments bookshelf-frontend
    
  4. After the deployment is complete, you can see the pods that the deployment created:

    kubectl get pods
    

Deploying the Bookshelf backend

The Bookshelf backend is deployed the same way as the frontend.

# 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. In the bookshelf-worker-datastore.yaml file, replace [GCLOUD_PROJECT] with your project ID. Save and close the bookshelf-worker-datastore.yaml file.

  2. Deploy the resources to the cluster:

    kubectl create -f bookshelf-worker-datastore.yaml
    
  3. Verify that the pods are running:

    kubectl get pods
    

Creating the Bookshelf service

GKE services provide a single point of access to a set of pods. While it's possible to access a single pod, pods are ephemeral, and it's more convenient to address a set of pods with a single endpoint. In the Bookshelf app, the Bookshelf service lets you access the Bookshelf frontend pods from a single IP address. This service is defined in the bookshelf-service.yaml file.

# 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

Notice that the pods and the service that uses the pods are separate. Kubernetes uses labels to select the pods that a service addresses. By using labels, you can have a service that addresses pods from different replica sets and have multiple services that point to an individual pod.

  1. Create the Bookshelf service:

    kubectl create -f bookshelf-service.yaml
    
  2. Get the service's external IP address:

    kubectl describe service bookshelf
    

    It might take up to a minute to allocate the IP address. The external IP address is listed under LoadBalancer Ingress.

Accessing the Bookshelf app

You've now deployed all the resources needed to run the Bookshelf app on GKE. To load the app in your browser and create books, use the external IP address from the previous step.

If you deployed the worker, the books are automatically updated with information from the Google Books API.

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

Delete the project

The easiest way to eliminate billing is to delete the project that you created for the tutorial.

To delete the project:

  1. In the Cloud Console, go to the Manage resources page.

    Go to the Manage resources page

  2. In the project list, select the project you want to delete and click Delete .
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Delete the cluster

Deleting the cluster removes all GKE and Compute Engine resources, but you need to manually remove any resources in Cloud Storage, Datastore, and Pub/Sub.

Delete the cluster by using the following command. Replace [YOUR_PROJECT_ID] and [YOUR_GCP_ZONE] with the project and zone you used when creating the cluster.

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

What's next

Apakah halaman ini membantu? Beri tahu kami pendapat Anda:

Kirim masukan tentang...