0

Ingress, Kubernetes, Akkahttp, Docker on Google Cloud Platform

Last years october post Akkahttp, Docker and Kubernetes using Minikube blog post describes how to work with Kubernetes on your local machine.
This post is about how to run an akkahttp sample project on Google Cloud Platform (GCP) using Kubernetes.             

Kubernetes is not only available locally but also on many cloud providers including GCP, Amazon Web Services (AWS) and others. Trying Kubernetes on GCP makes sense, because GCP is a google service and Kubernetes is initiated by Google.

Preconditions

The steps below assume these preconditions are in place:

Caution: existing Kubernetes installations

In case you followed the http://kubernetes.io/docs/user-guide/prereqs/ steps to install kubernetes initially you may have /usr/local/bin/kubectl in your path.
Google Cloud SDK uses a different item in your path. The existing Kubernetes entry has to be deleted to avoid confusion. Kubernetes has to be installed as Google Cloud SDK component though.

 

GCP setup

First step is to create a GCP project as described in kubernetes hello node in order to deploy and run any Kubernetes project.
Two variables should be defined in the local terminal session for later use:

  • export PROJECT_ID="akkahttp-playground-gcproj"
  • export CLUSTER_ID="akkahttp-playground-cluster"

Next step is to create and upload the docker image of the akkahttp sample project to a docker registry.
In this case, the docker image has to be deployed to the google container registry (gcr) first, hence the docker image tag includes a gcr.io reference.

I used the sbt docker plugin to create the docker image using this command:

sbt -DdockerOrganization=info.lotharschulz \
-DdockerName=akkahttp-playground \
-DdockerBImage=lotharschulz/scala:0.0.3 -DdockerRepo=gcr.io  \
-DartefactVersion=v0.0.3 -DversionInDocker=v0.0.3  \
-DdockerPackageName=$PROJECT_ID/akkahttp-playground  \
docker:publishLocal

You can find the -D parameters defined in build.sbt file: build.sbt#L27 ff.
The docker image list (docker images) should contain now the created image e.g.:

REPOSITORY                                              TAG          ...  ...
gcr.io/akkahttp-playground-gcproj/akkahttp-playground   v0.0.3       ...  ...

You can run this image locally:

docker run -it -p 8181:8181 --name akkahttp-playground --rm gcr.io/$PROJECT_ID/akkahttp-playground:v0.0.3

and test the service:

curl -v http://localhost:8181/

Stopping the container will also remove the container from the docker process list since the –rm flag is used (thx CyberDem0n for the tip).

No it”s time to upload the docker image to gcr:

gcloud docker -- push gcr.io/$PROJECT_ID/akkahttp-playground:v0.0.3

 

Next step would be to create a cluster.

gcloud container clusters create $CLUSTER_ID

creates a cluster including a master API server. You can also list the clusters:

gcloud container clusters list

as well as you have to fetch the cluster credentials using:

gcloud container clusters get-credentials $CLUSTER_ID

 

Now it is time to use Kubernetes.

A kubernetes deployment can be created using:

kubectl create -f gcloud-deployment-config.yaml --record

That will also create pod(s) that referencing the uploaded docker image.
There is only one pod created in this example as replicas is set to one.

There are basically 2 ways to route internet traffic to the akkahttp service:

  • load balancer
  • ingress

load balancer

Kubernetes deployments can be exposed to generate a public IP using a load balancer:

kubectl expose deployment akkahttpplayground-deployment --type="LoadBalancer" --port=8181 --target-port=8181

Exposing a deployment this way creates a service that provides a public IP e.g.

NAME                                CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
svc/akkahttpplayground-deployment   10.59.251.86   104.199.28.229   8181/TCP   1m

You can test the service e.g.:

curl http://104.199.28.229:8181/hello

that would produce {“msg”:”my msg”}

 

ingress

Another option to route traffic to the service is ingress that “allows inbound connections to reach the cluster services”. With this approach there is no load balancer required.
This approach consists of 2 steps:

  1. create a service:
    kubectl create -f gcloud-service-config.yaml
    
  2. ingress setup:
    kubectl create -f gcloud-ingress-config.yaml
    

Ingress on GCE expects an endpoint on / as health check, so I created an regarding endpoint in MyService class.

Getting the ingress item

kubectl get ing akkahttpplayground-ingress --watch

should include this output after some time:

NAME                         HOSTS     ADDRESS         PORTS     AGE
akkahttpplayground-ingress   *                         80        11s
akkahttpplayground-ingress   *         130.211.36.41   80        44s
akkahttpplayground-ingress   *         130.211.36.41   80        44s
akkahttpplayground-ingress   *         130.211.36.41   80        1m

The watch flag will update the output once an event arrives.

You can test the service e.g.

curl http://130.211.36.41/
curl http://130.211.36.41/hello
{"status":"is up"}
{"msg":"my msg"}

I really like the option to route internal paths with ingress to other public paths: gcloud-ingress-config.yaml#L17

 

Final thoughts

In case you want to try out Kubernetes on a cloud, GCP is one option. The Kubernetes/GCP integration is seamless. Beta resources like ingress are available on GCP already. That is hopefully the case for other beta resources in the future as well.

Due to that GCP is a very good option at least to test Kubernetes in the cloud .

related links

docker images used in this post

Lothar Schulz

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.