The Easy Way To Deploy Multilanguage Apps to Kubernetes

Kubernetes can be intricate to manage, and companies want to leverage its power while avoiding its complexity. A recent survey found that 84% of companies don’t see value in owning Kubernetes themselves. To address this complexity, Cloud Foundry introduced open-source Korifi, which preserves the classic Cloud Foundry experience of being able to deploy apps written in any language or framework with a single cf push command. But the big difference is that this time, apps are pushed to Kubernetes.

In this tutorial, we’ll explore how to use Korifi to deploy web applications written in different languages: Ruby, Node.js, ASP.NET, and PHP. I will also provide insights into Korifi’s functioning and basic configuration knowledge, helping you kick-start your multi-cloud, multitenant, and polyglot journey.

Ruby

For all the examples in this tutorial, I will use sample web applications that you can download from this GitHub repository, but feel free to use your own. You can also find instructions on installing Korifi in this article, which guides you through the easiest way to achieve that by running two Bash scripts that will set everything up for you.

Once you have Korifi installed and have cloned a Ruby sample application, go into the root folder and type the following command:

Shell
 
cf push my-ruby-app


That’s it! That is all you need to deploy a Ruby application to Kubernetes. Keep in mind that while the first iteration of cf push will take some time as Korifi needs to download a number of elements (I will explain this in the next paragraph); all subsequent runs will be much faster.

At any point, if you want to check the status of a Korifi app, you can use the cf app command, which, in the case of our Ruby app, would be:

Shell
 
cf app my-ruby-app


Node.js

Before deploying a Node.js application to Kubernetes using Korifi, let me explain how it works under the hood.

One of the key components at play here is Cloud Native Buildpacks. The concept was initially introduced in 2011 and adopted by PaaS providers like Google App Engine, GitLab, Deis, and Dokku. This project became a part of the CNCF in 2018.

Buildpacks are primarily designed to convert an application’s source code into an OCI image, such as a Docker image. This process unfolds in two steps: first, it scans the application to identify its dependencies and configures them for seamless operation across diverse clouds. Then, it assembles an image using a Builder, a structured amalgamation of Buildpacks, a foundational build image, a lifecycle, and a reference to a runtime image.

Although you have the option to construct your own build images and Buildpacks, you can also leverage those provided by established entities such as Google, Heroku, and Paketo Buildpacks. In this tutorial, I will exclusively use ones provided by Paketo — an open-source project that delivers production-ready Buildpacks for popular programming languages.

Let’s briefly demonstrate what Korifi does by manually creating a Buildpack from a Node.js application. You can follow the installation instructions here to install the pack CLI. Then, get into the root folder of your application and run the following command:

Shell
 
pack build my-nodejs-app --builder paketobuildpacks/builder:base


Your Node.js OCI image is available; you can check this by running the command:

Shell
 
docker images


Once the Docker image is ready, Korifi utilizes Kubernetes RBAC and CRDs to mimic the robust Cloud Foundry paradigm of orgs and spaces. But the beauty of Korifi is that you don’t have to manage any of that. You only need one command to push a Node.js application to Kubernetes:

Shell
 
cf push my-nodejs-app


That’s it!

ASP.NET

Now, let’s push an ASP.NET application. If you run cf push my-aspnet-app, the build will fail, and you will get the following error message:

Shell
 
BuildFail: Check build log output
FAILED
   2023-08-11T19:12:58.11+0000 [STG/] OUT ERROR: No buildpack groups passed detection.
   2023-08-11T19:12:58.11+0000 [STG/] OUT ERROR: failed to detect: buildpack(s) failed with err


These logs tell us that Korifi may not know a valid Buildpack to package an ASP.NET application. We can verify that by running the following command:

Shell
 
cf buildpacks


You should get the following output, and we can see that there are no .NET-related buildpacks.

Shell
 
position   name                         stack                        enabled   locked   filename
1          paketo-buildpacks/java       io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/java@9.18.0
2          paketo-buildpacks/go         io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/go@4.4.5
3          paketo-buildpacks/nodejs     io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/nodejs@1.8.0
4          paketo-buildpacks/ruby       io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/ruby@0.39.0
5          paketo-buildpacks/procfile   io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/procfile@5.6.4


To fix that, first, we need to tell Korifi which Buildpack to use for an ASP.NET application by editing the ClusterStore:

Shell
 
kubectl edit clusterstore cf-default-buildpacks -n tutorial-space


