OpenShift is a customized distribution of Kubernetes provided by Red Hat. In OpenShift, containers run using a no-root arbitrarily assigned user ID. This behavior provides an additional security level against processes escaping the container due to a vulnerability and thereby achieving escalated permissions on the host node. Due to this restriction, images that run as root may not be deployed on OpenShift.
In this section, we're going to describe various ways to deploy a containerized software application in OpenShift.
Before to procede, please make sure the internal OpenShift image registry is published outside the cluster, for example it is reachable at https://registry.openshift.noverit.com.
Users can deploy an application from an already built docker image if it can run as no-root user. Images can be pulled from the local reposistory or they can be pulled from any public registry.
As a demo user, create a new application strarting from the docker image in the Docker Hub
oc new-app \
--name=nodejs \
--docker-image=docker.io/kalise/nodejs-web-app \
-e MESSAGE="Hello New Application"
--> Found Docker image from docker.io for "docker.io/kalise/nodejs-web-app"
--> Creating resources ...
imagestream.image.openshift.io "nodejs" created
deploymentconfig.apps.openshift.io "nodejs" created
service "nodejs" created
--> Success
The command above creates a bounch of objects:
- Image Stream
- Deployment Config
- Service
The Image Stream object tells OpenShift when the referenced image changes. In suche case, a new deployment of our application is created.
By inspecting the Image Stream above
oc get is nodejs -o yaml
Here parts of the yaml of the above Image Stream
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
labels:
app: nodejs
name: nodejs
namespace: demo
spec:
lookupPolicy:
local: false
tags:
- annotations:
openshift.io/imported-from: docker.io/kalise/nodejs-web-app
from:
kind: DockerImage
name: docker.io/kalise/nodejs-web-appThe Image Stream references Docker Image originated from public image repository docker.io/kalise/nodejs-web-app. This image has been pulled during the application creation process and stored in the local registry at https://registry.openshift.noverit.com. Any changes to the image in the local registry will trigger a new deployment of the application.
A Deployment Config just creates a new replica controller and lets it start up the pods, similarly to a kubernetes deployment.
See the Deployment Config above
oc get dc/nodejs -o yaml
The Deployment Config defines the following:
- The number of the desired pod replicas.
- The labels selector used to bind the pods.
- The strategy for the update.
- The triggers for creating a new deployment.
Here some relevant details about the triggering conditions for the deployment above
apiVersion: v1
kind: DeploymentConfig
...
spec:
triggers:
- type: ConfigChange
- type: ImageChange
imageChangeParams:
automatic: true
containerNames:
- nodejs
from:
kind: ImageStreamTag
name: nodejs:latest
namespace: project00
lastTriggeredImage: docker.io/kalise/nodejs-web-app
...A ConfigChange trigger causes a new deployment to be created any time the configuration changes. An ImageChange trigger causes a new deployment to be created each time a new version of the image is available.
The user defines customizable strategies to transition from the previous deployment to the new one. Each application has different requirements for availability during deployments. OpenShift provides strategies to support a variety of deployment scenarios. The Rolling strategy is the default strategy while the other option is the Recreate strategy.
Here the relevant details about the strategy for the deployment above
apiVersion: v1
kind: DeploymentConfig
...
spec:
...
strategy:
resources: {}
rollingParams:
intervalSeconds: 1
maxSurge: 25%
maxUnavailable: 25%
updatePeriodSeconds: 1
type: Rolling
...Users can manually force a new deployment to start
oc rollout latest dc/nodejs
deploymentconfig "nodejs" rolled out
To get basic information about all the available revisions of the application
oc rollout history dc/nodejs
deploymentconfigs "nodejs"
REVISION STATUS CAUSE
1 Complete image change
2 Complete image change
3 Complete image change
4 Complete config change
5 Running manual change
Above we see latest deployment still running. It is triggered by a manual change. Rollback the deployment
oc rollout undo dc/nodejs
deploymentconfig "nodejs" rolled back
Other changes can be triggered by config changes in the pod template, as for example, adding probes and/or resource constraints.
Also an image change in the ImageStream creates a new deployment. For example, make a change in the ImageStream by pushing a different image to the local registry:
docker pull kalise/nodejs-web-app:1.2
docker tag kalise/nodejs-web-app:1.0 registry.openshift.noverit.com/demo/nodejs:latest
docker login -u openshift -p $(oc whoami -t) registry.openshift.noverit.com
docker push registry.openshift.noverit.com/demo/nodejs:latest
Check if the new deployment has been created
oc get dc,rc
NAME REVISION DESIRED CURRENT TRIGGERED BY
deploymentconfig.apps.openshift.io/nodejs 2 1 1 config,image(nodejs:latest)
NAME DESIRED CURRENT READY AGE
replicationcontroller/nodejs-1 0 0 0 8m
replicationcontroller/nodejs-2 1 1 1 1m
As we can see, the DeploymentConfig updated with a new Replication Controller.
Users can create applications from source code stored in a local or remote Git repository. When users specify a source code repository, OpenShift attempts to build the code into a new application image and tries to automatically determine the type of build strategy to use.
There are, basically two build strategies: Docker or Source.
If a Dockerfile is present in the source code repository, OpenShift uses the Docker strategy invoking the docker build command to produce a runnable image.
oc new-app https://github.com/kalise/nodejs-web-app.git \
--name=nodejs-git \
-e MESSAGE="Hello New Application"
--> Found Docker image from Docker Hub for "node:latest"
--> Creating resources ...
imagestream.image.openshift.io "node" created
imagestream.image.openshift.io "nodejs-git" created
buildconfig.build.openshift.io "nodejs-git" created
deploymentconfig.apps.openshift.io "nodejs-git" created
service "nodejs-git" created
--> Success
The above command creates a Build Config, which produces a runnable image. The code is cloned locally from the remote git reposistory and then a runnable image nodejs-web-app:latest is created and pushed to the local registry.
Since the code repository already contains a Dockerfile, the build strategy is "Docker" by default. The base image node:latest is also created and pushed to the local OpenShift registry.
The command also creates two image streams to keep track of changes in the base node:latest image and in the runnable image.
The command also create a new Deployment Config to deploy the runnable image, and a Service to provide load-balanced access to the pods.
In general, a build is the process of transforming input source code into a runnable image. The Build Config object created by OpenShift is the definition of this build process. A Build Config describes a single build process and a set of triggers for when a new build should be created.
Inspect the Build Config object above
oc get bc/nodejs-web-app -o yaml
Here some key points.
The source section, defines the source code repository location
...
source:
git:
uri: https://github.com/kalise/nodejs-web-app.git
type: Git
...The strategy section describes the build strategy used to execute the build
...
strategy:
dockerStrategy:
from:
kind: ImageStreamTag
name: node:latest
type: Docker
...The output section, defined where the runnable image is pushed after it is successfully built
...
output:
to:
kind: ImageStreamTag
name: nodejs-web-app:latest
...The trigger section, defines the criteria which cause a new build to be created
...
triggers:
- type: GitHub
github:
secret: *******
- type: Generic
generic:
secret: *******
- type: ConfigChange
- type: ImageChange
imageChange:
lastTriggeredImageID: node
...Users can force a new build to happen even if no changes are in place
oc start-build bc/nodejs-web-app
build "nodejs-web-app-2" started
When the new build completes, a new image is created and pushed to the local registry. Also a new deployment is created to start the new application.
The source build strategy optimizes, secures and speeds the build of the new application by injecting the application source into a single runnable image. By building runnable images from source code, instead of using a regular Dockerfile, the users can avoid accidental or intentional abuses by running, for example, an application as a root user.
To create a new application, using the source build strategy
oc new-app https://github.com/kalise/nodejs-web-app.git \
--name=nodejs-git-source \
-e MESSAGE="Hello New Application" \
--strategy=source
--> Creating resources ...
imagestream.image.openshift.io "nodejs-git-source" created
buildconfig.build.openshift.io "nodejs-git-source" created
deploymentconfig.apps.openshift.io "nodejs-git-source" created
service "nodejs-git-source" created
--> Success
OpenShift makes it possible to deploy a set of resources through a single JSON or YAML manifest file. In addition, OpenShift takes this a step further by allowing that manifest to be parameterizable. This is called a Template. A template is a list of OpenShift objects whose definitions can include placeholders that get replaced with actual values when OpenShift instantiate the template.
OpenShift comes with a set of predefined templates. However, users can create their own custom templates. An example of custom template can be found in the nodejs-template.yaml file descriptor.
First, create the template
oc apply -f nodejs-template.yaml
Create a new application, from the template nodejs-web-app by specifying the parameters, where it is required
oc new-app nodejs-web-app \
-p NAME=web \
-p NODEJS_VERSION=8 \
-p MEMORY_LIMIT=512Mi \
-p SOURCE_REPOSITORY_URL=https://github.com/kalise/nodejs-web-app.git \
-p APPLICATION_DOMAIN_NAME=openshift.noverit.com
Deploying template "openshift/nodejs-web-app" to project project00
NoverIT Nodejs Web App
---------
An example of nodejs web application.
The following service(s) have been created in your project: web.
labels:
template: nodejs-web-app
app: nodejs-web-app
* With parameters:
* Name=web
* Namespace=openshift
* Version of NodeJS Image=10
* Memory Limit=512Mi
* Git Repository URL=https://github.com/kalise/nodejs-web-app.git
* Git Reference=
* Context Directory=
* Application Domain=openshift.noverit.com