Red Hat OpenShift - Group home

Using Red Hat odo deploy command to deploy applications on IBM Z and IBM LinuxONE

  

Authors: Rishika Kedia, Harshitha M S, Surender Yadav

The Odo deploy command is helping to deploy microservice based applications on Red Hat OpenShift Container Platform (OCP) cluster in a similar manner they would be deployed by a CI/CD system on IBM® Z® and IBM® LinuxONE. First, by building the images of the containers to deploy that should be deployed, and second, by deploying the Red Hat OpenShift resources necessary to deploy the components.

Using Odo deploy should be deploy stage of development and when you are ready for a production ready environment. For more details on how to deploy your application using odo deploy command follow below steps.

Prerequisites to deploy:

Login to your container registry

Login to either docker or podman container registry that you will be pushing your application to using podman login or docker login.

    $ podman login quay.io
Username:
Password:
Login Succeeded!
    $ docker login docker.io
Username:
Password:
Login Succeeded!
Set the appropriate container build platform

Your container image build must match the same architecture as the cluster you are deploying to.

For example: you will have to cross-build a AMD64 image on a Mac M1 (ARM64) to deploy to a AMD64 cluster.

export DOCKER_DEFAULT_PLATFORM=linux/amd64

Step 1: Create the initial development application

For more details on how to use odo dev please refer this blog article: Using odo dev command to deploy application on IBM Z and IBM® LinuxONE.

Step 2: Containerize the application

To deploy an application, we must containerize it, in order to build and push it to a registry.

We must create a docker file as mentioned below in the same directory where application files are present to containerize it. In the following, I am using a Nodejs sample application.

# Sample copied from https://github.com/nodeshift-starters/devfile-sample/blob/main/Dockerfile

# Install the app dependencies in a full Node docker image
FROM registry.access.redhat.com/ubi8/nodejs-14:latest

# Copy package.json and package-lock.json
COPY package*.json ./

# Install app dependencies
RUN npm install --production

# Copy the dependencies into a Slim Node docker image
FROM registry.access.redhat.com/ubi8/nodejs-14-minimal:latest

# Install app dependencies
COPY --from=0 /opt/app-root/src/node_modules /opt/app-root/src/node_modules
COPY . /opt/app-root/src

ENV NODE_ENV production
ENV PORT 3000

CMD ["npm", "start"]
Step 3: Modify the Devfile

Add respective deployment code to your devfile.yaml as mentioned below.

odo deploy uses Devfile schema 2.2.0 and add variables as shown below.

    # Deploy "kind" ID's use schema 2.2.0+
schemaVersion: 2.2.0
    # Add the following variables code anywhere in devfile.yaml
# This MUST be a container registry you are able to access
variables:
  CONTAINER_IMAGE: quay.io/MYUSERNAME/nodejs-odo-example
  RESOURCE_NAME: my-nodejs-app
  CONTAINER_PORT: "3000"
  DOMAIN_NAME: nodejs.example.com

Note: When copy/pasting to devfile.yaml make sure the lines you inserted are correctly intended.

Add the commands which will be required to deploy your application as shown below.

    # This is the main "composite" command that will run all below commands
commands:
- id: deploy
  composite:
    commands:
    - build-image
    - k8s-deployment
    - k8s-service
    - k8s-url
    group:
      isDefault: true
      kind: deploy

# Below are the commands and their respective components that they are "linked" to deploy
- id: build-image
  apply:
    component: outerloop-build
- id: k8s-deployment
  apply:
    component: outerloop-deployment
- id: k8s-service
  apply:
    component: outerloop-service
- id: k8s-url
  apply:
    component: outerloop-url

We need to add the docker image location as well as Kubernetes deployment and service resources to components section in Devfile as below.

components:

# This will build the container image before deployment
- name: outerloop-build
  image:
    dockerfile:
      buildContext: ${PROJECT_SOURCE}
      rootRequired: false
      uri: ./Dockerfile
    imageName: "{{CONTAINER_IMAGE}}"