Make sure to replace tutorial-space with the value you used during your Korifi cluster configuration. Add the line – image: gcr.io/paketo-buildpacks/python; your file should look like this:

Shell
 
spec:
  sources:
  - image: gcr.io/paketo-buildpacks/java
  - image: gcr.io/paketo-buildpacks/nodejs
  - image: gcr.io/paketo-buildpacks/ruby
  - image: gcr.io/paketo-buildpacks/procfile
  - image: gcr.io/paketo-buildpacks/go
  - image: gcr.io/paketo-buildpacks/python


Then we need to tell Korifi in which order to use Buildbacks by editing our ClusterBuilder:

Shell
 
kubectl edit clusterbuilder cf-kpack-cluster-builder -n tutorial-space


Add the line – id: paketo-buildpacks/dotnet-core at the top of the spec order list. your file should look like this:

Shell
 
spec:
  sources:
  - image: gcr.io/paketo-buildpacks/java
  - image: gcr.io/paketo-buildpacks/nodejs
  - image: gcr.io/paketo-buildpacks/ruby
  - image: gcr.io/paketo-buildpacks/procfile
  - image: gcr.io/paketo-buildpacks/go
  - image: gcr.io/paketo-buildpacks/python


If everything was done right, you should see the .NET Core Paketo Buildpack in the list output by the cf buildpacks command. Finally, you can simply run cf push my-aspnet-app to push your ASP.NET application to Kubernetes.

PHP

We need to follow the same process for PHP with the Buildpack paketo-buildpacks/php that needs to be added to the ClusterStore and ClusterBuilder.

For anyone using Korifi version 0.9.0 released a few days ago, the issue that I am about to discuss has been fixed. But in case you are using an older version, running cf push my-php-app will fail and return the following error message:

Shell
 
[APP/] OUT php: error while loading shared libraries: libxml2.so.2: cannot open shared object file: No such file or directory


The OCI image is missing the libxml library, which is required by PHP, this is probably due to the builder not supporting PHP. To check that, let’s look what builder Korifi is using by running this command:

Shell
 
kubectl describe clusterbuilder cf-kpack-cluster-builder | grep 'Run Image'


Which will output the following:

Shell
 
 Run Image:  index.docker.io/paketobuildpacks/run-jammy-base@sha256:4cf369b562808105d3297296efea68449a2ae17d8bb15508f573cc78aa3b3772a


As you can see, Korifi currently uses Paketo Jammy Base, which, according to its Github repo description, does not support PHP. You also can check that by looking at the builder’s builder.toml file or by running the command pack builder suggest, which will return the output:

Shell
 
Suggested builders:
[...]
	Paketo Buildpacks:     paketobuildpacks/builder-jammy-base                     Ubuntu 22.04 Jammy Jellyfish base image with buildpacks for Java, Go, .NET Core, Node.js, Python, Apache HTTPD, NGINX and Procfile
	Paketo Buildpacks:     paketobuildpacks/builder-jammy-buildpackless-static     Static base image (Ubuntu Jammy Jellyfish build image, distroless-like run image) with no buildpacks included. To use, specify buildpack at build time.
	Paketo Buildpacks:     paketobuildpacks/builder-jammy-full                     Ubuntu 22.04 Jammy Jellyfish full image with buildpacks for Apache HTTPD, Go, Java, Java Native Image, .NET, NGINX, Node.js, PHP, Procfile, Python, and Ruby
[...]


While Jammy Base does not support PHP, the Jammy Full builder does. There are multiple ways to get Korifi to use another builder, I will just cover one way in this tutorial. This way assumes that we used the easy way to install Korifi with the deploy-on-kind.sh script.

You need to go to Korifi source code and edit the file scripts/assets/values.yaml so that the fields clusterStackBuildImage and clusterStackRunImage are set to paketobuildpacks/build-jammy-full by running this command:

Shell
 
sed -i 's/base/full/g' scripts/assets/values.yaml`


Then, run the scripts/deploy-on-kind.sh script.

That’s it! Korifi will use the Jammy full builder, and Korifi will be able to deploy your PHP application with a cf push my-php-app command.

Summary

Hopefully, now you’ve experienced just how easy it is to use Korifi to deploy applications to Kubernetes written in Ruby, Node.js, ASP.NET, and PHP. You can stay tuned with the Korifi project by following Cloud Foundry X account and joining the Slack workspace.

 

 

 

 

Top