A java application and a single-node Cassandra instance are running in Google Kubernetes Engine.
The java app and Cassandra each run in their own container, with each container running in its own Pod.
The Cassandra deployment mounts a volume which is provisioned by Google Cloud Platform.
This ensures that when Cassandra pods are re-provisioned, the data is not lost.
+-------+ +-------+
|Service| |Service|
+-------+ +-------+
| |
| |
| |
| |
+----------------+-----------------+ +----------------+-----------------+
|Deployment | |Deployment |
| | | |
| +------------------------+ | | +------------------------+ |
| |Pod | | | |Pod | |
| | | | | | | |
| | +--------------------+ | | | | +--------------------+ | |
| | |Cassandra Container | | | | | |Payload Viewer | | |
| | | | | | | | |Container | | |
| | | | | | | | | | | |
| | +--------------------+ | | | | +--------------------+ | |
| | | | | | | |
| +------------------------+ | | +------------------------+ |
| | | |
+----------------+-----------------+ +----------------------------------+
|
|
v
+-----+----+
| |
| 2GB |
| |
+----------+
- The Illustrated Children's Guide to Kubernetes
- A Cloud Guru - Kubernetes Deep Dive
- GCP YouTube Channel - Kubernetes Best Practices playlist
- GCP's Hello Kubernetes Lab
- Hello Minikube Tutorial
- Kubectl Cheatsheet
Containers are made possible by a set of facilities in the Linux Kernel that allow lightweight partitioning of a host operating system into isolated spaces—containers—where applications can safely run.
Credit: Pantheon - Why Containers?
Containers offer a logical packaging mechanism in which applications can be abstracted from the environment in which they actually run.
Instead of virtualizing the hardware stack as with the virtual machines approach, containers virtualize at the operating system level, with multiple containers running atop the OS kernel directly. This means that containers are far more lightweight: they share the OS kernel, start much faster, and use a fraction of the memory compared to booting an entire OS.
Credit: cloud.google.com - Containers 101
- Extremely fast provisioning. Containers can be quickly started, stopped and relocated.
- Each appliction's runtime environment and dependencies are defined by the developer and stored under source control.
- IT operations teams focus on deployment and management without bothering with application details such as specific software versions and configurations specific to the app.
- Consistent environment as an application moves from development through to production. Credit: cloud.google.com - Containers 101
- Containers do not run at bare metal speed. More suited to microservice style applications that can benefit from horizontally scale.
- Not all applications suit the architecture of microservies.
- Applications with a graphical frontend are not well suited to containers. X11 forwarding is a clunky workaround.
- Command line interface with
kubectl
which wraps and extends the familiardocker
command. - Declaritive workflow - Developer describes desired cluster state in yaml files and publish these to the K8s API server.
- Container Registry
- Pod
- Deployment
- Service
- Persistent Storage
- Auto-scaling of the cluster nodes
- Auto-scaling of the pods
- Role-based Access Control
In brief:
- Sign up with GCP
- Do the hello-world tutorial
- Select an application and Dockerise it
- Create your Kubernetes Cluster
- Set up your local dev environment
- Deploy your application
- Expose your application
- Test and Debug your application
... and now, in detail ...
Sign up with Google Cloud Platform.
You will hopefully have been awarded USD$300 of GCP credit which should hopefully last you a good amount of time.
Follow the GCP's Hello Kubernetes Lab.
Following this lab you will have gcloud
and kubectl
installed on your laptop.
You will then have a basic usable Kubernetes Dev environment.
Write a Dockerfile
that can be built into an image that runs your application.
Your application can be a rudimentary nodejs webserver (that's what I did) or a java application with a dependency on a Cassandra cluster (which is what we eventually created).
First you should confirm that your docker image runs correctly on your local machine.
Next, configure your docker runtime so that it can push images to the docker container registry in your GCP project.
gcloud auth configure-docker
Now tag your image with a name that GCP will accept.
docker tag myapplication:v1 gcr.io/[MY_GCP_PROJECT_NAME]/myapplication:v1
Alternatively you could just build your image with a specific name.
docker build -t gcr.io/[MY_GCP_PROJECT_NAME]/myapplication:v1 .
Now push your image to your private docker registry in GCP as follows:
docker push gcr.io/[MY_GCP_PROJECT_NAME]/myapplication:v1
As a side note, check out this 8 minute video from the official GCP YouTube channel about how to keep your docker images small.
Open the GCP Console -> Kubernetes Clusters and click Create Cluster.
Select a Standard Cluster. This will create a 3 node cluster with modest hardware performance.
When your cluster has been provisioned, click on the small connect button.
You will see a shell command like the following which you should run in your local dev machine.
gcloud container clusters get-credentials <YOUR_CLUSTER_NAME> --zone us-central1-a --project <YOUR_GCP_PROJECT_NAME>
Hopefully, the following commands also work.
kubectl get pods
kubectl get services
kubectl get deployments
kubectl get pvc
kubectl get pv
All of the above will show no resources because all you have done is provision some VMs and started an empty Kubernetes cluster. We have not depoyed any services kubectl
has nothing to report.
Your application is represented by the docker images you created earlier.
When launched, your application will run in a docker container.
In Kubernetes, it is standard practice to launch each docker container inside its own Kubernetes Pod.
You can generally replace the word "pod" with "container" and accurately understand the concept.
Credit: coreos.com
To launch your container in a pod, you must describe to Kubernetes how you want your application to run.
This description is expressed in yaml
and is called a deployment descriptor
. See payloadviewer_deployment.yaml.
You launch the payloadviewer pod by publishing payloadviewer_deployment.yaml
to your cluster as follows:
> kubectl apply -f payloadviewer_deployment.yaml
You may now view your new pod.
> kubectl get pods
Pods are expected to be created and destroyed reasonably frequently.
Auto-scaling rules may create or destroy pods or you may have a busy continuous deployment pipeline.
When a pod is destroyed and a new one takes its place, it has a new hostname and ip address.
To help establish a reliable presence in your cluster, you may create a service for your replica-set of pods.
You may assign your service a user-friendly hostname and its IP address will remain the same throughout its service to your chosen replica-set.
It is expected that other pods in your cluster will locate each other by interacting with service
objects in your cluster.
Here is a sample service which is launched in the same way that we launched the deployment
in the previous section.
> kubectl apply -f payloadviewer_service.yaml
When the service has been created, you will see that it has an external IP Address.
> kubectl get service payloadviewer
This is the IP address that you will use to communicate with your application.
In Google Cloud Platform, it is very simple to attach persistent storage to your pods.
Two steps are required:
A Persistent Storage Claim (PVC) is a request for storage. For example: I would like a 20GB disk.
Here is a sample PVC.
The next step is to mount the provision disk on your pods as follows.
volumes:
- name: cassandra-persistent-storage
persistentVolumeClaim:
claimName: cassandra-pv-claim
See the bottom of cassandra_deployment.yaml to see how the above snippet is used.
With this snippet in place, every pod that is created as part of this deployment, will mount this disk.
The disk will remain as pods are created and destroyed. Your data is safe!
The above steps show how to launch a docker container in a pod and expose it to the world using a Kubernetes Service.
If, however, you wish to debug it, there are some options.
> kubectl get pods
> kubectl exec -it [MY_POD_NAME] /bin/bash # You are now ssh'd into your container and you may debug as you wish.
> kubectl logs payloadviewer # This will show some logs that your application may have produce while it was running.