Aloha, I propose you a general presentation of Openshift with a Symfony 4 application as a use case.
First, we start with presentations
I'm an open source container application platform based on Kubernetes container orchestrator for enterprise application development and deployment ¹
What can I say in a few words about Openshift
- It's a PaaS : Plateform-as-a-service
- Three offers availables : Online (used in this Post), Online Dedicated and private (not hosted at RedHat)
- It allows build, deploy and run applications in containers
- His configuration is based on a Docker container engine with Kubernetes Orchestrator
- It offers a microservices oriented architecture.
Among the services of Openshift platform
- Containerization (Source to images ², Docker Repository, Image Stream)
- Route & LoaderBalancer
- Shared Storage
- Resource Management (Quota, Membership, ConfigMap, Secret,...)
- Monitoring (Elasticsearch, Fluentd, Kibana) & Readiness / Liveness
Real life
This is a simple example of a web application deployed in Openshift cluster.
The client (which may be a web browser) requests an URL (an external route to the cluster) of the Web application, the platform Router will dispatch this request to the concerned service (this may be an opening of port 80 of the frontal Pod).
The frontal Pod can then be considered as the FontEnd controller of our application, and which will use the business application also deployed in a Pod in Backend and in communication with the Pod of database (on a TCP service on 3306 for example with MySQL database).
Finally, all Pods use the distributed storage system managed by the platform on virtual file system mounts.
Typically, when you have multiple clusters, you define a front cluster (perhaps behind a proxy) to expose your services to outside of the cluster and another back cluster that will embed a business applications as well as access to the data. Both of these clusters will have different security configurations and requirements, which will allow us to isolate and protect business data.
Use case with a Symfony application
It's a standard Symfony 4 demonstration application with a few modifications to add Memcached support for example and using of MySQL database instead of SQLLite. Source is available here (branch "openshift").
Let's start !
To begin, we need an OpenShift instance, so there simple registration to demo program (Starter Pack), gives us right to 2GB of memory, 2GB of disk and 4 CPU core free for 60 days.
After login to Web console, we have a view of catalog of images and services supported by the platform:
So we start by creating a project (we're entitled to one at a time). For Openshift, this project is a namespace with own rules of resource management, access and some isolation with other namespaces.
For our Post, we will need an instance of Apache with PHP 7, Opcache and Memcached installed. The PHP image proposed by the platform does not support Memcached, for this reason that we will use a dedicated image available on DockerHub (Tag "openshift" and source available on GitHub).
However, if we want to use the proposed image, we go through the catalog and we will have this
And if we want to use our image, we go through "Add to Project" then "Import YAML / JSON "
We can copy / paste this content
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
labels:
app: webapp
name: webapp
spec:
output:
to:
kind: ImageStreamTag
name: 'webapp:latest'
source:
git:
ref: openshift
uri: 'https://github.com/mmohamed/demo.git'
type: Git
strategy:
sourceStrategy:
from:
kind: DockerImage
name: 'medinvention/s2i-ubuntu-php72-apache24:openshift'
type: Source
Then we have to define an external route for application
We can also go through " Add to Project " then " Deploy image " (Without Git sources) we will have
/!\ Tip: You can use the default PHP image to initiate S2I DeploymentConfig with our GitHub Repository, then modify the configuration to use our specific image without having to define a complete BuildConfig.
So, now we have a functional Build and DeploymentConfig, our first Build and our first Deploy are completed successfully. We have a Pod in Run and Ready to process queries.
It then remains the deployment of a database image (we will use MySQL from catalog), and a MemCached server image. For Memcached, we will use a YAML Template , because it does not exist in catalog, with the import of object definitions in YAML / JSON functionality to import this template and apply it.
Now, we must have a complete environment
We can access to our application with generated public URL
One last tool is missing for continuous deployment; there we can use Jenkins which is proposed by platform in catalog.
We just have to update our Jenkins Job to trigger a build, followed by a deployment when it detects a change in our application sources (hosted at GitHub)
We can see Logs of Job run
Started by an SCM change
No credentials specified
> git rev-parse --is-inside-work-tree # timeout=10
....
> git rev-list --no-walk b9feb776306e16bcba20a6d371e9e83a838d1a2b # timeout=10
Starting "Scale OpenShift Deployment" with deployment config "memcached" from the project "demo-medinvention".
Scaling to "0" replicas and verifying the replica count is reached ...
Operation will timeout after 180000 milliseconds
Exiting "Scale OpenShift Deployment" successfully, where the deployment "memcached-2" reached "0" replica(s).
Starting the "Trigger OpenShift Build" step with build config "webapp" from the project "demo-medinvention".
Started build "webapp-9" and waiting for build completion ...
Operation will timeout after 900000 milliseconds
Pulling image "medinvention/s2i-ubuntu-php72-apache24:openshift" ...
Using medinvention/s2i-ubuntu-php72-apache24:openshift as the s2i builder image
---> Installing application source...
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
....
Generating optimized autoload files
ocramius/package-versions: Generating version class...
ocramius/package-versions: ...done generating version class
Executing script cache:clear [OK]
Executing script assets:install --symlink --relative public [OK]
Executing script security-checker security:check [OK]
---> Clear cache/logs and fixing permissions...
Pushing image docker-registry.default.svc:5000/demo-medinvention/webapp:latest ...
Pushed 0/17 layers, 0% complete
....
Pushed 17/17 layers, 100% complete
Push successful
Exiting "Trigger OpenShift Build" successfully; build "webapp-9" has completed with status: [Complete].
Starting "Trigger OpenShift Deployment" with deployment config "webapp" from the project "demo-medinvention".
Operation will timeout after 600000 milliseconds
Exiting "Trigger OpenShift Deployment" successfully; deployment "webapp-13" has completed with status: [Complete].
Starting "Tag OpenShift Image" with the source [image stream:tag] "webapp:latest" from the project "demo-medinvention" and destination stream(s) "webapp" with tag(s) "prod" from the project "demo-medinvention".
Exiting "Tag OpenShift Image" successfully.
Starting "Verify OpenShift Deployment" with deployment config "webapp" from the project "demo-medinvention".
Waiting on the latest deployment for "webapp" to complete ...
Operation will timeout after 180000 milliseconds
Exiting "Verify OpenShift Deployment" successfully; deployment "webapp-13" has completed with status: [Complete].
Starting "Scale OpenShift Deployment" with deployment config "memcached" from the project "demo-medinvention".
Scaling to "1" replicas and verifying the replica count is reached ...
Operation will timeout after 180000 milliseconds
Exiting "Scale OpenShift Deployment" successfully, where the deployment "memcached-2" reached "1" replica(s).
Finished: SUCCESS
Finally,
Now, we have a complete environment with full integration and deployment.
We can pick out two Pipelines :
- First is for our Base Docker image (S2I) ; as I have set up an Auto-Build in DockerHub (1) , it's constantly monitors the repository of the image in GitHub and as soon as there is a change, a Build is launched in DockerHub and result image is pushed to Registry. In this way, with each new Build of our project in Openshit, the new image will be used (2) .
- The second Pipeline is for our application; it's our Jenkins Job who will be the orchestrator, because as soon as he detects a change in the repository of the sources of our demo application (5) , he will launch a new Build starting with a " Scale down " of the Memcache DeployConfig (because there is a lack of CPU in project resources), followed by a " Build webapp ", then a deployment " Deploy webapp ". Then we Tag the resulting image of the Build (in the Openshift Registry) before checking the deployment. Finally, we finish our Job with a " Scale Up " Memcache DeployConfig .
The functioning of our environment remains simple; when an HTTP request from the client(3) come, it will be dispatched by the Router to webapp service and therefore to application pod on port 8080 (4) . The application will need to communicate with the Memcache server(6) and will have to go through the services, as well as to communicate with Pod of database(7).
Here is an environment that can be used perfectly to develop and experience Openshift freely.
Personally, I fell in love with this solution and this wonderful compilation of tools. I hope you start to love Openshift.
NOTA : This post is the result of my experience with Openshift and my own understanding. If you notice omissions or errors do not hesitate to report it to me with a nice comment.
¹ : RedHat definition - ² :I will do another Post for S2I