Exercise 3: Deploy to the Kubernetes
In this exercise we will work in the Kubernetes Web Console and with the Kubernetes CLI.
The following image is a simplified overview of the topics of that lab.
overview
This lab has two parts:
  1. 1.
    Start build and save the container image
  2. 2.
    Deploy the application and expose the service
    • We will define and apply a deployment configuration (yaml) to create a Pod with our Microservice
    • We will define a service which routes requests to the Pod with our Microservice
The following gif is an animation of the simplified steps above in a sequence.
overview

Step 1: Ensure you have the terminal session open with the started Docker image and you have downloaded the Cloud Native Starter project also in this running container

Step 2: Navigate to the folder cloud-native-starter/authors-java-jee

Note: You have cloned the project twice: first to your local machine and second into the Docker image. The code changes you did in execrise 2 on your local computer, don't exist in the running Docker container.

1. Build and save the container image

Step 1: Build and save the container image in the IBM Cloud Container Registry

Now we want to build and save a container image in the IBM Cloud Container Registry.
  1. 1.
    Ensure you logon on to IBM Cloud.
    REMEMBER: You should know this from the prerequisites.
    You can follow the steps in the Access tab, by starting from After your cluster provision .. and inserting the commands into your terminal session.
Follow the steps in the Access tab, by starting from "After your cluster provision" and inserting the commands into your terminal session.
  1. 1.
    Logon to the IBM Cloud Container Registry (Ensure you are in the $ROOT_FOLDER/authors-java-jee)
    1
    cd $ROOT_FOLDER/authors-java-jee
    2
    ibmcloud cr login
    Copied!
  2. 2.
    List you namespaces inside the IBM Cloud Container Registry
    1
    ibmcloud cr namespaces
    Copied!
    Example output:
    1
    $ Listing namespaces for account 'Thomas Suedbroecker's Account' in registry 'us.icr.io'...
    2
    $
    3
    $ Namespace
    4
    $ cloud-native-suedbro
    Copied!
  3. 3.
    Build the container image using buildah.
1
buildah bud -t [YOUR_REGISTRY]/[YOUR_REGISTRY_NAMESPACE]/authors:v1 .
Copied!
  1. 1.
    Now upload the container image to the IBM Cloud Container Registry. We use the information from step 3, where we got the list of namespaces.
1
buildah push [YOUR_REGISTRY]/[YOUR_REGISTRY_NAMESPACE]/authors:v1 .
Copied!
Example command:
  • [YOUR_REGISTRY] = us.icr.io
  • [YOUR_REGISTRY_NAMESPACE] = cloud-native-suedbro
1
buildah push us.icr.io/cloud-native-suedbro/authors:v1 .
Copied!
Optional: Verify the container upload in the IBM Cloud web UI.
authors-java-container-image
  1. 1.
    List the container images to verify the upload.
    1
    ibmcloud cr images
    Copied!
    Example output:
    1
    $ Listing images...
    2
    $
    3
    $ Repository Tag Digest Namespace Created Size Security status
    4
    $ us.icr.io/cloud-native-suedbro/authors 1 5a86758f1056 cloud-native-suedbro 2 minutes ago 226 MB 3 Issues
    5
    $
    6
    $ OK
    Copied!
  2. 2.
    Copy the REPOSITORY path for the uploaded Authors container image. In this sample case it would be: us.icr.io/cloud-native-suedbro/authors and save it somewhere, we need this later in the deployment.yaml configuration.

2. Apply the Deployment

This deployment will deploy a container to a Pod in Kubernetes. For more details we use the Kubernetes documentation for Pods.
A Pod is the basic building block of Kubernetes-the smallest and simplest unit in the Kubernetes object model that you create or deploy. A Pod represents processes running on your Cluster .
Here is a simplified image for that topic. The deployment.yaml file points to the container image that needs to be instantiated in the pod.
deployment
Inside the container image cns-workshop-tools you can use the editor nano.
1
nano deployment.yaml
Copied!
Let's start with the deployment yaml. For more details see the Kubernetes documentation for deployments.
Definition of kind defines this as a Deployment configuration.
1
kind: Deployment
2
apiVersion: apps/v1
3
metadata:
4
name: authors
Copied!
In the spec section we specify an app name and version label.
1
spec:
2
...
3
template:
4
metadata:
5
labels:
6
app: authors
7
version: v1
Copied!
Then we define a name for the container and we provide the container image location, e.g. where the container can be found in the Container Registry.
The containerPort depends on the port definition inside our Dockerfile and in our server.xml.
We have previously talked about the usage of the HealthEndpoint class for our Authors service and here we see it the livenessProbe definition.
1
spec:
2
containers:
3
- name: authors
4
image: authors:1
5
ports:
6
- containerPort: 3000
7
livenessProbe:
Copied!
This is the full deployment.yaml file.
1
kind: Deployment
2
apiVersion: apps/v1
3
metadata:
4
name: authors
5
spec:
6
selector:
7
matchLabels:
8
app: authors
9
version: v1
10
replicas: 1
11
template:
12
metadata:
13
labels:
14
app: authors
15
version: v1
16
spec:
17
containers:
18
- name: authors
19
image: us.icr.io/cloud-native-suedbro/authors:1
20
ports:
21
- containerPort: 3000
22
livenessProbe:
23
exec:
24
command: ["sh", "-c", "curl -s http://localhost:3000/"]
25
initialDelaySeconds: 20
26
readinessProbe:
27
exec:
28
command: ["sh", "-c", "curl -s http://localhost:3000/health | grep -q authors"]
29
initialDelaySeconds: 40
30
restartPolicy: Always
Copied!

