According to the Kubernetes website:
It is a simple and powerful tool for managing containerized applications. It provides zero downtime when you roll out a newer application or update an existing application. You can automate it to scale in and out based on certain factors. It also provides self-healing so that Kubernetes automatically detects the failing application and spins up a new instance. We can also define secrets and configuration that can be used across instances.
Kubernetes primarily focuses on zero downtime production application upgrades and also scales them as required.
A single deployable component is called a pod in Kubernetes. This can be as simple as a running process in the container. A group of pods can be combined together to form a deployment.
Similar to Docker Compose, we can define the applications and their required services in a single YAML file or multiple files (as per our convenience).
The following code is a sample Kubernetes file that will start an NGINX server:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Here, we start with apiVersion in a Kubernetes deployment file. This is followed by the type, which takes a pod, deployment, service, namespace, Ingress (load balancing the pods), role, or something else.
This is followed by the metadata information, such as the type of environments, the deployment name (nginx-deployment), and labels (Kubernetes uses this information to identify and segregate the pods). Kubernetes uses this metadata information to identify particular pods or a group of pods, and we can manage these instances with this metadata. This is one of the key differences with Docker Compose, where Docker Compose doesn't have the flexibility of defining the metadata pertaining to the containers.
This is followed by the spec, where we define the replicas, selectors, and deployment template.
Within the template is containers, where the specification of the images or our application is defined. There can be one or more containers in a deployment. We can also define the pull strategy for our images, as well as the environment variables and their exposed ports. We can define the resource limitations on the machine (or VM) for a particular service. We can also define health checks here, that is, each service is monitored for its health and, when some services fail, they are immediately replaced by newer ones.
They also provide service discovery out of the box by assigning each pod an IP, which makes it easier for the services to identify and interact with them. They also provide a better dashboard so that you can visualize your architecture and the status of the application. You can do most of this management via this dashboard, including checking the status, logs, scaling the services up or down, and so on.
Since Kubernetes provides a complete orchestration of our services and deployments with configurable options, it makes it a bit hard to set up initially, and this means it is not ideal for a development environment. We also need the kubectl CLI tool for management. Despite the fact that we use Docker images inside, the Docker CLI can't be used.
There is also Minikube (minified Kubernetes), which is used for developing and testing applications locally. Kubernetes can also be enabled on Docker Desktop on Mac and Windows for development and testing purposes.
We will focus more on the Kubernetes sub-generator in the next chapter.