openshift

How to Expose Openshift Route into a Secure Endpoint

We can do below command to expose a specific Openshift Service into a route or URL

$ oc expose svc <service-name>

but it would create a regular not-secure http endpoint, which sometimes not sufficient enough to fulfil our requirements. Therefore we need to find a way to create a secure route endpoint, and we can achieve that condition by using below command

$ oc create route edge --service <service-name>

It would create a route with an edge TLS termination.

Importing a Custom SPI into Keycloak Operator in Openshift

Keycloak Operator provide a convenient method for uploading a custom SPI into Keycloak instances, and that is by using an extensions inside Keycloak YAML operator.

apiVersion: keycloak.org/v1alpha1
kind: Keycloak
metadata: 
  namespace: my-redhat-sso
  labels:
    app: sso
spec:
  extensions:
    - >-
      https://url/custom-sso-spi-1.0.0.jar
  externalAccess:
    enabled: true
  externalDatabase:
    enabled: true
  instances: 1

Rollout your Keycloak pod, and you can see that Keycloak instance is now having a custom SPI embedded within it.

Java, SecureRandom, and Openshift

Had one unique case where generating a SecureRandom in Java is very very slow, the thing is that this never happens on a regular VM deployment, and only happens in a Pod deployment in Openshift 4.

This is original sample code that is slow,

    @GetMapping(path = "/secure-random")
    public HashMap secureRandom() {
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.setSeed(secureRandom.generateSeed(24));
        return new HashMap(){{
            put("random-value", String.format("%06d", secureRandom.nextInt(1000000)));
        }};
    }

The reason why it is slow is because SecureRandom is relying on the OS random generator which is relying on noise. And it seems that for our case, we are lacking of noise to make a good entropy therefore we arent able to generate a SecureRandom at all.

Our workaround for this is by using a Pseudo Random Number Generator (PRNG) from Java, and not relying on the OS at all. For this example, im using “SHA1PRNG”.

    @GetMapping(path = "/secure-random-new")
    public HashMap secureRandomNew() throws Exception {
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.setSeed(secureRandom.generateSeed(24));
        return new HashMap(){{
            put("random-value", String.format("%06d", secureRandom.nextInt(1000000)));
        }};
    }

Hope it helps.

Fail Fast Architecture using Openshift Container Platform

This week ive met an application that are being deployed as Pod in OCP but having a very unique behaviour, it keeps giving below error every one and a while.

[5585.146s][warning][os,thread] Failed to start thread "Unknown thread" 
         - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached.
[5585.147s][warning][os,thread] Failed to start the native thread for java.lang.Thread "HandshakeCompletedNotify-Thread"
[5586.153s][warning][os,thread] Failed to start thread "Unknown thread" 
         - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached.
[5586.154s][warning][os,thread] Failed to start the native thread for java.lang.Thread "HandshakeCompletedNotify-Thread"
[5589.672s][warning][os,thread] Failed to start thread "Unknown thread" 
         - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached.
[5589.673s][warning][os,thread] Failed to start the native thread for java.lang.Thread "pool-4944-thread-1"
06:57:23,949 
         ERROR [io.undertow.request] (default task-34) UT005023: Exception handling request to /actuator/health: java.lang.OutOfMemoryError: 
         unable to create native thread: possibly out of memory or process/resource limits reached	

It seems that once this error happens, Pod will never recover from this condition. So Openshift need to find a way to handle this situation.

One workaround which i found is by utilizing Kubernetes Liveness Probe, which will detect application’s healthness.

      livenessProbe:
        httpGet:
          path: /actuator/health
          port: 8080
          scheme: HTTP
        initialDelaySeconds: 60
        timeoutSeconds: 3
        periodSeconds: 4
        successThreshold: 1
        failureThreshold: 2

For this configuration I am setting a 4 seconds delay between request and will wait for 3 seconds for reply from the corresponding Pod. And if Pod are unable to response to Openshift’s request for two times, Openshift will force terminate the Pod assuming that the Pod is in an unhealthy state.

This strategy makes applications restart quite often in a day, but at least it will be healthy again after being restarted forcefully.

Direcly Deploy Jar File to Openshift

Openshift provides a convenient method for deploying binary Java applications. Other than deploying application’s source code, it can also deploy Jar file directly. For this example, im trying to deploy a Spring Boot and Red Hat Fuse middleware which is located on below repository.

https://github.com/edwin/hello-world-fuse-on-ocp

After we clone it, we can build the repo into Jar file.

$ mvn clean package

It will later on create a Jar file with the name of hello-world-fuse-on-ocp-1.0-SNAPSHOT.jar, which we can deploy to Openshift later on.

Along the way, we can create Openshift BuildConfig by using below command, it will create an Application template using Java8 on UBI8 base image.

$ oc new-build --name=hello-world-fuse-on-ocp \
		--binary=true \ 
		--image-stream=openshift/ubi8-openjdk-8:1.10  \ 
		--strategy=source

Next is we can deploy our Jar file using below command,

$ oc start-build hello-world-fuse-on-ocp \ 
		--from-file=hello-world-fuse-on-ocp-1.0-SNAPSHOT.jar \ 
		--follow

And publish it,

$ oc new-app hello-world-fuse-on-ocp

$ oc create route edge \
		--service=hello-world-fuse-on-ocp

Lets say we have some code changes and we want to build and redeploy the Application, we can just rerun the start-build command, and deploying the latest jar file into Openshift.

$ oc start-build hello-world-fuse-on-ocp \ 
		--from-file=hello-world-fuse-on-ocp-1.1-LATEST-JAR.jar \ 
		--follow