A new programming language, Ballerina, can compile right into Docker and Kubernetes artifacts.

Kubernetes is rapidly becoming the platform to run your microservices. Unfortunately, for most existing programming languages this means that developers or operations need to produce hundreds of lines of YAML configuration files defining the deployment.

Ballerina is a cloud-native programming language aimed at making microservice development and deployment easy. Let us see how with just a little bit of annotations Ballerina code can be deployed into Docker and Kubernetes.

Suppose, I have a simple service designed in Ballerina. This is an HTTP service called hello on port 9090, it has a single POST resource called hi that accepts a string name in the request and sends "Hello, name" back:

import ballerina/http; endpoint http:Listener listener { port: 9090 }; service<http:Service> hello bind listener { @http:ResourceConfig { methods: ["POST"] } hi (endpoint caller, http:Request request) { string name = check request.getTextPayload(); _ = caller->respond("Hello, " + name); } }

If I compile and run it with Ballerina, I can invoke the service with curl (or some other HTTP client):

$ ballerina build demo.bal $ ballerina run demo.balx ballerina: initiating service(s) in 'demo.bal' ballerina: started HTTP/WS endpoint 0.0.0.0:9090 $ curl -X POST -d "Ballerina" localhost:9090/hello/hi Hello, Ballerina

Now, if I want to turn this into a Kubernetes deployment, I can simply add @kubernetes annotations right inside the service code.

I will add one to the endpoint definition asking Ballerina build process to turn it into a Kubernetes NodePort, and another one to my hello service itself to turn it into a Docker image and Kubernetes deployment.

import ballerina/http; import ballerinax/kubernetes; @kubernetes:Service { serviceType: "NodePort", name: "ballerina-demo" } endpoint http:Listener listener { port: 9090 }; @kubernetes:Deployment { image: "demo/ballerina-demo", name: "ballerina-demo" } service<http:Service> hello bind listener { @http:ResourceConfig { methods: ["POST"] } hi (endpoint caller, http:Request request) { string name = check request.getTextPayload(); _ = caller->respond("Hello, " + name); } }

If I do ballerina build now, instead of a local executable file, it will generate me the Docker image and Kubernetes YAMLs that I can deploy right into my cloud:

$ kubectl get pods No resources found. $ ballerina build demo.bal @kubernetes:Deployment - complete 1/1 @kubernetes:Docker - complete 3/3 Run following command to deploy kubernetes artifacts: kubectl apply -f kubernetes/ $ tree . ├── demo.bal ├── demo.balx └── kubernetes ├── demo_deployment.yaml ├── demo_svc.yaml └── docker └── Dockerfile 2 directories, 5 files $ kubectl apply -f kubernetes/ deployment.extensions "ballerina-demo" created service "ballerina-demo" created $ kubectl get pods NAME READY STATUS RESTARTS AGE ballerina-demo-57ccd9f69c-j4klz 1/1 Running 0 6s $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ballerina-demo NodePort 10.100.95.68 <none> 9090:31885/TCP 11s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25d $ curl -X POST -d "Kubernetes" localhost:31885/hello/hi Hello, Kubernetes

Note that we did not have to modify the logic of the service, add or edit any external files, or change our build process.

We only added Kubernetes-specific annotations to the existing code and the build process took care of the rest.

Besides the Services and Deployment annotations that we used, there are a few more for other configuration aspects such as autoscaling, passing config and other files, and so on:

Ballerina is an open-source project. You can find its source code repository at https://github.com/ballerina-platform/ballerina-lang.

This Kubernetes integration is just one of the features that Ballerina has.

You can learn more about Ballerina, see the examples, and download the runtime and tooling at https://ballerina.io.