# This will create a Deployment in order to run your container image across
# the cluster.
- name: outerloop-deployment
  kubernetes:
    inlined: |
      kind: Deployment
      apiVersion: apps/v1
      metadata:
        name: {{RESOURCE_NAME}}
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: {{RESOURCE_NAME}}
        template:
          metadata:
            labels:
              app: {{RESOURCE_NAME}}
          spec:
            containers:
              - name: {{RESOURCE_NAME}}
                image: {{CONTAINER_IMAGE}}
                ports:
                  - name: http
                    containerPort: {{CONTAINER_PORT}}
                    protocol: TCP
                resources:
                  limits:
                    memory: "1024Mi"
                    cpu: "500m"

# This will create a Service so your Deployment is accessible.
# Depending on your cluster, you may modify this code so it's a
# NodePort, ClusterIP or a LoadBalancer service.
- name: outerloop-service
  kubernetes:
    inlined: |
      apiVersion: v1
      kind: Service
      metadata:
        name: {{RESOURCE_NAME}}
      spec:
        ports:
        - name: "{{CONTAINER_PORT}}"
          port: {{CONTAINER_PORT}}
          protocol: TCP
          targetPort: {{CONTAINER_PORT}}
        selector:
          app: {{RESOURCE_NAME}}
        type: NodePort

To access our application, we need to add Route to the component section of Devfile for Red Hat OpenShift cluster as shown below.

- name: outerloop-url
  kubernetes:
    inlined: |
      apiVersion: route.openshift.io/v1
      kind: Route
      metadata:
        name: {{RESOURCE_NAME}}
      spec:
        path: /
        to:
          kind: Service
          name: {{RESOURCE_NAME}}
        port:
          targetPort: {{CONTAINER_PORT}}
Step 4: Run odo deploy command

Now we are all set to deploy our application so run odo deploy and you can see your application getting deployed to the cluster as below.

$ odo deploy
  __
 /  \__     Deploying the application using my-nodejs-app Devfile
 \__/  \    Namespace: odo-dev
 /  \__/    odo version: v3.7.0
 \__/

↪ Building & Pushing Container: quay.io/MYUSERNAME/nodejs-odo-example
 •  Building image locally  ...
build -t quay.io/MYUSERNAME/nodejs-odo-example -f /home/user/quickstart-demo/nodejs-demo/Dockerfile /home/user/quickstart-demo/nodejs-demo
 ✓  Building image locally
 •  Pushing image to container registry  ...
push quay.io/MYUSERNAME/nodejs-odo-example
 ✓  Pushing image to container registry

↪ Deploying Kubernetes Component: my-nodejs-app
 ✓  Creating resource Deployment/my-nodejs-app

↪ Deploying Kubernetes Component: my-nodejs-app
 ✓  Creating resource Service/my-nodejs-app

↪ Deploying Kubernetes Component: my-nodejs-app
 ✓  Creating resource Ingress/my-nodejs-app

Your Devfile has been successfully deployed
Step 5: Accessing the application

One can access their application by using odo describe component command.

You can use the URI mentioned under Red Hat OpenShift Routes section to access your application.

    odo describe component

Name: my-nodejs-app
Display Name: Node.js Runtime
Project Type: Node.js
Language: JavaScript
Version: 2.1.1
Description: Stack with Node.js 16
Tags: Node.js, Express, ubi8

Running in: Deploy

Supported odo features:
   Dev: true
   Deploy: true
   Debug: false

Container components:
   runtime

Kubernetes components:
   outerloop-deployment
   outerloop-service
   outerloop-url

OpenShift Routes:
   my-nodejs-app: my-nodejs-app-pvala-crt-dev.apps.sandbox-m2.ll9k.p1.openshiftapps.com/
Step 6: Delete resources

After testing your application, you may optionally undeploy using the odo delete component command as below.

$ odo delete component
Searching resources to delete, please wait...
This will delete "my-nodejs-app" from the namespace "odo-dev".
 •  The following resources will get deleted from cluster:
 •      - Deployment: my-nodejs-app
 •      - Service: my-nodejs-app
 •      - Ingress: my-nodejs-app

? Are you sure you want to delete "my-nodejs-app" and all its resources? Yes
 ✓  Deleting resources from cluster [65ms]
The component "my-nodejs-app" is successfully deleted from namespace "odo-dev"