My journey through Openshift
Tags: container, orchestration, openshift, kubernetes
Published: 2018-07-19 02:20:41

---
title: My journey through Openshift
published: true
description: My impressions on the Openshift platform
tags: container, orchestration, openshift, kubernetes
---

Recently I started working with [Openshift](https://www.openshift.org/) since the company I work for adopted it. It will be quite an interesting journey because I will have to adapt our services that currently run on JBoss and Tomcat to run on containers.

But first, what exactly is Openshift?

From my understanding, it is a distribution of [Kubernetes](https://kubernetes.io/) focused on providing an easier way to migrate, deploy and manage your applications on a containerized environment. It hides some of the complexities of Kubernetes while providing some nice features like its dashboard and the source-to-image (S2I) strategy.

Openshift is maintained by RedHat.

The S2I is very interesting: it combines a specially built docker image with your application's source code and build another docker image ready to be deployed. Each S2I image is specialized in building and deploying a different technology stack. For example, the JBoss S2I image will look for a `pom.xml` in the sources, run `mvn package`, copy the generated artifact to the deployments directory and, when run, will configure the datasource using environment variables. The Tomcat S2I image works similarly. RedHat provides images for Java, Python, Ruby, Nodejs and others.

You can also deploy an image from docker hub.

## Getting started

To get started with Openshift, you can download the [minishift](https://github.com/minishift/minishift/releases) tool, which will start a virtual machine running an instance of Openshift.

But before we begin, we should tweak the virtual machine a little bit:

```sh
minishift config set vm-driver virtualbox
minishift config set memory 8G
minishift config set cpus 4
minishift config set disk-size 100G
```

These commands will tell minishift to:

- use virtualbox instead of KVM/Hyper-V/xhyve (you can still use those)
- set the memory to 8GB (but 4GB will do too)
- set the number of cpus to 4, so we can run a few more containers
- use a disk size of 100GB, so we do not run out of storage

You can use lower values for memory and cpus, but it will be very limited (and sometimes openshift may freeze).

To start minishift we can run:

```sh
minishift start
```

When the machine is ready, we can run:

```sh
eval $(minishift oc-env)
```

to have `oc` (the openshift command line tool) in our path.

Before we can interact with Openshift, we need to login (use admin/admin as credencials):

```sh
oc login
```

With everything running, it is time to deploy an application. For this example we will deploy [Gitea](https://gitea.io), a git repository manager forked from [Gogs](https://gogs.io/).

But first, we need to create a project (which is effectively a kubernetes namespace):

```sh
oc new-project scm --display-name "Source Control Management"
```

Now we tell openshift to create an "app" from Gitea docker image:

```sh
oc new-app gitea/gitea:1.5
```

which will end up creating:

- an [Image Stream](https://docs.openshift.org/latest/dev_guide/managing_images.html)
- a [DeploymentConfig](https://docs.openshift.org/latest/dev_guide/deployments/kubernetes_deployments.html), similar to (and will eventually be replaced by) a kubernetes Deployment
- a Service

To expose the service to the external world, we can create a [Route](https://docs.openshift.org/latest/architecture/networking/routes.html)

```sh
oc expose svc/gitea \
    --name gitea-http \
    --port 3000-tcp
```

The `3000-tcp` is the name of the port on the service.

With the Route created, Gitea will now be available at http://gitea-scm.192.168.99.100.nip.io

You can also expose Gitea's ssh endpoint

```sh
oc expose svc/gitea \
    --name gitea-ssh \
    --port 22-tcp \
    --hostname gitea-scm-ssh.192.168.99.100.nip.io
```

Gitea is working, but its data will be lost on container restart, so we need a persistent volume to hold that data:

```sh
# remove automatically create volume
oc volume dc/gitea --remove --name gitea-volume-1

oc volume dc/gitea --add \
    --name 'gitea-volume-data' \
    --type 'pvc' \
    --mount-path '/data/' \
    --claim-name 'gitea-data' \
    --claim-size '1G'
```

One thing that is missing is configuration. Fortunately, Gitea can be configured [using environment variables](https://docs.gitea.io/en-us/install-with-docker/). So now we will create a ConfigMap to hold the environment:

```sh
oc create configmap gitea-config \
    --from-literal APP_NAME="My Gitea Instance" \
    --from-literal RUN_MODE=prod \
    --from-literal SSH_DOMAIN=gitea-scm-ssh.192.168.99.100.nip.io \
    --from-literal ROOT_URL=http://gitea-scm.192.168.99.100.nip.io \
    --from-literal DB_TYPE=sqlite3 \
    --from-literal INSTALL_LOCK=true
```

Now add the environment to the DeploymentConfig:

```sh
oc set env --from configmap/gitea-config dc/gitea
```

If you access our Gitea instance right now, you will notice that our configuration was not applied! This happened because Gitea already have a configuration file in the volume we created. To solve this, we need to add another volume, an EmptyDir volume, so Gitea can rebuild the configuration using the environment variables we set:

```sh
oc volume dc/gitea --add \
    --name 'gitea-volume-config' \
    --type 'emptyDir' \
    --mount-path '/data/gitea/conf'
```

It may take a bit longer for the application to be ready since it is creating the database tables, but then you will see that our settings were applied.

Now we just need to setup [probes to monitor application health](https://docs.openshift.org/latest/dev_guide/application_health.html):

```sh
oc set probe dc/gitea --liveness \
    --failure-threshold 3 \
    --initial-delay-seconds 5 \
    -- echo ok

oc set probe dc/gitea --readiness \
    --failure-threshold 3 \
    --initial-delay-seconds 10 \
    --get-url=http://:3000/user/login
```

The readiness probe is particularly useful during rollouts so openshift can tell if it can safely remove the old container and redirect requests to the new one.

Update:

I made a [Template](https://docs.openshift.org/3.9/dev_guide/templates.html) to make easier to deploy Gitea. [It is available here](https://github.com/livioribeiro/devops-stuff/blob/master/openshift/gitea-persistent-template.yaml).

Gitea has more settings than the ones configurable through the environment variables, but right now setting the config file (app.ini) from a configmap does not work very well since Gitea tries to write to the file and fails because it is readonly. However, [there is a pull request to fix that](https://github.com/go-gitea/gitea/pull/4412).