Kubernetes is an open source software solution for orchestrating application containers that run across a cluster of physical machines. The cluster provides compute power, networking and storage through a set of organized worker nodes, which can keep applications running in a highly available manner. This post describes some basic Kubernetes concepts, and in particular explains their relevance for readers coming from an IBM Integration Bus background.
Originally based on technology created at Google, Kubernetes has now been donated to the open source community under the stewardship of the Cloud Native Computing Federation (of which IBM is a contributing member). IBM also provides its own forms of the Kubernetes technology supported for production workloads, both in the cloud and on-premises:
IBM Integration Bus has traditionally been marketed as a product which provides users with an Enterprise Service Bus integration pattern. This pattern is typically characterized as a centralised component, running on a range of platforms in a private data center positioned behind a corporate firewall, which sits between applications and Systems of Record. Increasingly however, the product’s versatility has seen our users deploy IIB as a lightweight integration engine, running inside one or more containers as part of a microservices architecture. In this guise, IIB still plays to its traditional functional strengths providing routing and transformation capabilities which can expose Systems of Record as convenient REST APIs and messaging streams. Under some circumstances, IIB can also be used to implement a microservice. If you are planning to use an integration engine like IIB inside a microservice architecture, you will probably be interested in how it functions as a compliant 12-factor application. Further background on these ideas is available in this article which expands on the idea of how IIB can be used as a lightweight integration engine and shows how integrations built using IBM Integration Bus (IIB) can be compliant with the 12-factor approach.
In this post, we will dive deeper into this area and discuss how IIB can be run inside one or more Docker containers which are orchestrated using the open source Kubernetes framework. In future posts we will show worked examples of IIB operating in conjunction with Kubernetes. As future articles in this series are published we will come back and update the article list below:
Kubernetes (v1 was announced and released in 2015), provides an open source system for helping run, deploy and automate the management of applications running in container systems such as Docker. It can help you package applications and manage them through the “Kubernetes Control Plane” which is a collection of processes runing in the Kubernetes cluster whose job is to try and make the cluster’s current state match with a desired state expressed by the user. As a user of the system, and particularly as an IIB user who is entirely new to Kubernetes clusters, you will typically be interacting with objects defined to Kubernetes either using the command-line interface called kubectl, or using the Kubernetes dashboard. These interfaces use the Kubernetes API to exchange information with the cluster and configure it for your purposes. In this regard, you can treat large parts of the Kubernetes system as a black box.
Kubernetes Master
The Master node provides management services for centrally controlling and monitoring the rest of the Kubernetes cluster. Specifically the Master is responsible for orchestrating Worker nodes and making choices about how to run the cluster. This includes scheduling your containerized applications so that they are suitably provisioned to take advantage of the available compute resources in the cluster, and in order to meet the desired state of the deployed applications.
Kubernetes Worker
The role of a Worker node is to run containerized applications. It could be a virtual machine or an actual physical machine, and will have a defined maximum CPU and memory capacity. Typically a Kubernetes cluster will have multiple workers, and you can also always add further worker nodes as the need to add further compute resources comes along. Workers will:
- Manage the networking between the running containers (running inside “pods” – see below)
- Communicate with the Master node
- Provide the container runtime (e.g. Docker) which is responsible for downloading images and running the associated containers.
Worker nodes run a kubelet service which talks to the Master (including interacting with the etcd store of configuration information), and is responsible for starting and stopping containers on the worker. Worker nodes can be marked as “unschedulable” to prevent new pods from being placed on the worker in question. The kubectl command (the CLI for running commands to manage Kubernetes clusters) has a cordon option for this purpose.
Kubernetes Pods
Pods are defined to be a group of one or more containers which have access to the same shared storage and network. Applications in a traditional IT architecture which were required to be co-located on the same physical host, will typically be pushed into the same Kubernetes pod because here they will share an IP address and port space, and can communicate using inter-process communication methods such as semaphores and shared memory. Just like Docker containers, for cloud native applications, pods should really be considered to be relatively short lived and will typically operate in a stateless fashion. They can be stopped, destroyed and a new one started in its place very quickly with a minimum of configuration. In this regard, IIB users should really think very carefully before departing from the most common IIB architectural model of each Kubernetes pod, containing one IIB integration node which is configured to own one IIB integration server.
In cases where you are trying to make IIB behave in a cloud-native fashion for running in Kubernetes, we encourage you to follow a suggested best practice of using a single IIB node definition, owning a singe IIB integration server inside each container. We also encourage you to use a single IIB container in each Kubernetes pod. This keeps your architecture very simple, and will encourage your architecture to follow the well-known mantra of treating your IIB integration servers as “cattle not pets”. To scale IIB in a Kubernetes environment, we encourage you to rely on Kubernetes’ auto-scaling capabilities to deploy extra pods, rather than attempting to add extra integration server processes into the existing container(s) (which is the way you might typically first think of scaling IIB if you come from a background of treating IIB as an on-premise ESB implementation pattern). So with this advice in mind, let’s next consider how to describe IIB when deploying to Kubernetes…
IIB can be administered remotely by sending instructions over the public IIB administrative REST API. This involves connecting through the web administration port (by default this is port 4414). Typically you might also want to expose a port for sending HTTP traffic into an IIB integration server (by default using port 7800). You might expose other ports for the use of other transport protocols, but these two ports are the most common that a user might start by thinking of exposing using IIB deployments to a Kubernetes cluster. So, even a basic IIB Kubernetes service definition will probably require more than one port to be exposed, even if you choose to follow our suggested best practice of using a single IIB node, owning a single IIB integration server.
Kubernetes describes the concept of a service as “an abstraction which defines a logical set of Pods and a policy by which to access them – sometimes called a micro-service”. Many Kubernetes services need to expose more than one port. For this case, Kubernetes supports users defining multiple port definitions on a Service object. When using multiple ports, they are given names, so that endpoints can be disambiguated. The easiest way to define a Kubernetes service is to use a tool called Helm, and a packaging format called a Helm chart. A chart is a collection of files that describe a related set of Kubernetes resources. The excellent following description is taken from the Kubernetes Helm readme:
- Helm has two parts: a client component (commonly referred to as helm) and a server component (commonly referred to as tiller)
- Tiller runs inside of your Kubernetes cluster, and manages releases (installations) of your charts.
- Helm can run on your laptop, or as part of a Continuous Integration / Continuous Delivery pipeline
- Charts are Helm packages that contain at least two things:
- A description of the package (Chart.yaml)
- One or more templates, which contain Kubernetes manifest files
- Charts can be stored on disk, or fetched from remote chart repositories
Below, is a small snippet from an example IIB Helm chart. As you can see it includes the specifications for ports 4414 and 7800 which an IIB system would expect to be enabled:
apiVersion: v1
kind: Service
metadata:
name: iibv10
labels:
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
spec:
type: LoadBalancer
ports:
- port: 4414
targetPort: 4414
name: webui
- port: 7800
targetPort: 7800
name: serverlistener
selector:
app: iibv10
In future posts we will dive deeper into an example IIB Helm chart and demonstrate how it can be used to control Kubernetes deployments.