Introduction to Kubernetes
Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. It provides a framework for managing and coordinating containerized workloads across a cluster of nodes.
In Kubernetes, a cluster is a set of nodes that run containerized applications. Nodes are individual machines (virtual or physical) that form the foundation of a Kubernetes cluster. The master node controls and manages the cluster, while the worker nodes host the applications.
key Kubernetes components
API Server: The central management point of the cluster, responsible for handling API requests and serving as the primary interface for interacting with the cluster.
etcd: A distributed key-value store that stores the cluster's configuration data and serves as its backing store.
Scheduler: Assigns workloads to nodes based on resource requirements, policies, and constraints.
Controller Manager: Ensures that the desired state of objects in the cluster matches the current state and manages various controllers, such as the ReplicaSet controller and Deployment controller.
Container Runtime: Executes containers on nodes, such as Docker or containerd.
Kubelet: Runs on each node and communicates with the master node. It manages containers, ensures their health, and reports node status to the master.
Kubernetes Concepts
Pods
In Kubernetes, containers are not directly deployed on the worker nodes. Instead, Kubernetes encapsulates the containers within a Kubernetes object called pods. A Pod is the smallest deployable unit in Kubernetes. It represents a single instance of a running process in the cluster. Pods can contain one or more containers that share the same network namespace, IPC namespace, and storage volumes.
Here's an example of a pod definition in YAML (pod-definition.yaml):
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-image:tag
To run a pod using the YAML definition, you can use the following command:
kubectl apply -f pod-definition.yaml
ReplicaSets
ReplicaSets ensure that a specified number of pod replicas are running at any given time. They provide fault tolerance and enable the scaling of pods.
Here's an example of a ReplicaSet definition (replicaset-definition.yaml):
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image:tag
To create a ReplicaSet, you can use the following commands:
kubectl apply -f replicaset-definition.yaml
Scaling can also be achieved using the command line, as shown below:
kubectl scale replicaset my-replicaset --replicas=5
Deployments
Deployments provide declarative updates for Pods and ReplicaSets. They manage the rollout and rollback of application updates.
Here's an example of a Deployment definition (deployment-definition.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image:tag
To create a Deployment and perform updates and rollbacks, you can use the following:
kubectl apply -f deployment-definition.yaml
The command below is used to update the image of a container in a deployment:
kubectl set image deployment/my-deployment my-container=my-new-image:tag
This command is used to check the status of a rollout for a deployment:
kubectl rollout status deployment/my-deployment
This is used to rollback a deployment to a previous revision:
kubectl rollout undo deployment/my-deployment
Service
In Kubernetes, a Service is a fundamental building block that enables networking and communication between different components (such as pods) within a cluster
Let's explore three types of Kubernetes Services:
NodePort
Exposes the service on a static port on each node in the cluster. The service is accessible via <NodeIP>:<NodePort>.
Here's an example (service-definition.yaml):
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
nodePort: 30080
ClusterIP
Exposes the service internally within the cluster using a cluster-internal IP. The service is only accessible from within the cluster.
Here's an example (service-definition.yaml):
apiVersion: v1
kind: Service
metadata:
name: my-clusterip-service
spec:
type: ClusterIP
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
LoadBalancer
Provides external access to the service using a cloud provider's load balancer. Here's an example (service-definition.yaml):
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
To create and run the services, you can use the following commands:
kubectl apply -f service-definition.yaml
kubectl get services
Key Differences Between the Services
The major difference between NodePort, ClusterIP, and LoadBalancer in Kubernetes lies in how they expose services and handle external access. Here's a breakdown of each:
NodePort:
Exposes the service on a static port on each worker node in the cluster.
The service is accessible externally using the worker nodes' IP addresses and the assigned static port.
Traffic coming to any worker node on that port is forwarded to the corresponding service and its pods.
Suitable for development or testing environments, but not recommended for production scenarios with large-scale deployments.
ClusterIP:
Provides a stable internal IP address for accessing the service within the cluster.
The service is only accessible from within the cluster and not from outside.
Traffic sent to the ClusterIP is load balanced to the pods belonging to the service.
Suitable for internal communication between different components within the cluster.
LoadBalancer:
Exposes the service using an external load balancer provided by the cloud provider.
The load balancer distributes traffic to the service across multiple pods.
The load balancer obtains a public IP address that allows external clients to access the service.
Typically used in production environments to expose services to the external world.
Microservice Architecture
Say we want to deploy a sample-voting app using the microservices architecture. We'll assume that the necessary Docker images are available in a Docker repository. The app consists of:
Front-end web app for the voting interface.
Another front-end web app for viewing the voting results.
Redis database connected to the voting interface for recording votes.
PostgreSQL database connected to the result app to store the vote percentages.
Worker app that links Redis and PostgreSQL databases.
Here's an illustration of how you can define and deploy these components:
Voting Interface Deployment
Create a Deployment for the voting interface:
apiVersion: apps/v1
kind: Deployment
metadata:
name: voting-interface
spec:
replicas: 1
selector:
matchLabels:
app: voting-interface
template:
metadata:
labels:
app: voting-interface
spec:
containers:
- name: voting-interface
image: dockerrepo/voting-interface:latest
ports:
- containerPort: 80
Voting Interface Service
Create a ClusterIP Service for the voting interface:
apiVersion: v1
kind: Service
metadata:
name: voting-interface-service
spec:
selector:
app: voting-interface
ports:
- protocol: TCP
port: 80
targetPort: 80
Result App Deployment
Create a Deployment for the result app:
apiVersion: apps/v1
kind: Deployment
metadata:
name: result-app
spec:
replicas: 1
selector:
matchLabels:
app: result-app
template:
metadata:
labels:
app: result-app
spec:
containers:
- name: result-app
image: dockerrepo/result-app:latest
ports:
- containerPort: 80
Result App Service
Create a ClusterIP Service for the result app:
apiVersion: v1
kind: Service
metadata:
name: result-app-service
spec:
selector:
app: result-app
ports:
- protocol: TCP
port: 80
targetPort: 80
Redis Deployment
Create a Deployment for Redis:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-db
spec:
replicas: 1
selector:
matchLabels:
app: redis-db
template:
metadata:
labels:
app: redis-db
spec:
containers:
- name: redis-db
image: dockerrepo/redis-db:latest
ports:
- containerPort: 6379
PostgreSQL Deployment
Create a Deployment for PostgreSQL:
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-db
spec:
replicas: 1
selector:
matchLabels:
app: postgres-db
template:
metadata:
labels:
app: postgres-db
spec:
containers:
- name: postgres-db
image: dockerrepo/postgres-db:latest
ports:
- containerPort: 5432
Worker App Deployment
Create a Deployment for the worker app:
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker-app
spec:
replicas: 1
selector:
matchLabels:
app: worker-app
template:
metadata:
labels:
app: worker-app
spec:
containers:
- name: worker-app
image: dockerrepo/worker-app:latest
After creating the deployment and service definitions for each component, you can deploy them using the following commands:
kubectl apply -f voting-interface-deployment.yaml
kubectl apply -f voting-interface-service.yaml
kubectl apply -f result-app-deployment.yaml
kubectl apply -f result-app-service.yaml
kubectl apply -f redis-deployment.yaml
kubectl apply -f postgres-deployment.yaml
kubectl apply -f worker-app-deployment.yaml
This will deploy the sample-voting app using Kubernetes with the defined microservices architecture. You can access the voting interface and result app using their corresponding service endpoints.
Explanation
Here's how the components of the app connect as they come alive:
Front-end Voting Interface:
The front-end voting interface is deployed as a Deployment and exposed through a Service.
When the voting interface pod comes alive, it registers with the Kubernetes Service and obtains an internal IP.
Other components can communicate with the voting interface by using the Service's internal IP and port.
Result App:
The result app is also deployed as a Deployment and exposed through a Service.
When the result app pod comes alive, it registers with the Kubernetes Service and obtains an internal IP.
The result app can communicate with the voting interface through the voting interface's Service IP and port.
Redis Database:
The Redis database, used to record the votes, is deployed as a Deployment.
The voting interface pod connects to the Redis database using the Redis database's DNS name or IP.
The DNS name or IP can be obtained by the voting interface pod through environment variables or configuration.
PostgreSQL Database:
The PostgreSQL database, used to store the percentage of votes casted, is deployed as a Deployment.
The result app pod connects to the PostgreSQL database using the PostgreSQL database's DNS name or IP.
The DNS name or IP can be obtained by the result app pod through environment variables or configuration.
Worker App:
The worker app, responsible for linking Redis and PostgreSQL databases, is deployed as a Deployment.
The worker app pod connects to both the Redis and PostgreSQL databases using their respective DNS names or IPs.
The DNS names or IPs can be obtained by the worker app pod through environment variables or configuration.
Key points
Kubernetes is a powerful container orchestration platform that simplifies the management of containerized applications. It uses various key components such as nodes, clusters, and the master node to deploy and manage applications. Pods, ReplicaSets, and Deployments are essential concepts in Kubernetes, enabling the deployment, scaling, and management of application replicas.
Networking in Kubernetes is facilitated through Services, which provide connectivity, load balancing, and service discovery within the cluster. Service types like NodePort, ClusterIP, and LoadBalancer offer different ways to expose and access services both internally and externally.
Microservice architecture in Kubernetes involves deploying individual components as separate microservices. These components can communicate with each other using Services and connect to databases and other services using DNS names, IPs, or environment variables.
Overall, Kubernetes simplifies the deployment, scaling, and management of applications, allowing for efficient utilization of resources and seamless orchestration of containerized workloads. With its robust features and flexibility, Kubernetes has become a popular choice for building and managing scalable, distributed systems.