Elastic Stack on Openshift
This section outlines how to setup and configure an Openshift project to get the Elastic Stack to a deployable state. This document assumes a working knowledge of Kubernetes/Openshift container orchestration concepts (i.e. buildconfigs, deployconfigs, imagestreams, secrets, configmaps, routes, etc)
Our builds and deployments can be orchestrated with Jenkins. However at this time, all manifests are to be manually invoked.
Environment Setup - ConfigMaps and Secrets
There are some requirements in the target Openshift namespace/project which are outside of the CI/CD pipeline process. This application requires that a few Secrets as well as Config Maps be already present in the environment before it is able to function as intended. Otherwise the deployments fail due to missing data.
In order to prepare an environment, you will need to ensure that all of the following configmaps and secrets are populated. This is achieved by executing the following commands as a project administrator of the targeted environment. Note that this must be repeated on each of the target deployment namespace/projects (i.e. dev
, test
and prod
) as that they are independent of each other. Deployment will fail otherwise.
Config Maps
At this time, all config maps are defined in the deploymentconfig manifest templates. As the Elastic Stack components are mainly configured through yaml files, the majority of the config maps will end up being mounted onto the containers at specific directory locations. Refer to the Official Elastic Stack documentation for more details on how to manage your Elastic Stack components.
Secrets
Elastic Stack secrets involves the use of a combination of TLS Certificates and user/password secrets. In order to generate Elastic Stack compatible certificates, they must be generated by an elasticsearch instance. To achieve this, we temporarily spin up an elasticsearch container on OCP in order to generate and extract the certificates. This is then pushed up as secrets.
Certificate Generation
Ensure your OpenShift CLI tool is logged in. Make sure you change your namespace to the correct project with oc project <projectname>
.
Start Temporary Elasticsearch Pod
export ELK_VERSION=7.5.1
export NAMESPACE=ixhmbm-dev
oc run -n $NAMESPACE cert --image=elastic/elasticsearch:$ELK_VERSION --command -it --rm --restart=Never -- bash
Generate Certificates
Open a new terminal and ensure your OpenShift CLI tool is logged in. Make sure you change your namespace to the correct project with oc project <projectname>
. You will create certs for desired elasticsearch host ${APP_NAME}-${INSTANCE}
.
export APP_NAME=elasticsearch
export INSTANCE=master
export NAMESPACE=ixhmbm-dev
oc rsh -n $NAMESPACE cert elasticsearch-certutil ca --out /tmp/$APP_NAME-ca.p12 --pass ''
oc rsh -n $NAMESPACE cert elasticsearch-certutil cert --name $APP_NAME --dns $APP_NAME-$INSTANCE --ca /tmp/$APP_NAME-ca.p12 --pass '' --ca-pass '' --out /tmp/$APP_NAME-certificates.p12
oc cp -n $NAMESPACE cert:/tmp/$APP_NAME-ca.p12 ./
oc cp -n $NAMESPACE cert:/tmp/$APP_NAME-certificates.p12 ./
openssl pkcs12 -nodes -passin pass:'' -in $APP_NAME-certificates.p12 -out $APP_NAME-certificate.pem
openssl pkcs12 -clcerts -nokeys -passin pass:'' -in $APP_NAME-ca.p12 -out $APP_NAME-ca.pem
Create Secrets
Once the four certificate files are created, we can add them to OpenShift secrets.
oc create -n $NAMESPACE secret generic $APP_NAME-$INSTANCE-certificates --from-file=$APP_NAME-certificates.p12
oc create -n $NAMESPACE secret generic $APP_NAME-$INSTANCE-certificate-pem --from-file=$APP_NAME-certificate.pem
oc create -n $NAMESPACE secret generic $APP_NAME-$INSTANCE-ca-pem --from-file=$APP_NAME-ca.pem
oc process -n $NAMESPACE -f elasticstack.secret.yaml -p INSTANCE=$INSTANCE | oc create -f -
Stop & Remove Temporary Elasticsearch Pod
Once the secrets are up, you need to dispose of your cert pod. This can be done by exiting out of the remote terminal shell, or by force deleting the specific cert pod.
oc delete -n $NAMESPACE pod/cert --force
Build Config & Deployment
The Elastic stack is made up of ElasticSearch, Kibana and Logstash. We are currently leveraging basic Openshift Routes to expose and foward incoming traffic to the right services. Most of the images we are using are the official published images from Elastic.co. However, as we apply certain plugin plugins to support specific functionality, some components will have custom build configurations which extend on top of those images.
Templates
We leverage Openshift Templates in order to ensure all environment variables, settings and contexts are pushed to Openshift correctly. Files ending with .bc.yaml
specify the build configurations, while files ending with .dc.yaml
specify the components required for deployment.
Build Configurations
Build configurations will emit and handle the chained builds or standard builds as necessary. Note that most parameters will have reasonable defaults specified if you do not explicitly configure them. Refer to the template parameter definitions for more details. They take in the following parameters:
Name | Required | Description |
---|---|---|
APP_NAME | yes | Application name |
ELASTIC_VERSION | yes | Application version of Elastic Stack in string format |
INSTANCE | yes | The deployment instance name |
CPU_LIMIT | yes | Limit Peak CPU per pod (in millicores ex. 1000m) |
CPU_REQUEST | yes | Requested CPU per pod (in millicores ex. 500m) |
MEMORY_LIMIT | yes | Limit Peak Memory per pod (in gigabytes Gi or megabytes Mi ex. 2Gi) |
MEMORY_REQUEST | yes | Requested Memory per pod (in gigabytes Gi or megabytes Mi ex. 500Mi) |
The template can be manually invoked and deployed via Openshift CLI. For example:
export INSTANCE=master
export NAMESPACE=ixhmbm-dev
oc process -n $NAMESPACE -f logstash.bc.yaml -p INSTANCE=$INSTANCE -o yaml | oc -n $NAMESPACE apply -f -
Note that these build configurations do not have any triggers defined. They will be invoked by the Jenkins pipeline, started manually in the console, or by an equivalent oc command for example:
oc start-build -n $NAMESPACE <buildname> --follow
The build config should write the resultant image to <imagename>:$INSTANCE
, where the image name is ${APP_NAME}-custom, and the tag is the specified INSTANCE. Depending on your build tooling, you may need to do the equivalent oc command for tag management:
oc tag -n $NAMESPACE <imagename>:$INSTANCE <imagename>:latest
Note: Remember to swap out the bracketed values with the appropriate values!
Deployment Configurations
Deployment configurations will emit and handle the deployment lifecycles of running containers based off of the previously built images. They generally contain a deploymentconfig, a service, and a route, but may also contain configmaps and statefulsets depending on the application. Most templates will take in the following parameters (consult the templates directly for exact details):
Name | Required | Description |
---|---|---|
APP_NAME | yes | Application name |
ELASTIC_VERSION | yes | Application version of Elastic Stack in string format |
INSTANCE | yes | The deployment instance name |
LABEL_ENV | yes | Deployment environment |
NAMESPACE | yes | Target namespace reference (i.e. ‘ixhmbm-dev’) |
CPU_LIMIT | yes | Limit Peak CPU per pod (in millicores ex. 1000m) |
CPU_REQUEST | yes | Requested CPU per pod (in millicores ex. 500m) |
MEMORY_LIMIT | yes | Limit Peak Memory per pod (in gigabytes Gi or megabytes Mi ex. 2Gi) |
MEMORY_REQUEST | yes | Requested Memory per pod (in gigabytes Gi or megabytes Mi ex. 500Mi) |
PVC_SIZE | yes | The size of the persistent volume to create |
STORAGE_CLASS | yes | The type of the persistent volume to create |
A Jenkins pipeline will be handle deployment invocation automatically. However should you need to run it manually, you can do so with the following for example:
export INSTANCE=master
export NAMESPACE=ixhmbm-dev
oc process -n $NAMESPACE -f elasticsearch.dc.yaml -p INSTANCE=$INSTANCE -o yaml | oc -n $NAMESPACE apply -f -
oc process -n $NAMESPACE -f kibana.dc.yaml -p INSTANCE=$INSTANCE -p NAMESPACE=$NAMESPACE -o yaml | oc -n $NAMESPACE apply -f -
oc process -n $NAMESPACE -f logstash.dc.yaml -p INSTANCE=$INSTANCE -p NAMESPACE=$NAMESPACE -o yaml | oc -n $NAMESPACE apply -f -
Due to the triggers that are set in the deploymentconfig, the deployment will begin automatically. However, you can deploy manually by use the following command for example:
oc rollout -n $NAMESPACE latest dc/<buildname>-$INSTANCE
Note: Remember to swap out the bracketed values with the appropriate values!
Instance Cleanup
In order to clear all resources for a specific instance, run the following three commands to delete all relevant resources from the Openshift project:
export INSTANCE=master
export NAMESPACE=ixhmbm-dev
oc delete all,cm,pvc -n $NAMESPACE --selector app=elasticsearch-$INSTANCE
oc delete all,cm -n $NAMESPACE --selector app=kibana-$INSTANCE
oc delete all,cm -n $NAMESPACE --selector app=logstash-$INSTANCE
If necessary, you can remove old secrets through the Openshift Web Console or its equivalent OC CLI command.
export APP_NAME=elasticsearch
export INSTANCE=master
export NAMESPACE=ixhmbm-dev
oc delete -n $NAMESPACE secret $APP_NAME-$INSTANCE-certificates
oc delete -n $NAMESPACE secret $APP_NAME-$INSTANCE-certificate-pem
oc delete -n $NAMESPACE secret $APP_NAME-$INSTANCE-ca-pem
oc delete -n $NAMESPACE secret $APP_NAME-$INSTANCE-credentials