Ballerina Deployment with Google Cloud Platoform Kubernetes Engine
Google Kubernetes Engine (GKE) is a powerful cluster manager and orchestration system for running your Docker containers
In this guide you will learn about building a Ballerina service and deploying it on Google Kubernetes Enginer (GKE).
The following are the sections available in this guide.
What you’ll build
In this guide, you will build a simple Ballerina Hello World service, and you will deploy this service on GKE.
Compatibility
Ballerina Language Version |
---|
0.990.0 |
Prerequisites
- Ballerina Distribution
- A Text Editor or an IDE
- Docker
- kubectl
- Docker Hub Account
- Google Cloud Platform account
Optional requirements
- Ballerina IDE plugins (IntelliJ IDEA, VSCode)
Implementation
Create the project structure
Ballerina is a complete programming language that can have any custom project structure that you wish. Although the language allows you to have any module structure, use the following module structure for this project to follow this guide.
ballerina-gke-deployment
└── guide
└── hello_world_service.bal
-
Create the above directories in your local machine and also create empty
.bal
file. -
Then open the terminal and navigate to
ballerina-gke-deployment/guide
and run Ballerina project initializing toolkit.
$ ballerina init
As the first step, add the following content to the hello_world_service.bal.
import ballerina/http;
import ballerina/log;
import ballerinax/kubernetes;
listener http:Listener httpListener = new(9090);
// By default, Ballerina exposes a service via HTTP/1.1.
service hello on httpListener {
// Invoke all resources with arguments of server connector and request.
resource function sayHello(http:Caller caller, http:Request req) {
http:Response res = new;
// Use a util method to set a string payload.
res.setPayload("Hello, World!");
// Send the response back to the caller.
var result = caller->respond(res);
if (result is error) {
log:printError("Error sending response", err = result);
}
}
}
Now you can add the Kubernetes annotations that are required to generate the Kubernetes deployment artifacts.
import ballerina/http;
import ballerina/log;
import ballerinax/kubernetes;
@kubernetes:Service {
name:"hello-world",
serviceType:"LoadBalancer",
port:80
}
listener http:Listener httpListener = new(9090);
@kubernetes:Deployment {
enableLiveness:true,
image:"<username>/hello_world_service:latest",
push:true,
username:"<username>",
password:"<password"
}
// By default, Ballerina exposes a service via HTTP/1.1.
service hello on httpListener {
// Invoke all resources with arguments of server connector and request.
resource function sayHello(http:Caller caller, http:Request req) {
http:Response res = new;
// Use a util method to set a string payload.
res.setPayload("Hello, World!");
// Send the response back to the caller.
var result = caller->respond(res);
if (result is error) {
log:printError("Error sending response", err = result);
}
}
}
We will be building a Docker image here and publishing it to Docker Hub. This is required, since we cannot simply have the Docker image in the local registry, and run the Kubernetes applicates in GKE, where it needs to have access to the Docker image in a globally accessible location. For this, an image name should be given in the format $username/$image_name in the "image" property, and "username" and "password" properties needs to contain the Docker Hub account username and password respectively. The property "push" is set to "true" to signal the build process to push the build Docker image to Docker Hub.
You can build the Ballerina service using $ ballerina build hello_world_service.bal
. You should be able to see the following output.
$ ballerina build guide/hello_world_service.bal
Compiling source
hello_world_service.bal
Generating executable
hello_world_service.balx
@kubernetes:Service - complete 1/1
@kubernetes:Deployment - complete 1/1
@kubernetes:Docker - complete 2/3
@kubernetes:Docker - complete 3/3
@kubernetes:Helm - complete 1/1
Run the following command to deploy the Kubernetes artifacts:
kubectl apply -f /home/manurip/Documents/Work/Repositories/ballerina-gcp-deployment/kubernetes/
Run the following command to install the application using Helm:
helm install --name hello-world-service-deployment /home/manurip/Documents/Work/Repositories/ballerina-gcp-deployment/kubernetes/hello-world-service-deployment
After the build is complete, the Docker image is created and pushed to Docker Hub. The Kubernetes deployment artifacts are generated as well.
Deployment
- Configuring GKE environment
Before deploying the service on GKE, you will need to setup the GKE environment to create the Kubernetes cluster and deploy an application.
Let's start by installing the Google Cloud SDK in our local machine. Please refer to Google Cloud SDK Installation in finding the steps for the installation.
Next step is gcloud configuration and creating a Google Cloud Platform project.
You can begin with gcloud init
command.
$ gcloud init
Welcome! This command will take you through the configuration of gcloud.
Your current configuration has been set to: [default]
You can skip diagnostics next time by using the following flag:
gcloud init --skip-diagnostics
Network diagnostic detects and fixes local network connection issues.
Checking network connection...done.
Reachability Check passed.
Network diagnostic passed (1/1 checks passed).
You must log in to continue. Would you like to log in (Y/n)?
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/auth?redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&prompt=select_account&response_type=code&client_id=32555940559.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&access_type=offline
Once you click on the provided link, you will be prompted to login to your Google account and authorize.
Once authentication flow completes, you will be prompted to create a new project or choose an existing project as the current project. Here, we are creating a project named "BallerinaDemo"
This account has no projects.
Would you like to create one? (Y/n)?
Enter a Project ID. Note that a Project ID CANNOT be changed later.
Project IDs must be 6-30 characters (lowercase ASCII, digits, or
hyphens) in length and start with a lowercase letter. BallerinaDemo
Your current project has been set to: [BallerinaDemo].
Not setting default zone/region (this feature makes it easier to use
[gcloud compute] by setting an appropriate default value for the
--zone and --region flag).
See https://cloud.google.com/compute/docs/gcloud-compute section on how to set
default compute region and zone manually. If you would like [gcloud init] to be
able to do this for you the next time you run it, make sure the
Compute Engine API is enabled for your project on the
https://console.developers.google.com/apis page.
Created a default .boto configuration file at [/home/manurip/.boto]. See this file and
[https://cloud.google.com/storage/docs/gsutil/commands/config] for more
information about configuring Google Cloud Storage.
Your Google Cloud SDK is configured and ready to use!
With the following command you can list the projects.
$ gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
ballerinademo-225007 BallerinaDemo 1036334079773
- Create the Kubernetes cluster
Next step is creating a kubernetes cluster in the project we just created. With a command similar to below, you can create a cluster with minimal resources.
gcloud container clusters create ballerina_demo_cluster --zone us-central1 --machine-type g1-small --disk-size 30GB --max-nodes-per-pool 1
With the following command you can verify the cluster is running.
$ gcloud container clusters list
ballerina-demo-cluster us-central1 1.9.7-gke.11 35.239.235.173 g1-small 1.9.7-gke.11 3 RUNNING
Also, with kubectl get nodes
commands you can verify the connection to the cluster. In next steps we'll be using
kubectl
in order to create our kubernetes deployment.
Please note that when you create a cluster using gcloud container clusters create, an entry is automatically added to the kubeconfig in your environment, and the current context changes to that cluster. Therefore, we don't have to do any manual
configuration to make it possible for kubectl
to talk to the cluster.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-ballerina-demo-clust-default-pool-70ca2fd4-jv97 Ready <none> 4h v1.9.7-gke.11
gke-ballerina-demo-clust-default-pool-77c556be-x42n Ready <none> 4h v1.9.7-gke.11
gke-ballerina-demo-clust-default-pool-8a9f3889-l6ks Ready <none> 4h v1.9.7-gke.11
- Deploying the Ballerina service in GKE
Since the Kubernetes artifacts were automatically built in the earlier Ballerina application build, we simply have to run the following command to deploy the Ballerina service in GKE:
$ kubectl apply -f /home/manurip/Documents/Work/Repositories/ballerina-gcp-deployment/kubernetes/
service "hello-world" created
deployment.extensions "hello-world-service-deployment" created
When you list the pods in Kubernetes, it shows that the current application was deployed successfully.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-service-deployment-6ccccb4dd8-wd78n 1/1 Running 0 3h
After verifying that the pod is alive, we can list the services to see the status of the Kubernetes service created to represent our Ballerina service:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world LoadBalancer 10.19.255.12 104.154.64.112 80:30736/TCP 3h
kubernetes ClusterIP 10.19.240.1 <none> 443/TCP 4h
Testing
You've just deployed your first Ballerina service in GKE!. You can test out the service using a web browser with the URL http://$EXTERNAL-IP/hello/sayHello, or by running the following cURL command:
$ curl http://$EXTERNAL-IP/hello/sayHello
Hello, World!