OpenShift = Docker + Kubernetes. OpenShift is an orchestration platform PaaS provided by Red Hat. It is infrastructure-agnostic; you could run it on top of EC2, for example: imagine deploying Docker containers to EC2 instances.
What do we need to run Magnolia? Tomcat, MySQL, Magnolia WAR file. What if I want to add or remove a public instance to a Magnolia install, say in a High Availability scenario? I will need some orchestration machine - this is where OpenShift comes in.
OpenShift uses ActiveMQ to communicate between the orchestration machine ('Broker') and the Nodes.
Cartridge
A Cartridge is an OpenShift extension. Think library include. We might build a Cartridge to a DB platform like MySQL. We install Cartridges into Gears to provide functionality to our apps.
Gear
A Gear is a Container. We organize N > 1 Gears into a Pod.
Pod
A Pod is the atomic unit for OpenShift. It is the smallest manageable unit. Pods live on Virtual Machines. Virtual Machines are also known as 'Nodes'.
Cluster
A Cluster is a collection of Virtual Machines.
Links
- There's a basic Ansible Role for installing OpenShift here.
- The OpenShift docu are either weak or outdated in most cases, and the authors of OpenShift tend to answer online questions with "You're using the product wrong", rather than be helpful, so, good documentation is hard to find. Here's a couple useful links - surprise, surprise - not from the OpenShift docu:
- https://docs.ansible.com/ansible-container/openshift/containers.html
- http://www.javamonamour.org/2017/12/oc-cluster-up-how-to-enable-admin.html
Other
First working cluster was built like so:
Expand |
---|
Code Block |
---|
| #!/bin/bash
# ===========================================================
# [1] get prerequisites, openshift client, and set hostname #
# ===========================================================
# need wget and docker
sudo yum -y install wget docker git
# get the latest open shift client from https://github.com/openshift/origin/releases
wget https://github.com/openshift/origin/releases/download/v3.9.0/openshift-origin-client-tools-v3.9.0-191fece-linux-64bit.tar.gz
# extract the latest open shift client you just downloaded
tar zxf openshift-origin-client-tools-v3.9.0-191fece-linux-64bit.tar.gz
# move the oc executable somewhere so it's on most PATHS
sudo mv openshift-origin-client-tools-v3.9.0-191fece-linux-64bit/oc /usr/local/bin/
# add your ip address to /etc/hosts
sudo -- sh -c "echo 139.162.131.60 localhost.openshift >> /etc/hosts"
# ==========================================
# [2] configure docker and start openshift #
# ==========================================
# unless you have a cert, tell docker to use insecure resgistries
sudo -- sh -c "echo "{\"insecure-registries\"" : ["\"139.162.131.60:5000\"", "\"172.30.0.0/16\""]} > /etc/docker/daemon.json"
# the file should look like this: {"insecure-registries" : ["139.162.131.60:5000", "172.30.0.0/16"]}
# now need to make docker mounts 'shared' ... guidance is here: https://docs.portworx.com/knowledgebase/shared-mount-propogation.html#redhatcentos-configuration-and-shared-mounts ... TL;DR: remove the line starting with 'MountFlags' from /lib/systemd/system/docker.service ... OS-level --make-shared does NOT work!
sed -i '/^MountFlags/d' /lib/systemd/system/docker.service
# reload docker
sudo service docker reload
# create the openshift cluster ... seems must be run as 'root', not even sudo works because it doesn't find oc on PATH
oc cluster up --public-hostname 139.162.131.60
# now you should be able to visit 139.162.131.60:8443 and log in using (by default) *any* credentials you choose ... whatever you enter, it'll create that acct for you
#### SCREEN SHOT HERE #### |
|
Screenshots
Image AddedImage Added
Now that everything is set up and you can log in to the web console, let's do some configuration:
Code Block |
---|
oc login 139.162.131.60:8443 --username=system --password=admin --insecure-skip-tls-verify |
You should see something like:
Code Block |
---|
[bandersen@li1397-60 ~]$ oc login 139.162.131.60:8443 --username=system --password=admin --insecure-skip-tls-verify
Login successful.
You don't have any projects. You can try to create a new project, by running
oc new-project <projectname>
Welcome! See 'oc help' to get started.
[bandersen@li1397-60 ~]$ |
Note |
---|
An OpenShift 'project' is like a Kubernetes 'namespace', but with extra herbs and spices thrown in. |
Note |
---|
Most tutorials will tell you to do it this way, but I have never gotten it to work: Code Block |
---|
oc login -u system:admin |
Usually, you'll get an error like so: Code Block |
---|
[bandersen@li1397-60 ~]$ oc login -u system:admin
Server [https://localhost:8443]:
The server uses a certificate signed by an unknown authority.
You can bypass the certificate check, but any data you send to the server could be intercepted by others.
Use insecure connections? (y/n): y
Authentication required for https://localhost:8443 (openshift)
Username: system:admin
Password:
error: username system:admin is invalid for basic auth
[bandersen@li1397-60 ~]$ |
|
The best way is actually to follow the advice here.
Creating an App
There are many ways to create an OpenShift application, including:
- from source code
oc new-app /path/to/someUser/someProject
- oc
new-app https://github.com/someUser/someProject
- from docker images
- oc
new-app someImageOnDockerHub
- oc
new-app localhost:5000/someImage
- from templates
- oc
new-app someOpenShiftTemplate
- oc
new-app -f /path/to/someTemplate.json
- using the web console
Deploying an App
When we deploy an app, we deploy three things:
- configuration
- this describes the desired state of your application
- replication controller(s)
- this is basically a snapshot of some state of your application (the system will create this for you)
- pod(s)
- this is basically an instance of the app you created
If you create an app, as per above, you can inspect the configuration file for your app thusly:
Expand |
---|
Code Block |
---|
[bandersen@li1397-60 docker]$ oc get route magnoliax -o yaml
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
openshift.io/host.generated: "true"
creationTimestamp: 2018-04-19T07:05:27Z
labels:
app: magnoliax
name: magnoliax
namespace: default
resourceVersion: "100481"
selfLink: /apis/route.openshift.io/v1/namespaces/default/routes/magnoliax
uid: 09f3ab6f-43a0-11e8-ba2b-6ee30226f73c
spec:
host: magnoliax-default.139.162.131.60.nip.io
port:
targetPort: 8080-tcp
to:
kind: Service
name: magnoliax
weight: 100
wildcardPolicy: None
status:
ingress:
- conditions:
- lastTransitionTime: 2018-04-19T07:05:27Z
status: "True"
type: Admitted
host: magnoliax-default.139.162.131.60.nip.io
routerName: router
wildcardPolicy: None
[bandersen@li1397-60 docker]$ |
|
Running Magnolia on OpenShift
Two ways: as a standalone WAR file, or using Docker.
as a standalone WAR
Code Block |
---|
wget https://files.magnolia-cms.com/5.6/magnolia-enterprise-pro-demo-webapp-5.6.war -O magnoliaauthor.war |
Note |
---|
The name is important here. The name we use in the next command has to follow these rules: Must be an a lower case alphanumeric (a-z, and 0-9) string with a maximum length of 58 characters, where the first character is a letter (a-z), and the '-' character is allowed anywhere except the first or last character. |
Code Block |
---|
oc new-app wildfly:latest~. --name magnoliaauthor |
You should get some output like:
Code Block |
---|
[bandersen@li1397-60 ~]$ oc new-app wildfly:latest~. --name magnoliaauthor
--> Found image fdd5894 (4 weeks old) in image stream "openshift/wildfly" under tag "latest" for "wildfly:latest"
WildFly 10.1.0.Final
--------------------
Platform for building and running JEE applications on WildFly 10.1.0.Final
Tags: builder, wildfly, wildfly10
* A source build using binary input will be created
* The resulting image will be pushed to image stream "magnoliaauthor:latest"
* A binary build was created, use 'start-build --from-dir' to trigger a new build
* This image will be deployed in deployment config "magnoliaauthor"
* Port 8080/tcp will be load balanced by service "magnoliaauthor"
* Other containers can access this service through the hostname "magnoliaauthor"
--> Creating resources ...
imagestream "magnoliaauthor" created
buildconfig "magnoliaauthor" created
deploymentconfig "magnoliaauthor" created
service "magnoliaauthor" created
--> Success
Build scheduled, use 'oc logs -f bc/magnoliaauthor' to track its progress.
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose svc/magnoliaauthor'
Run 'oc status' to view your app.
[bandersen@li1397-60 ~]$ |
Now we build it and then we can go see it:
Code Block |
---|
[bandersen@li1397-60 ~]$ oc start-build magnoliaauthor --from-file=magnoliaauthor.war
Uploading file "magnoliaauthor.war" as binary input for the build ...
build "magnoliaauthor-2" started
[bandersen@li1397-60 ~]$ oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
magnoliaauthor magnoliaauthor-default.139.162.131.60.nip.io magnoliaauthor 8080-tcp None |
So if we go to http://magnoliaauthor-default.139.162.131.60.nip.io/magnoliaauthor, we should see Magnolia 5.6 running on WildFly.
using Docker
You could use something from Docker Hub, or from a local Docker image, like so:
Expand |
---|
Code Block |
---|
[root@localhost ~]# oc new-app magnolia-1 --name magnoliax
W0419 07:05:16.233491 28843 newapp.go:480] Could not find an image stream match for "magnolia-1:latest". Make sure that a Docker image with that tag is available on the node for the deployment to succeed.
--> Found Docker image bdd1731 (18 hours old) from for "magnolia-1:latest"
* This image will be deployed in deployment config "magnoliax"
* Port 8080/tcp will be load balanced by service "magnoliax"
* Other containers can access this service through the hostname "magnoliax"
* WARNING: Image "magnolia-1:latest" runs as the 'root' user which may not be permitted by your cluster administrator
--> Creating resources ...
deploymentconfig "magnoliax" created
service "magnoliax" created
--> Success
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose svc/magnoliax'
Run 'oc status' to view your app.
[root@localhost ~]# oc expose svc/magnoliax
route "magnoliax" exposed
[root@localhost ~]# oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
magnoliaauthor magnoliaauthor-default.139.162.131.60.nip.io magnoliaauthor 8080-tcp None
magnoliax magnoliax-default.139.162.131.60.nip. |
|
...
io magnoliax 8080-tcp None
[root@localhost ~]# |
|
Troubleshooting
If for some reason your app is not running, you can check the logs, by pod name:
Expand |
---|
Code Block |
---|
[bandersen@li1397-60 docker]$ oc get pod --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE
default docker-registry-1-p9fc8 1/1 Running 0 20h 172.17.0.5 localhost
default magnoliaauthor-1-build 0/1 Completed 0 19h 172.17.0.2 localhost
default magnoliaauthor-2-build 0/1 Completed 0 19h 172.17.0.2 localhost
default magnoliaauthor-2-djlpt 1/1 Running 0 19h 172.17.0.2 localhost
default magnoliax-1-deploy 0/1 Error 0 35m 172.17.0.3 localhost
default persistent-volume-setup-68t4w 0/1 Completed 0 20h 172.17.0.3 localhost
default router-1-hpvfq 1/1 Running 0 20h 139.162.131.60 localhost
openshift-web-console webconsole-7dfbffd44d-mfzt8 1/1 Running 0 20h 172.17.0.4 localhost
[bandersen@li1397-60 docker]$ oc logs magnoliax-1-deploy
--> Scaling magnoliax-1 to 1
error: update acceptor rejected magnoliax-1: pods for rc 'default/magnoliax-1' took longer than 600 seconds to become available
[bandersen@li1397-60 docker]$ |
|
https://developers.redhat.com/blog/2017/08/16/troubleshooting-java-applications-on-openshift/
Expand |
---|
Code Block |
---|
[bandersen@li1397-60 docker]$ oc get route magnoliax -o yaml
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
openshift.io/host.generated: "true"
creationTimestamp: 2018-04-19T07:05:27Z
labels:
app: magnoliax
name: magnoliax
namespace: default
resourceVersion: "100481"
selfLink: /apis/route.openshift.io/v1/namespaces/default/routes/magnoliax
uid: 09f3ab6f-43a0-11e8-ba2b-6ee30226f73c
spec:
host: magnoliax-default.139.162.131.60.nip.io
port:
targetPort: 8080-tcp
to:
kind: Service
name: magnoliax
weight: 100
wildcardPolicy: None
status:
ingress:
- conditions:
- lastTransitionTime: 2018-04-19T07:05:27Z
status: "True"
type: Admitted
host: magnoliax-default.139.162.131.60.nip.io
routerName: router
wildcardPolicy: None
[bandersen@li1397-60 docker]$ |
or Code Block |
---|
[bandersen@li1397-60 docker]$ oc describe dc magnoliax
Name: magnoliax
Namespace: default
Created: 7 hours ago
Labels: app=magnoliax
Annotations: openshift.io/generated-by=OpenShiftNewApp
Latest Version: 1
Selector: app=magnoliax,deploymentconfig=magnoliax
Replicas: 1
Triggers: Config
Strategy: Rolling
Template:
Pod Template:
Labels: app=magnoliax
deploymentconfig=magnoliax
Annotations: openshift.io/generated-by=OpenShiftNewApp
Containers:
magnoliax:
Image: magnolia-1:latest
Port: 8080/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Deployment #1 (latest):
Name: magnoliax-1
Created: 7 hours ago
Status: Failed
Replicas: 0 current / 0 desired
Selector: app=magnoliax,deployment=magnoliax-1,deploymentconfig=magnoliax
Labels: app=magnoliax,openshift.io/deployment-config.name=magnoliax
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
Events: <none>
[bandersen@li1397-60 docker]$ |
|