Step 1: Apply the deployment

  1. 1.
    Ensure you are in the $ROOT_FOLDER/authors-java-jee/deployment
1
cd $ROOT_FOLDER/authors-java-jee/deployment
Copied!
  1. 1.
    Open the ../authors-java-jee/deployment/deployment.yaml file with a editor and replace the value for the container image location with the path we got from the IBM Container Registry and just replace the authors:1 text, and add following statement imagePullPolicy: Always and save the file.
Note: With the specification imagePullPolicy: Always we force that the image is pulled from the IBM Cloud Container Registry and not cashed image in Kubernetes is possible used, when we change our container image IBM Cloud Container Registry.
REMEMBER: You should have saved the IBM Container Registry information somewhere.
Before:
1
image: authors:1
Copied!
Sample change:
1
image: us.icr.io/cloud-native-suedbro/authors:1
2
imagePullPolicy: Always
3
ports:
4
- containerPort: 3000
Copied!
  1. 1.
    Now we apply the deployment and we create a new Authors Pod.
    1
    kubectl apply -f deployment.yaml
    Copied!

Step 2: Verify the deployment with kubectl

  1. 1.
    Insert this command and verify the output.
    1
    kubectl get pods
    Copied!
    Sample output:
    1
    NAME READY STATUS RESTARTS AGE
    2
    authors-7b6dd98db-wl9wc 1/1 Running 0 6m9s
    Copied!

Step 3: Verify the deployment with the Kubernetes dashboard

  1. 1.
    Open your Kubernetes Cluster in the IBM Cloud web console
  2. 2.
    Open the Kubernetes dashbord
  3. 3.
    In the overview you see the created deployment and the pod
In the overview you see the created deployment and the pod

3. Apply the service

After the definition of the Pod we need to define how to access the Pod. For this we use a service in Kubernetes. For more details see the Kubernetes documentation for service.
A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them - sometimes called a micro-service. The set of Pods targeted by a Service is (usually) determined by a Label Selector.
In the service we map the NodePort of the cluster to the port 3000 of the Authors Microservice running in the authors Pod, as we can see in the following picture.
service
In the service.yaml we see a selector of the pod using the label 'app: authors'.
1
kind: Service
2
apiVersion: v1
3
metadata:
4
name: authors
5
labels:
6
app: authors
7
spec:
8
selector:
9
app: authors
10
ports:
11
- port: 3000
12
name: http
13
type: NodePort
14
---
Copied!

Step 1: Ensure you are in the $ROOT_FOLDER/authors-java-jee/deployment

1
cd $ROOT_FOLDER/authors-java-jee/deployment
Copied!

Step 2: Apply the service specification

1
kubectl apply -f service.yaml
Copied!

Step 3: Verify the service in Kubernetes with kubectl

1
kubectl get services
Copied!
Sample output:
1
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
2
authors NodePort 172.21.107.135 <none> 3000:31347/TCP 22s
3
kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 28h
Copied!

Step 4: Verify the service in the Kubernetes dashboard

  1. 1.
    Open your Kubernetes Cluster in the IBM Cloud web console
  2. 2.
    Open the Kubernetes dashbord
deployment
  1. 1.
    In the overview scroll down until you see the created service
service

Step 5: Verify the running Microservice on Kubernetes

  1. 1.
    Get cluster (worker node) IP address and show the IP address
    1
    workernodeip=$(ibmcloud ks workers --cluster cloud-native | awk '/Ready/ {print $2;exit;}')
    Copied!
    1
    echo $workernodeip
    Copied!
    Example output:
    1
    184.172.247.228
    Copied!
    Expose a public port on your worker node and use the public IP address of the worker node to access your service in the cluster publicly from the internet.
  2. 2.
    Get nodeport to access the service (do you remember the mapping?)
    1
    nodeport=$(kubectl get svc authors --ignore-not-found --output 'jsonpath={.spec.ports[*].nodePort}')
    2
    echo $nodeport
    Copied!
    Example output:
    1
    31347
    Copied!
  3. 3.
    Open API explorer.
    1
    echo http://${workernodeip}:${nodeport}/openapi/ui/
    Copied!
    Sample output:
    1
    http://184.172.247.228:31347/openapi/ui/
    Copied!
    Copy and past the URL in a local browser on your PC:
  4. 4.
    Execute curl to test the Authors service.
    1
    curl http://${clusterip}:${nodeport}/api/v1/getauthor?name=Niklas%20Heidloff
    Copied!
    Example output:
    1
    {"name":"Niklas Heidloff","twitter":"@nheidloff","blog":"http://heidloff.net"}
    Copied!
  5. 5.
    Execute following curl command to test the HealthCheck implementation for the Authors service.
    1
    curl http://${workernodeip}:${nodeport}/health
    Copied!
Example output:
1
{"checks":[{"data":{"authors":"ok"},"name":"authors","state":"UP"}],"outcome":"UP"}
Copied!
Optional:
  1. 1.
    We can also verify that call in the browser.
health
  1. 1.
    We can simply delete the deployed Authors Microservice with:
1
kubectl delete -n default deployment authors
Copied!
Congratulations you have finished this hands-on workshop. Maybe you want to verify your learning in the Cloud Native Starter Level 1 Badge.
Last modified 1mo ago