Migrating A Monolithic Website To Micro Services On Google Kubernetes Engine
Migrating A Monolithic Website To Micro Services On Google Kubernetes Engine
Introduction
Why migrate from a monolithic application to a microservices
architecture? Breaking down an application into microservices has
the following advantages, most of these stem from the fact that
microservices are loosely coupled:
Prerequisites
A Google Cloud Platform account with administrative access to
create projects or a project with Project Owner role
A basic understanding of Docker and Kubernetes
already authenticated, and the project is set to your PROJECT_ID.
For example:
You can list the active account name with this command:
gcloud auth list
(Output)
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
(Example output)
Credentialed accounts:
(Output)
[core]
project = <project_ID>
(Example output)
[core]
project = qwiklabs-gcp-44776a13dea667a6
For full documentation of gcloud see the gcloud command-line tool
overview.
Run the following commands to clone the git repo to your Cloud
Shell instance and change to the appropriate directory. You will also
install the NodeJS dependencies so you can test your monolith
before deploying:
cd ~
cd ~/monolith-to-microservices
./setup.sh
Warning
If you get an error about region/zone not being specified, please see
the environment set up section to make sure you set the default
compute zone.
Once the command has completed, run the following to see the
cluster's three worker VM instances:
gcloud compute instances list
Output:
NAME ZONE
MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
You can also view your Kubernetes cluster and related information
in the Cloud Console. From the Navigation menu, scroll down
to Kubernetes Engine and click Clusters.
You should see your cluster named fancy-cluster.
Check my progress
./deploy-monolith.sh
You should see the welcome page for the monolithic website just
like the picture above. The welcome page is a static page that will
be served up by the Frontend microservice later on. You now have
your monolith fully running on Kubernetes!
Check my progress
Google Cloud Build will compress the files from the directory and
move them to a Cloud Storage bucket. The build process will then
take all the files from the bucket and use the Dockerfile to run the
Docker build process. The --tag flag is specified with the host as
gcr.io for the Docker image, the resulting Docker image will be
pushed to the Google Cloud Container Registry.
This process will take a minute, but after it is completed, there will
be output in the terminal similar to the following:
-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------------------------------------------------------
--------
ID CREATE_TIME
DURATION SOURCE
IMAGES STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53 2019-08-29T01:56:35+00:00
33S gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-
abfd382011724422bf49af1558b894aa.tgz
gcr.io/<PROJECT_ID>/orders:1.0.0 SUCCESS
To view your build history or watch the process in real time, in the
Console click the Navigation Menu button on the top left and scroll
down to Tools and click Cloud Build > History. Here you can see a
list of all your previous builds, there should only be 1 that you just
created.
If you click on the build id, you can see all the details for that build
including the log output.
From the build details page you can view the container image that
was created by clicking on the Execution Details tab.
Now that you have containerized the website and pushed the
container to the Google Container Registry, it is time to deploy to
Kubernetes!
Output:
NAME READY STATUS RESTARTS AGE
replicaset.apps/monolith-779c8d95f5 1 1 1
15h
replicaset.apps/orders-5bc6969d76 1 1 1
21s
For purposes of this lab, the exposure of the service has been
simplified. Typically, you would use an API gateway to secure your
public endpoints. Read more here about microservices best
practices.
When you deployed the Orders service, you exposed it on port 8081
internally via a Kubernetes deployment. In order to expose this
service externally, you need to create a Kubernetes service of
type LoadBalancer to route traffic from port 80 externally to internal
port 8081.
Output:
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
Reconfigure Monolith
Since you removed the Orders service from the monolith, you will
have to modify the monolith to point to the new external Orders
microservice.
You need to update your config file in the monolith to point to the
new Orders microservices IP address. Use the nano editor to
replace the local URL with the IP address of the Orders
microservice:
cd ~/monolith-to-microservices/react-app
nano .env.monolith
When the editor opens, your file should look like this:
REACT_APP_ORDERS_URL=/service/orders
REACT_APP_PRODUCTS_URL=/service/products
REACT_APP_PRODUCTS_URL=/service/products
Next, rebuild the monolith frontend and repeat the build process to
build the container for the monolith and redeploy to the GKE cluster.
Check my progress
Find the public IP of the Products services the same way you did for
the Orders service:
kubectl get service products
Output:
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
You will use the IP address in the next step when you reconfigure
the monolith to point to your new Products microservice.
Reconfigure Monolith
Use the nano editor to replace the local URL with the IP address of
the new Products microservices:
cd ~/monolith-to-microservices/react-app
nano .env.monolith
When the editor opens, your file should look like this:
REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=/service/products
Test the new microservice by navigating the URL you just set in the
file. The webpage should return a JSON response from the
Products microservice.
Next, rebuild the monolith frontend and repeat the build process to
build the container for the monolith and redeploy to the GKE cluster.
Run the following commands complete these steps:
Check my progress
Previously when you rebuilt the monolith you updated the config to
point to the monolith. Now you need to use the same config for the
frontend microservice.
cp .env.monolith .env
Check my progress