The Red Hat OpenShift CLI, oc, supports different ways to deploy applications to a cluster.
For example, you can use the oc new-app command, which creates the resources required to build and deploy an application to OpenShift.
For complex applications, the oc apply command has the -f option, which provides a file containing all the Kubernetes resources that your application requires.
The file that contains the Kubernetes resources is also called a manifest file.
[user@host ~]$ oc apply -f YAML_FILEUsing a manifest file enables you to define your application Kubernetes requirements declaratively, and also to use a version control system on that file. On the other hand, this approach requires you manually creating and maintaining the manifest files.
For deploying applications with the oc command, this section focuses on the oc new-app approach.
The oc new-app command creates an application and makes it available within the cluster.
In its simplest form, oc new-app takes a single URL argument that points to either a Git repository or a container image.
If the URL points to a Git repository, then OpenShift must containerize the application before it can deploy it.
Consequently, oc determines the container image build strategy by following this process:
If the repository contains a Jenkins file, then OpenShift uses the pipeline strategy, which creates a build pipeline.
If the repository contains a Dockerfile, then OpenShift follows the docker build strategy that uses the Dockerfile.
For other cases OpenShift follows the source build strategy, which uses S2I, a technology that builds the image from source code.
The oc new-app command provides the following options to customize the application build:
Table 2.1. Supported Options
| Option | Description |
|---|---|
--as-deployment-config
| Configures the oc new-app to create a DeploymentConfig resource instead of a Deployment. |
|
| Provides the image stream to be used as either the S2I builder image for an S2I build or to deploy a container image. |
--strategy
|
docker, pipeline or source
|
--code
| Provides the URL to a Git repository to be used as input for an S2I build. |
--image
| Provides the URL to a container image to be deployed. |
--dry-run
| set to true to show the result of the operation without performing it. |
--context-dir
| Provides the path to a directory inside of the git repository to be treated as the application root. |
An image stream is an OpenShift abstraction for decoupling the usage of containers from changes in the container image name.
To get a complete list of options, and to see a list of examples, run the oc new-app -h command.
The oc new-app command adds the following resources to the current project to support building and deploying an application:
A build configuration to build the application container image from either source code or a Dockerfile.
An image stream pointing to either the generated image in the internal registry or to an existing image in an external registry.
A Deployment or a DeploymentConfig resource that uses the image stream as input to create application pods.
A ReplicaSet in the case of a Deployment or a ReplicationController in the case of the DeploymentConfig resource.
A service for all ports that the application container image exposes.
If the application container image does not declare any exposed ports, then the oc new-app command does not create a service.
The following command deploys a MySQL service by using the mysql image stream and adds the db=mysql label to the resources that it creates.
The -e options provide the environment variables that the container needs for configuring the database credentials.
[user@host ~]$ oc new-app -i mysql \
-e MYSQL_USER=user -e MYSQL_PASSWORD=pass \
-e MYSQL_DATABASE=testdb -l db=mysqlBy default, the resources that oc new-app creates use the name of the application Git repository or the existing container image as a base name.
Also, the oc new-app command assigns the app label with this default name to the resources it creates.
The oc new-app command has the --name option to provide a different default name.
The following command creates an application from source code in the PHP programming language.
[user@host ~]$ oc new-app -i php \
https://gitserver.example.com/myrepo.git \
--name=hello \
--as-deployment-configAfter the build and deployment processes complete, use the oc get all command to display the resources in the current project.
The output shows that the oc new-app command creates some additional resources when using the --as-deployment-config option:
[user@host ~]$oc get allNAME READY STATUS RESTARTS AGE pod/hello-1-8hm7p 1/1 Running 0 19mpod/hello-1-build 0/1 Completed 0 19m
pod/hello-1-deploy 0/1 Completed 0 19m
NAME DESIRED CURRENT READY AGE replicationcontroller/hello-1 1 1 1 19m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/hello ClusterIP 172.30.73.222 <none> 8080/TCP,8443/TCP 19m
NAME REVISION DESIRED CURRENT TRIGGERED BY deploymentconfig.../hello 1 1 1 config,image(hello:latest)
NAME TYPE FROM LATEST buildconfig.build.openshift.io/hello Source Git 1
NAME TYPE FROM STATUS STARTED DURATION build.build.openshift.io/hello-1 Source Git@ddfc7fe Complete 19 ... 26s
NAME IMAGE REPOSITORY TAGS UPDATED imagestream.image.openshift.io/hello .../project-name/hello latest 16 ...
Pod running the application container. | |
Pod that builds the application from source code. Inspect the logs of this pod for more information about the application build. | |
The deployer pod that controls the deployment process for the DeploymentConfig resource. | |
The replication controller configuration that the deployment configuration manages. | |
The service that the | |
The deployment configuration that the | |
The build configuration that the | |
The first build is triggered by the | |
The image stream that the oc new-app command creates. It points to the container image that the S2I process creates. |
The following command creates an application from source code in the PHP programming language by using a deployment instead of a deployment configuration:
[user@host ~]$ oc new-app \
--name hello -i php \
--code http://gitserver.example.com/mygitrepo.gitIf your application expects resources such as routes, secrets, or persistent volume claims, then create them by running separate oc commands.
You can delete resources that the oc new-app command creates by using a single oc delete command with the --selector option and the app label.
The following command deletes the resources created by the previous oc new-app command:
[user@host ~]$ oc delete all --selector app=testTo create an application that has multiple components you can run oc new-app several times.
For example, to create a Node.js application with a database you could:
Run the oc new-app command with the URL to a MongoDB database container image.
Run the oc new-app command with the URL to the Git repository for a Node.js application with the service for the MongoDB database.
If you want to inspect resource definitions without creating the resources in the current project, use the -o option:
[user@host ~]$ oc new-app \
-o yaml registry.example.com/mycontainerimageThe resource definitions are sent to the standard output and can be redirected to a file. The resulting file can then be customized or inserted into a template definition.
The odo CLI gives a Kubernetes-native developer experience, allowing you to build, run, and debug your application directly on the cluster.
These operations are all considered part of the inner loop development.
The inner loop is an iterative process that developers run locally before they commit the source code to a shared repository.
Compared to odo, the oc CLI does not have any of these developer-focused features.
Also, with odo you can define the process that your application must follow to go from source code to the application components running in a production cluster.
The set of tasks that compose this process is also known as the outer loop.
Consequently, you can implement your organizational deployment process within the odo outer loop, for example:
Building the deployment artifact
Running integration tests
Running security tests
Deploying the application
Developers can trigger the execution of the preceding steps with odo for every application change they make.
Compared to odo, the oc new-app command lacks the features to define and run a deployment process that fits your organization requirements.
The instructions that odo must follow for the inner loop and the outer loop are defined in a devfile, which is the devfile.yaml file.
The devfile is composed of components, which are Kubernetes-related entities such as container images, containers, manifest files or volumes.
The devfile contains commands that reference components and tie them to an execution phase.
The devfile specification uses the command groups term for the execution phases.
To get a devfile to bootstrap your project, the odo init command tries to detect the programming runtime from the sources in the current working directory.
If you don't specify additional options to the odo init command, odo starts an interactive shell session for configuring a devfile.
This command requires connection to a devfile registry such as https://registry.devfile.io, which is the default.
The current devfile specification defines the following command groups:
build
run
test
debug
deploy
Here is a relation of the odo command and the groups that the command executes:
| odo command | devfile command groups running |
|---|---|
odo dev
| build, run |
odo dev --debug
| build, debug |
odo deploy
| deploy |
There can be more than one command for a command group, but by default, only the command with the isDefault: true configuration runs.
This section focuses on deploying applications, to get more information about working in the inner loop with odo read the reference material.
The odo command offers administrative features to work with the cluster.
For example, you can create a project by running the following command.
[user@host ~]$ odo create project PROJECT_NAMEYou must log in to the cluster before running any of the odo commands that require cluster access.
Version 3 of odo introduces backward incompatible changes.
Because of this, there are online resources that might not work with the current odo version.
The odo documentation lists these changes in the https://odo.dev/docs/user-guides/v3-migration-guide#commands-added-modified-or-removed-in-v3 URL.
To deploy an application by using the odo deploy command, define the tasks that satisfy your outer loop requirements.
Then, you must create commands to implement each individual task and a composite command to run the outer loop commands in sequence.
Finally, in the composite command, define the group with the kind property set to deploy and the isDefault property set to true.
The following devfile provides a simplified example for outer loop development with odo.
This devfile declares a composite command, which runs the following commands:
The build-image command that targets the image-build component.
The image-build component defines a Dockerfile for building the container image.
The deployk8s command that targets the kubernetes-deploy component.
The kubernetes-deploy component references the deployment.yaml, which defines your application Kubernetes resources.
This devfile also relies on a parent devfile that might provide additional features, or default behavior that this devfile can override.
schemaVersion: 2.2.0 metadata: name: nodejs version: 2.1.1 displayName: Node.js Runtime description: Stack with Node.js 16 tags: ["Node.js", "Express", "ubi8"] projectType: "Node.js" language: "JavaScript" provider: Red Hat supportUrl: https://github.com/devfile-samples/devfile-support#support-information parent:id: nodejs registryUrl: "https://registry.devfile.io" components: - name: image-build
image: imageName: nodejs-image:latest
dockerfile: uri: Dockerfile buildContext: . rootRequired: false - name: kubernetes-deploy
kubernetes: uri: deploy.yaml commands:
- id: build-image apply: component: image-build - id: deployk8s apply: component: kubernetes-deploy - id: deploy composite: commands: - build-image - deployk8s group:
kind: deploy isDefault: true
Parent devfile that defines default behavior, which this devfile can override. | |
The | |
The | |
The | |
The | |
The |
This devfile has some implicit requirements to work:
The Dockerfile needs to exist in the same directory as the devfile.yaml.
The contents of this Dockerfile must reference the application source code.
The deploy.yaml containing the Kubernetes resources for the application.
The parent devfile must exist.
You must have podman available and logged in to an image registry where odo pushes the image that the deploy.yaml references.
With the devfile.yaml file in place and all the requirements met, the odo deploy command executes the outer loop steps.
[user@host ~]$odo deploy__ / \__ Running the application in Deploy mode using nodejs Devfile \__/ \ Namespace: odo-example / \__/ odo version: v3.11.0 \__/ ↪ Building & Pushing Image: registry.ocp4.example.com/nodejs-nodejs-image:4673• Building image locally ... [1/2] STEP 1/3: FROM registry.access.redhat.com/ubi8/nodejs-16:latest [1/2] STEP 2/3: COPY package.json package-lock.json* ./ --> Using cache 8ba8...1e0c --> 8ba8d939abb ...output omitted... [2/2] COMMIT registry.ocp4.example.com/nodejs-nodejs-image:4673 --> 54961796442 Successfully tagged registry.ocp4.example.com/nodejs-nodejs-image:4459 549617964421f7b134e9f5dff7b2bb3b7e49b6dcb7ef357b50ec3fc2f38d0572 ✓ Building image locally [2s] • Pushing image to container registry ... ...output omitted... Storing signatures ✓ Pushing image to container registry [1s]
↪ Deploying Kubernetes Component: my-nodejs
✓ Creating resource Deployment/my-nodejs ↪ Deploying Kubernetes Component: my-nodejs-svc
Your Devfile has been successfully deployed
To provide devfile portability, odo can customize the container image names to work with your container registry.
This image renaming process works for the image names that exists in the devfile or in the Kubernetes resources that the devfile references.
The image renaming logic only triggers if you define the ImageRegistry preference by running the following command:
[user@host ~]$ odo preference set ImageRegistry REGISTRY_URL/NAMESPACETo select an image name for renaming, you must create an image component with an imageName property that contains a relative image.
A relative image name does not include the container registry.
...
components:
- image:
imageName: "my-relative-image"
name: relative-image
...The final image names have the following pattern:
ImageRegistry/DevfileName-ImageName:UniqueIdYou can verify the results by inspecting the image registry where odo creates the images or by inspecting the Kubernetes sources that odo creates in the cluster.
After you create a service resource, for example by using the oc new-app command, your application is only accessible from within the cluster.
To provide external access to your application, you can use the oc expose command.
[user@host ~]$ oc expose service SERVICE_NAMEThe oc expose commmand creates a Route resource, which is an OpenShift specific resource.
Refer to the Red Hat OpenShift Development I: Introduction to Containers with Podman course for more information about exposing OpenShift resources.
For more information, refer to the Creating Applications Using the Cli section in the Creating Applications chapter in the Red Hat OpenShift Container Platform 4.12 Building Applications documentation at https://access.redhat.com/documentation/en-us/openshift_container_platform/4.12/html-single/building_applications/index#creating-applications-using-cli