Recently I started working with Openshift 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 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.
To get started with Openshift, you can download the minishift 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:
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:
When the machine is ready, we can run:
eval $(minishift oc-env)
oc (the openshift command line tool) in our path.
Before we can interact with Openshift, we need to login (use admin/admin as credencials):
But first, we need to create a project (which is effectively a kubernetes namespace):
oc new-project scm --display-name "Source Control Management"
Now we tell openshift to create an "app" from Gitea docker image:
oc new-app gitea/gitea:1.5
which will end up creating:
- an Image Stream
- a DeploymentConfig, 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
oc expose svc/gitea \ --name gitea-http \ --port 3000-tcp
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
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:
# 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. So now we will create a ConfigMap to hold the environment:
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:
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:
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:
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.
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.