Openshift

How to autoscale your applications with Openshift

This tutorial will demonstrate how to use the Autoscaling feature to let Openshift automatically scale the number of Pods based on the amount of resources required by the Pod, up to a certain limit.

Out of the box when you create a new application with Openshift, a Pod will be automatically deployed with that application and the Replication Controller ensures that the configured number of Pods will remain available. However the number of Pods, out of the box, is a static value which can be changed manually with:

oc scale [object_type] --replicas=[number of replicas]

One key aspect of Openshift Paas is the ability to provide an automatic mechanism to scale Pods. Some steps are however necessary:

At first you need to enable metrics

Start Openshift using the --metrics option as described in detail in this tutorial: Configuring metrics on Openshift

$ oc cluster up --metrics

Create an application

In order to test autoscaling we will create an application based on WildFly image that will be requested in a loop so that the autoscaler will be able to scale up the number of pods:

$ oc new-app wildfly~https://github.com/fmarchioni/ocpdemos --context-dir=wildfly-basic --name=wildfly-basic

And expose the service through the router with:

$ oc expose service wildfly-basic

Now wait for the application pod to be available:

$ oc get pods
NAME                    READY     STATUS      RESTARTS   AGE
wildfly-basic-1-build   0/1       Completed   0          1h
wildfly-basic-2-0cxrt   1/1       Running     0          36m

Ok, now in order to configure an autoscaler mechanism, we need to define a limit range, which is a mechanism for specifying default project CPU and memory limits and requests.

See as an example the following limits.json file:

{
    "kind": "LimitRange",
    "apiVersion": "v1",
    "metadata": {
        "name": "mylimits",
        "creationTimestamp": null
    },
    "spec": {
        "limits": [
            {
                "type": "Pod",
                "max": {
                    "cpu": "0.2",
                    "memory": "1Gi"
                },
                "min": {
                    "cpu": "30m",
                    "memory": "5Mi"
                }
            },
            {
                "type": "Container",
                "max": {
                    "cpu": "1",
                    "memory": "1Gi"
                },
                "min": {
                    "cpu": "50m",
                    "memory": "5Mi"
                },
                "default": {
                    "cpu": "50m",
                    "memory": "200Mi"
                }
            }
        ]
    }
}

The above json file, defines some min and max ranges both for the Pod and for the Container. You can create the limits in your namespace with:

$ oc create -f limits.json -n myproject

You can check that limits are available by querying through the mylimits object:

$ oc describe limits mylimits
Name:		mylimits
Namespace:	myproject
Type		Resource	Min	Max	Default Request	Default Limit	Max Limit/Request Ratio
--------------------------------------------------------------------------------------------------------
Pod		memory		5Mi	1Gi	-		-		-
Pod		cpu		30m	200m	-		-		-
Container	cpu		50m	1	50m		50m		-
Container	memory		5Mi	1Gi	200Mi		200Mi		-

Ok, we have set on purpose some tight CPU/Memory resource limits on the Pod so that autoscaling will be easily triggered.

Create the Autoscaler

The last step will be creating the Autoscaler object which will describe the range of Pods which the Autoscaler will be allowed to create, based on the CPU threshold:

$ oc autoscale dc wildfly-basic --min 1 --max 3 --cpu-percent=25

In our case, we allow a minimum of 1 Pod and a maximum of 3 Pods for the Deployment config "wildfly-basic". The --cpu-percent parameter is the percentage of the requested CPU that each pod should be using. In case the amount of CPU consumed is higher, the Autoscaler will attempt to create additional Pods.

Load Testing

Now we can finally load test our application. The default route for the application is the following one:

$ oc get routes
NAME            HOST/PORT                                       PATH      SERVICES        PORT       TERMINATION
wildfly-basic   wildfly-basic-myproject.10.201.210.194.xip.io             wildfly-basic   8080-tcp   

And here is the number of Pods which are available before the test:

Autoscaling openshift pods: an example with wildfly

Now we can trigger a number of HTTP requests with:

for i in {1..500}; do curl http://wildfly-basic-myproject.10.201.210.194.xip.io ; done;

As you can see, the Autoscaler has created two additional Pods to meet the number of requests:

Autoscaling openshift pods: an example with wildfly

If you keep the application idle for a while, you will see that the Autoscaler will downscale your Pods back to 1.

Follow us on Twitter