Scalable web application on Red Hat OpenShift on IBM Cloud
This tutorial may incur costs. Use the Cost Estimator to generate a cost estimate based on your projected usage.
This tutorial walks you through how to deploy an application to a Red Hat OpenShift on IBM Cloud cluster from a remote Git repository, expose the application on a route, monitor the health of the environment, and scale the application. Additionally, you will learn how to use a private container registry, deploy an application from a private Git repository and bind a custom domain to the application.
With Red Hat OpenShift on IBM Cloud, you can create Kubernetes clusters with worker nodes that come installed with the OpenShift Container Platform. For more information about the OpenShift Container Platform architecture, see the Red Hat OpenShift docs. You get all the advantages of a managed service for your cluster.
Objectives
- Deploy a web application to the Red Hat OpenShift on IBM Cloud cluster.
- Bind a custom domain.
- Monitor the logs and health of the cluster.
- Scale Red Hat OpenShift on IBM Cloud pods.
- The developer deploys a web application using the code from a remote Git repository. Optionally, the developer can also push the code to a private Git repository on IBM Cloud.
- A container image is built from the code.
- The image is pushed to a local container registry that comes with the cluster or to a namespace in the IBM Cloud Container Registry.
- The application is deployed to a Red Hat OpenShift on IBM Cloud cluster by pulling the image.
- Users access the application through a public route.
Before you begin
This tutorial requires:
- IBM Cloud CLI,
- IBM Cloud Kubernetes Service plugin (
kubernetes-service
), - (optional) Container Registry plugin (
container-registry
)
- IBM Cloud Kubernetes Service plugin (
- Docker engine,
oc
to interact with Red Hat OpenShift on IBM Cloud,git
to clone the source code repository,- (optional) IBM Cloud GitLab configured with your SSH key. Check the instructions under the
Generate an SSH key pair
andAdd an SSH key to your GitLab account
sections of the documentation here
You will find instructions to download and install these tools for your operating environment in the Getting started with tutorials guide.
To avoid the installation of these tools, you can use the Cloud Shell from the IBM Cloud console. Use oc version
to ensure the version of the Red Hat OpenShift on IBM Cloud CLI matches your cluster version (4.13.x
).
If they do not match, install the matching version by following these instructions.
In addition, make sure you set up a registry namespace.
Create an Red Hat OpenShift on IBM Cloud cluster
With Red Hat OpenShift on IBM Cloud, you have a fast and secure way to containerize and deploy enterprise workloads on Kubernetes clusters. Red Hat OpenShift on IBM Cloud clusters builds on Kubernetes container orchestration that offers consistency and flexibility for your development lifecycle operations.
In this section, you will provision a Red Hat OpenShift on IBM Cloud cluster in one (1) zone with two (2) worker nodes:
- Create an Red Hat OpenShift on IBM Cloud cluster from the IBM Cloud® catalog.
- Under Infrastructure choose VPC or Classic,
- For Red Hat OpenShift on IBM Cloud on VPC infrastructure, you are required to create a VPC and one subnet prior to creating the cluster. Create or use an existing VPC keeping in mind the following requirements:
- One subnet that can be used for this tutorial, take note of the subnet's zone and name.
- A public gateway is attached to the subnet, for more details, see Creating VPC clusters.
- For Red Hat OpenShift on IBM Cloud on VPC infrastructure, you are required to create a VPC and one subnet prior to creating the cluster. Create or use an existing VPC keeping in mind the following requirements:
- Under Location,
- For Red Hat OpenShift on IBM Cloud on VPC infrastructure
- Uncheck the inapplicable zones and subnets.
- In the desired zone verify the desired subnet name and if not present click the edit pencil to select the desired subnet name
- For Red Hat OpenShift on IBM Cloud on Classic infrastructure:
- Select a Resource group.
- Select a Geography.
- Select Single zone as Availability.
- Choose a Worker zone.
- For more details, see the Creating classic clusters instructions.
- For Red Hat OpenShift on IBM Cloud on VPC infrastructure
- Set the OpenShift version to 4.13.x (Note: If you choose to use a version of 4.15.xx and higher, you need to switch off Outbound traffic protection).
- Select your OpenShift Container Platform (OCP) license.
- Under Worker pool,
- Select 4 vCPUs 16GB Memory as the flavor.
- Select 2 Worker nodes per data center for this tutorial (if you selected classic infrastructure: Leave Encrypt local disk).
- Under Cluster details:
- Set Cluster name to
myopenshiftcluster
. - Select a Resource group (if you selected VPC infrastructure).
- Set Cluster name to
- Click Create to provision an Red Hat OpenShift on IBM Cloud cluster.
Take a note of the resource group selected above. This same resource group will be used for all resources in this lab.
Configure CLI
In this step, you'll configure oc
to point to your newly created cluster. The Red Hat OpenShift on IBM Cloud Container Platform CLI exposes commands for managing your applications, as well as lower level tools to interact with each component of your system. The CLI is available using the oc
command.
- When the cluster is ready, click on OpenShift web console to open the console.
- On the web console, from the dropdown menu in the upper right of the page, click Copy Login Command and then click the Display Token link.
- Copy the text found under Log in with this token.
- Once logged-in using the
oc login
command, run the command below to see all the namespaces in your cluster.oc get ns
Create a new Red Hat OpenShift on IBM Cloud application
In this section, you will create a Red Hat OpenShift on IBM Cloud project and then deploy an application from a GitHub repository. The code for this application is a simple Node.js landing page and two API endpoints to get started. You can always extend this application based on your own exploration requirements.
Create a project
A Kubernetes namespace provides a mechanism to scope resources in a cluster. In Red Hat OpenShift on IBM Cloud, a project is a Kubernetes namespace with additional annotations.
- Define an environment variable named
MYPROJECT
and set the application name by replacing<your-initials>
with your own initials :export MYPROJECT=<your-initials>-openshiftapp
- Create a new project.
After creating a project using the above command, you are automatically switched to that project and all commands that follow run in the context of that project. If you need to switch projects or go back into that project at a later stage, use theoc new-project $MYPROJECT
oc project $MYPROJECT
command.
Deploy an application
With the oc new-app
command you can create applications from source code in a local or remote Git repository.
-
Create an application using the
docker
build strategy to build a container image from a Dockerfile in the repo. You are setting the application name to the project name for simplicity.oc new-app https://github.com/IBM-Cloud/openshift-node-app --name=$MYPROJECT --strategy=docker --as-deployment-config
If a Jenkins file exists in the root or specified context directory of the source repository when creating a new application, Red Hat OpenShift on IBM Cloud generates a
pipeline
build strategy. Otherwise, it generates asource
build strategy. You can always override the build strategy by setting the--strategy
flag. -
To check the builder container image creation and pushing to the internal Red Hat OpenShift on IBM Cloud Container Registry (OCR), run the command below.
oc logs -f buildconfig/$MYPROJECT
Your cluster is set up with the internal Red Hat OpenShift on IBM Cloud Container Registry so that Red Hat OpenShift on IBM Cloud can automatically build, deploy, and manage your application lifecycle from within the cluster.
-
Wait until the build is successful and the image is pushed. You can check the status of deployment and service by running the command below.
oc status
Access the application through IBM provided domain
To access the application, you need to create a route. A route announces your service to the world.
-
Create a route by running the command below in a terminal.
oc expose service/$MYPROJECT
-
You can access the application through an IBM provided domain. Run the command below to obtain the URL.
oc get route/$MYPROJECT
-
Copy the value for the hostname under HOST/PORT value and paste the URL in a browser to see your application in action at
http://<hostname>
. Make sure to usehttp
in the URL. -
Set an environment variable pointing to the hostname.
export HOST=<hostname>
Secure the default IBM provided domain route
- To create a secured HTTPS route encrypted with the default certificate for Red Hat OpenShift on IBM Cloud, you can use the
create route
command.oc create route edge $MYPROJECT-https --service=$MYPROJECT --port=3000
- For the HTTPS HOST URL, run
oc get routes
. Copy and paste the URL with HTTPS(https://<HOST>
) next to the route $MYPROJECT-https in a browser. This time you can usehttps
in the URL.
Monitor the app
In this section, you will learn to monitor the health and performance of your application. OpenShift Container Platform ships with a pre-configured and self-updating monitoring and alerting stack.
- From a terminal, run the command with the route URL to generate a load. The command will endlessly send requests to the application.
while sleep 1; do curl --max-time 2 -s http://$HOST/load/50; done
- In the OpenShift web console, switch to the Administrator view.
- Under Observe, select Metrics.
- In the expression box, enter the expression below, replace
<MYPROJECT>
by your project name and click Run queries to see the total container cpu usage in seconds in a graph.sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace="<MYPROJECT>"}) by (container)
- Under Observe, select Dashboards.
- Click on the Dashboard dropdown and select Kubernetes / Compute Resources / Namespace (Workloads).
- Change Namespace to your project.
- Set Time Range to Last 5 minutes.
- Check the CPU and memory usage.
- Stop the above script using
control+C
. - For logging, you can use the in-built
oc logs
command. Check viewing logs for a resource to learn about the usage ofoc logs
.
You can also provision and use IBM Log Analysis and IBM Cloud Monitoring services for logging and monitoring your Red Hat OpenShift on IBM Cloud application. Follow the instructions mentioned in this link to setup logging and monitoring add-ons to monitor cluster health.
Scale the app
In this section, you will learn how to manually and automatically scale your application.
Manual scaling
- You can achieve manual scaling of your pods with
oc scale
command. The command sets a new size for a deployment configuration or replication controlleroc scale dc/$MYPROJECT --replicas=2
- You can see a new pod being provisioned by running
oc get pods
command. - Rerun the Monitoring step to see the updated metrics.
Autoscaling
You can use a horizontal pod autoscaler (HPA) to specify how Red Hat OpenShift on IBM Cloud should automatically increase or decrease the scale of a deployment configuration(dc) or replication controller(rc), based on metrics collected from
the pods that belong to that dc
or rc
.
- Before you can setup autoscaling for your pods, you first need to set resource limits on the pods running in the cluster. Limits allows you to choose the minimum and maximum CPU and memory usage for a pod. You can set the limits and requests
on a container using
oc set resources
command.
To verify, runoc set resources dc/$MYPROJECT --limits=cpu=250m,memory=512Mi --requests=cpu=100m,memory=256Mi
oc describe dc/$MYPROJECT
and look forLimits
andRequests
. - To create an autoscaler, you need to run the
oc autoscale
command with the lower(min) and upper(max) limits for the number of pods that can be set by the autoscaler and the target average CPU utilization (represented as a percent of requested CPU) over all the pods. For testing, let's set--cpu-percent
to 5%.oc autoscale dc/$MYPROJECT \ --min=1 \ --max=5 \ --cpu-percent=5
- Rerun the Monitoring step to generate load on the application.
- You can see new pods being provisioned by running
oc get pods --watch
command or by looking at the application in the web console. - Remove the auto scaler:
oc delete hpa/$MYPROJECT
(Optional) Build and push the container image to Container Registry
In this section, you will learn how to use a remote private Container Registry to store the created container images.
IBM Cloud Container Registry provides a multi-tenant, highly available, scalable, and encrypted private image registry that is hosted and managed by IBM. You can use IBM Cloud Container Registry by setting up your own image namespace and pushing container images to your namespace.
-
To identify your Container Registry URL, run:
ibmcloud cr region
-
Define an environment variable named
MYREGISTRY
pointing to the registry such as:export MYREGISTRY=us.icr.io
-
Pick one of your existing registry namespaces or create a new one. To list existing namespaces, use:
ibmcloud cr namespaces
To create a new namespace:
ibmcloud cr namespace-add <REGISTRY_NAMESPACE>
-
Define an environment variable named
MYNAMESPACE
pointing to the registry namespace:export MYNAMESPACE=<REGISTRY_NAMESPACE>
-
Define an environment variable name
API_KEY
pointing to an IBM Cloud IAM API key:export API_KEY=<YOUR_API_KEY>
To create an API key, refer to this link.
-
To automate access to your registry namespaces and to push the generated builder container image to Container Registry, create a secret:
oc create secret docker-registry push-secret --docker-username=iamapikey --docker-password=$API_KEY --docker-server=$MYREGISTRY
-
Copy and patch the image-pull secret from the
default
project to your project:oc get secret all-icr-io -n default -o yaml | sed 's/default/'$MYPROJECT'/g' | oc -n $MYPROJECT create -f -
-
For the image pull secret to take effect, you need to add it in the
default
service account:oc secrets link serviceaccount/default secrets/all-icr-io --for=pull
Clone a sample application
In this section, you will clone a GitHub repository which comes with a template file and a shell script to generate a yaml
file from your previously created environment variables. The generated file is used to build a container
image, push the image to the private container registry and deploy a new application.
- In a terminal, run the command below to clone the GitHub repository to your machine:
git clone https://github.com/IBM-Cloud/openshift-node-app
- Change to the application directory:
cd openshift-node-app
Update the BuildConfig and Push the builder image to Container Registry
In this step, you run a script to update the sections of the openshift.template.yaml
file and generate a new yaml
file pointing to your Container Registry namespace.
-
Run the below bash script to update the placeholders in the
openshift.template.yaml
file and to generate openshift_private_registry.yaml file../generate_yaml.sh use_private_registry
-
Run the export command from the output to set the existing
MYPROJECT
environment variable with the new application name. Runecho $MYPROJECT
to see the new application name. -
Optionally, check the generated
openshift_private_registry.yaml
file to see if all the placeholders are updated with the respective environment variables. The below are 3 places to do a quick check. You can skip to the next section. -
Optional Locate the ImageStream object with the name attribute set to your project (
$MYPROJECT
) and check whether the placeholders$MYREGISTRY
,$MYNAMESPACE
, and$MYPROJECT
underdockerImageRepository
definition ofspec
are updated- apiVersion: image.openshift.io/v1 kind: ImageStream metadata: annotations: openshift.io/generated-by: OpenShiftNewApp creationTimestamp: null labels: app: $MYPROJECT app.kubernetes.io/component: $MYPROJECT app.kubernetes.io/instance: $MYPROJECT name: $MYPROJECT spec: dockerImageRepository: $MYREGISTRY/$MYNAMESPACE/$MYPROJECT lookupPolicy: local: false status: dockerImageRepository: ""
An image stream and its associated tags provide an abstraction for referencing container images from within Red Hat OpenShift on IBM Cloud Container Platform
-
Optional Check the
spec
underBuildConfig
section for the output set to kindDockerImage
and placeholders undername
updated.spec: nodeSelector: null output: to: kind: DockerImage name: $MYREGISTRY/$MYNAMESPACE/$MYPROJECT:latest pushSecret: name: push-secret
A build is the process of transforming input parameters into a resulting object. Most often, the process is used to transform input parameters or source code into a runnable image. A
BuildConfig
object is the definition of the entire build process. -
Optional Search for
containers
, check theimage
andname
containers: - image: $MYREGISTRY/$MYNAMESPACE/$MYPROJECT:latest name: $MYPROJECT
-
If updated, save the YAML file.
Deploy the application using the IBM Cloud Container Registry
In this section, you will deploy the application to the cluster using the generated openshift_private_registry.yaml file. Once deployed, you will access the application by creating a route.
-
Create a new OpenShift application along with a buildconfig(bc), deploymentconfig(dc), service(svc), imagestream(is) using the updated yaml.
oc apply -f openshift_private_registry.yaml
-
To check the builder container image creation and pushing to the Container Registry, run the command below.
oc logs -f bc/$PRIVREG
In the logs, you should see the below message if the container image is pushed to the private container registry.
Pushing image us.icr.io/mods15/vmac-openshift-app-registry:latest ... Getting image source signatures Copying blob sha256:9d038e1c7afbe92c29313557c02110e8fb796818ebb78441c68929381103a94b Copying blob sha256:61c671f49591a059c9b6728a9f84c16f5b00126470112ee9c9f9e01dbbfcc3ea Copying blob sha256:e2787650308235c87eff7d2b88c3ab217e84b74a3fa9696103bd46bb99068c7a Copying blob sha256:dcef409117430ed9906a59ad0a3ea0752061fbf8a9e544f4edd77667a25d85ae Copying blob sha256:a1f889dd610c6510c7fc091a51c247463f3cc9a7c67bdc397c9632168808f7d2 Copying blob sha256:bd278801acd18ada10f43b732113a6fffc163011862ea6cde729f8dc59e64222 Copying blob sha256:2d6c03ed5d15be86cdef7d9c0c9fea40a3f6b89662bca59680d037074f52bb38 Copying blob sha256:fa2ef7f80d6fc9543f6eb472846931ed1cec2b5f776d1b67bcb1b9942e1a947e Copying blob sha256:ff5a4e4d3690ccc931900b63714d326cc53a58e644f8d0a4f06bf8c62f11c5c7 Copying config sha256:01aa1ebb7be74529867106100c4e699ca2ae87f8242460771527f772e6a3d174 Writing manifest to image destination Storing signatures Successfully pushed us.icr.io/mods15/vmac-openshift-app-registry@sha256:6847b889397704b9fb8c3122c84b505c3dc5f99a0669fb69f534d3504eec385d Push successful
-
You can check the status of deployment and service.
oc status
-
Manually import the latest image stream to ensure the deployment takes place as soon as possible.
oc import-image $PRIVREG
You can also use the command if the deployment is taking more time, Refer to this link for more info.
-
Expose the service to create a new route.
oc expose service/$PRIVREG
-
You can access the application through IBM provided domain. Run the command below to obtain the URL.
oc get route/$PRIVREG
-
Copy the value for the hostname under HOST/PORT value and paste the URL in a browser to see your application in action at
http://<hostname>
. Make sure to usehttp
in the URL.You should see the same application exposed on a different route and deployed using the container image stored in a private container registry.
(Optional) Push the code to a private IBM Cloud Git repository
In this step, you will create a private IBM Cloud Git repository and push the sample application code. You will also learn how to automatically build and redeploy when the application is updated.
You need to configure an SSH key for the push to be successful, review the instructions under the Generate an SSH key pair
and Add an SSH key to your GitLab account
sections of the documentation here
-
In a browser, open IBM Cloud Git.
The link above is for
us-south
region. For other regions, runibmcloud regions
and replaceus-south
in the URL with region name. -
Click on New project, click on Create blank project, and then provide
openshiftapp
as the project name. -
Set the Visibility Level to Private.
-
Under Project Configuration remove the check mark next to Initialize repository with a README.
-
Click Create project,
-
Follow the instructions under Git global setup and Push an existing Git repository sections to setup Git and to push the sample application code.
-
Once you push the code to the private repository, you should see the sample code in the project.
Create a Git deploy token
In this section, you will create a Git deploy token to allow read-only access to your repository.
To generate a deploy token:
- In the navigation panel of the Git repo page, click Settings > Repository.
- Click on Expand next to Deploy Tokens.
- In the Name filed, type
foropenshift
and then select read_repository under Scopes. Finally click on Create deploy token. - Save the generated username and password for future reference.
- In the Name filed, type
- In the navigation panel, click on Project overview then click on Clone and copy Clone with HTTPS URL. Save the URL for future reference.
- Define environment variables for the username, password and private Git repo URL to be used with the YAML file later in the tutorial
export GIT_TOKEN_USERNAME=<PRIVATE_GIT_DEPLOY_TOKEN_USERNAME> export GIT_TOKEN_PASSWORD=<PRIVATE_GIT_DEPLOY_TOKEN_PASSWORD> export REPO_URL=<PRIVATE_GIT_REPO_URL>
Deploy a new application using the private registry and the code from private repository
-
Run the below bash script to update the placeholders in the
openshift.template.yaml
file and to generate openshift_private_repository.yaml file../generate_yaml.sh use_private_repository
-
Run the export command from the output to set the existing
MYPROJECT
environment variable with new project name. -
Additional to the private container registry placeholders, the script will also replace the
REPO_URL
underBuildConfig
spec with the the environment variables you set in the above step,source: git: uri: $REPO_URL type: Git
-
Create a new openshift application along with a buildconfig(bc), deploymentconfig(dc), service(svc), imagestream(is) using the updated yaml
oc apply -f openshift_private_repository.yaml
-
You can check the builder logs.
oc logs -f bc/$PRIVREPO
-
You can check the status of deployment and service using.
oc status
-
Manually import the latest image stream to ensure the deployment takes place as soon as possible.
oc import-image $PRIVREPO
-
Expose the service to create a new route.
oc expose service/$PRIVREPO
-
You can access the application through IBM provided domain. Run the command below to obtain the URL.
oc get route/$PRIVREPO
-
Copy the value for the hostname under HOST/PORT value and paste the URL in a browser to see your application in action at
http://<hostname>
. Make sure to usehttp
in the URL.A new application is deployed using the code from the private Git repo and the container image from the private registry namespace.
Update the application and redeploy
In this step, you will automate the build and deploy process. Whenever you update the application and push the changes to the private repository, a new build runs generating a new version of the container image. This image is then deployed automatically.
-
You will create a new GitLab Webhook trigger. Webhook triggers allow you to trigger a new build by sending a request to the Red Hat OpenShift on IBM Cloud Container Platform API endpoint.You can define these triggers using GitHub, GitLab, Bitbucket, or Generic webhooks.
oc set triggers bc $PRIVREPO --from-gitlab
-
To add a webhook on the GitLab repository, you need a URL and a secret
- For webhook GitLab URL,
oc describe bc/$PRIVREPO | grep -A 1 "GitLab"
- For secret that needs to be passed in the webhook URL,
oc get bc/$PRIVREPO -o yaml | grep -A 3 "\- gitlab"
- Replace
<secret>
in the webhook GitLab URL with the secret value under gitlab in the above command output.
- For webhook GitLab URL,
-
Open your private git repo in a browser using the Git repo HTTPS link then click on Settings and click Webhooks.
-
Paste the URL, select Push events as the Trigger and click on Add webhook. You should see
Webhook was created
message. -
Update the ImagePolicy of the image stream to query Container Registry at a scheduled interval to synchronize tag and image metadata. This will update the
tags
definitionoc tag $MYREGISTRY/$MYNAMESPACE/${PRIVREPO}:latest ${PRIVREPO}:latest --scheduled=true
-
Open the cloned repository in an IDE to update the
h1
tag of local public/index.html file and change it toCongratulations! <insert your name>
. -
Save and push the code to the repository.
git add public/index.html
git commit -m "Updated with my name"
git push -u origin master
-
You can check the progress of the build and deploy with
oc status
command. Once the deployment is successful, refresh the route HOST address to see the updated web app.Sometimes, the deployment may take up to 15 minutes to import the latest image stream. You can either wait or manually import using
oc import-image $PRIVREPO
command. Refer to this link for more info.
(Optional) Use your own custom domain
This section requires you to own a custom domain and to be able to modify the DNS records of the domain. You will need to create a CNAME
record pointing to the IBM-provided domain.
Steps for setting up the CNAME record vary depending on your DNS provider. Under DNS Management/Zone of your domain, add a new CNAME
record, set Host(name) to openshiftapp
or any subdomain you like
and set Points to to IBM-provided domain without HTTP or HTTPS
With HTTP
- Create a route exposing the service at a hostname by replacing
<HOSTNAME>
with your hostname(e.g.,www.example.com or openshiftapp.example.com), so that external clients can reach it by name.oc expose svc/$PRIVREPO --hostname=<HOSTNAME> --name=$PRIVREPO-domain --port=3000
- Access your application at
http://<HOSTNAME>/
With HTTPS
- To create a secured HTTPS route, you can use your own certificate and key files from a CA like Let's Encrypt or order through Secrets Manager.
Pass them with the
create route
command
Here, you have used Edge termination. To learn about other secured routes and termination types like passthrough and re-encryption, runoc create route edge $PRIVREPO-httpsca --service=$PRIVREPO --cert=example.pem --key=example.key --hostname=<www.HOSTNAME> --port=3000
oc create route --help
command)
Remove resources
-
Delete all resource objects specific to an application:
oc delete all --selector app=$PRIVREPO oc delete all --selector app=$PRIVREG oc delete all --selector app=$MYPROJECT
To list the application names in the project, run
oc get svc | awk '{print $1}'
-
Delete the project:
oc delete project $MYPROJECT
-
Delete the application repository:
- In the navigation panel of the Git repository page, click Settings > General.
- Click on Expand next to Advanced.
- Click on Delete project and confirm the deletion of the project.
-
Delete container image(s) from the Container Registry:
- Using your browser, navigate to the repositories page for the Container Registry.
- Select the image(s) created as part of this tutorial and delete them.
-
Delete the cluster you created.