Table of contents
In this blog, I am going to discuss Kubernetes Networking: Services, Ingress, Network Policies, DNS, and CNI (Container Network Interface) plugins.
I am getting started with the 7-day #KubeWeek challenge by Shubham Londhe. #TrainWithShubham #KubeWeekChallenge #Day2.
Kubernetes Networking
Kubernetes networking is the process of enabling communication between the various components of a Kubernetes cluster. It involves configuring networking resources such as pods, services, and ingress to allow traffic to flow between them.
Kubernetes has fundamental requirements for networking implementations
Pods should be able to communicate with other pods on other nodes also without NAT.
Agents on the node should be able to communicate with all the pods on that node.
In Kubernetes, each pod gets its own IP address, and services act as a stable endpoint for accessing a set of pods. This allows for load balancing and automatic scaling of application traffic.
In addition, Kubernetes provides network policies that allow for fine-grained control over traffic flow between pods.
Kubernetes Networking addresses the four concerns
Pod-to-Pod Communication: In a Kubernetes cluster, each Pod is assigned a unique IP address for communication with other Pods in the same cluster. But these Pod IP addresses are not visible outside the cluster. To enable communication between pods, K8s provides a virtual network overlay to allow communication irrespective of the pods' location in the cluster.
Pod-to-Service Communication: Kubernetes Services provide a stable IP address and DNS name for a set of pods, allowing clients to access the pods via the service. To enable pod-to-service communication, Kubernetes uses the IP address and port mapping to route traffic from the service to the pods that back it.
External-to-Service Communication: Kubernetes Services can be exposed externally, allowing clients outside the cluster to access them. This requires setting up an ingress controller and a load balancer to route external traffic to the appropriate service.
Network Security: Network policies allow administrators to specify which pods can communicate with each other and which ports they can use. This helps to prevent unauthorized access and ensures that traffic flows only where it is needed.
The network model is implemented by the Container Runtime on each node. The most common container runtimes use Container Network Interface(CNI) plugins to manage their network and security capabilities. Some popular network plugins for Kubernetes include Calico, Flannel, and Weave Net.
Pods
In Kubernetes, a pod is the smallest deployable unit that can be created, scheduled, and managed.
One of the key benefits of using pods is that they provide a layer of abstraction between the application and the underlying infrastructure. This allows developers to focus on the application logic without worrying about the underlying details of the infrastructure. Pods are a fundamental building block in Kubernetes and are used to deploy and manage containers in a way that is scalable, portable, and flexible.
Pods are the encapsulation of containers. K8s uses pods to deploy, as it can't deploy the containers deploy.
Replica Sets
A ReplicaSet is responsible for maintaining a set of identical pods, ensuring that the desired number of replicas is always available. Replica sets help in auto-scaling and load balancing.
When a pod fails, Replica sets automatically create a new replica to replace it.
A ReplicaSet is a way to ensure that a specified number of replicas of a pod are running at any given time.
Deployments
Deployments allow users to define the desired state of their application and manage updates to the application over time.
When a Deployment is created, it creates a ReplicaSet to manage the desired number of replicas of the application. The ReplicaSet then creates and manages the actual pods that run the application.
Deployments provide many benefits like Rolling updates, rollbacks, scaling, etc.
Services
A Service in Kubernetes is a method for exposing a network application that is running as one or more Pods in the cluster. Services can be used to provide internal or external connectivity to Pods. A Service has a stable IP address and DNS name, and it provides a single entry point for accessing a set of pods.
Services can be exposed externally by using a Kubernetes Ingress controller and a load balancer. In simple terms, Services help in connecting our applications with other applications/databases, etc.
Types of services in Kubernetes:
ClusterIP Service
NodePort Service
LoadBalancer Service
ExternalName Service (This type of service is used to provide DNS aliases to external services)
Headless Service (This service type is used for stateful sets where each pod has a unique identity)
Ingress (This is not a service type per se, but a way to expose HTTP and HTTPS services to the outside world)
We will discuss a few of the above-mentioned services.
ClusterIP Service
This is the default service type in Kubernetes. It creates a virtual IP address within the cluster to access the pods that are part of the service.
ClusterIP services expose a set of pods in a K8s cluster to the other pods in the same cluster using a virtual IP address.
A common practical use case for ClusterIP service would be when a web application consists of a backend API service and a frontend service. The frontend service can access the backend API service which can be exposed as a ClusterIP service. The backend pods are not directly accessible from outside the Kubernetes cluster, but they can be accessed by the frontend pods that are running in the same cluster.
So, the ClusterIP will provide access to an application within a Kubernetes cluster but without access from the world, and will use an IP from the cluster’s IP pool and will be accessible via a DNS name in the cluster’s scope.
Cluster IP Service can be created using the following YAML file:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
In this example: apiVersion
specifies the Kubernetes API version to use (v1 in this case). kind
specifies the kind of object to create (Service in this case). metadata
specifies the name of the service. spec
specifies the service's specifications. selector
specifies the labels used to select the pods that the service will load balance traffic to. In this case, it selects pods with the app: my-app
label. ports
specifies the ports that the service will listen on. In this case, it listens on port 80 and forwards traffic to port 8080 on the selected pods. type
specifies the type of service. In this case, it is ClusterIP
.
NodePort Service
A NodePort service is a type of Kubernetes service that allows access to a set of pods running on a cluster from outside the cluster. It exposes the pods to the outside world by opening a specific port on all the nodes of the cluster.
This type of service exposes the container to the outside world by mapping a static port on the worker node(s) to the pod. This is useful for testing or accessing a service from outside the cluster.
When a NodePort is created, K8s assigns a random port number (between 30000 and 32767 by default) on each node in the cluster. The service can then be accessed using the IP address of any node in the cluster and the assigned port number.
The NodePort type is: tied to a specific host like ЕС2, if the host isn’t available from the world – then such a Service will not provide external access to pods, will use an IP from a provider’s pool, for example, AWS VPC CIDR, and will provide access to pods only on the same Worker Node.
A practical example is, NodePort Service can be used to expose a web application to the internet.
Here's an example YAML manifest for creating a NodePort service:
apiVersion: v1
kind: Service
metadata:
name: web-frontend
spec:
type: NodePort
selector:
app: web-frontend
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 30000
This YAML manifest creates a NodePort service named "web-frontend" and assigns it to the pods with the label "app: web-frontend". The service listens on port 80 and forwards traffic to the pods on port 8080. It also assigns the NodePort service to port 30000 on each node in the cluster.
LoadBalancer Service
A LoadBalancer service is a type of Kubernetes service that provides external network access to a set of pods running on a cluster. It creates a load balancer that distributes incoming traffic across multiple backend pods, providing scalability and high availability for the application.
When you create a LoadBalancer service, Kubernetes creates a cloud load balancer (if you are running on a cloud provider) or a software load balancer (if you are running on-premises) that distributes traffic across the pods in the service. The load balancer provides a stable IP address that external clients can use to connect to the service.
So, the LoadBalancer Service type will provide external access to pods, will provide a basic load-balancing to pods on different EC2, will give the ability to terminate SSL/TLS sessions, and doesn’t support level-7 routing.
It can be used to distribute traffic across a set of pods running a web application or a backend API service, for example.
Here's an example YAML manifest for creating a LoadBalancer service:
apiVersion: v1
kind: Service
metadata:
name: web-loadbalancer
spec:
type: LoadBalancer
selector:
app: web
ports:
- name: http
port: 80
targetPort: 8080
This YAML manifest creates a LoadBalancer service named "web-loadbalancer" and assigns it to the pods with the label "app: web". The service listens on port 80 and forwards traffic to the pods on port 8080.
Ingress
In Kubernetes, an Ingress is an API object that provides a way to manage external access to services running in a cluster. An Ingress allows you to configure rules for routing traffic from external sources to your services based on the URL path or hostname. In other words: Ingress isn’t a dedicated Service – it just describes a set of rules for the Kubernetes Ingress Controller to create a Load Balancer, its Listeners, and routing rules for them.
With Ingress, multiple rules can be defined for accessing different services within the cluster using a single IP address or domain name.
An example of how Ingress can be used: Let's say you have two services running in your Kubernetes cluster, a frontend service and a backend service. The frontend service serves the user interface, while the backend service handles API requests. To provide external access to these services, you can create an Ingress that routes traffic based on the URL path. For example, you can configure the Ingress to route requests to "/api" to the backend service and requests to "/" to the frontend service.
An Ingress can be created using the below YAML manifest:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: backend-service
port:
name: http
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
name: http
This YAML manifest creates an Ingress named "my-ingress" and defines two rules for routing traffic. The first rule routes requests to "example.com/api" to the backend service and the second rule routes requests to "example.com/" to the frontend service.
Network Policies
In Kubernetes, Network Policies are used to control network traffic to and from pods in a cluster. Network Policies allow defining rules that specify how traffic should flow within a cluster, which can help to improve security and ensure that applications are properly isolated.
Network Policies are not enforced by default in Kubernetes. To enable Network Policy enforcement, a CNI plugin that supports Network Policies must be installed in the cluster, such as Calico or Cilium.
Below is an example of a YAML manifest to create Network Policies:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-network-policy
spec:
podSelector:
matchLabels:
app: my-app
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-app
ports:
- protocol: TCP
port: 8080
In this YAML file, my-network-policy
is the name of the NetworkPolicy, my-app
is the label selector for the pods that will have this policy applied, Ingress
specifies that this policy applies to incoming traffic, and other-app
is the label selector for the pods that are allowed to access my-app
pods over TCP port 8080.
DNS
In Kubernetes, DNS (Domain Name System) is used to provide name resolution services for the services running within a cluster. DNS allows services to discover each other and communicate with each other using their domain names, rather than their IP addresses.
DNS Service is applicable to Services, Pods, Endpoints, and Nodes. Kubernetes has a built-in DNS (Domain Name System) service that is automatically deployed when the cluster is set up.
Container Network Interface (CNI) Plugins
Container Network Interface is a standard interface for configuring network interfaces in Linux containers, including those used by Kubernetes. In Kubernetes, the CNI interface is used by the kubelet, which is responsible for managing the networking for pods.
When a pod is created, the kubelet invokes the CNI plugin to create a network interface for the pod. CNI plugins are used to implement this interface and provide networking capabilities to containers running on a host. The CNI plugin sets up the network configuration for the pod, including IP addresses, routes, and DNS settings.
Some popular CNI plugins include Calico, Flannel, Weave Net, and Cilium.
CNI Plugins provide many networking capabilities like IP address management and allocation, Network isolation and segmentation, Encryption and authentication, Load balancing, service discovery, etc.
In conclusion, networking is a critical aspect of Kubernetes, as it enables communication between pods, services, and other resources within the cluster. Kubernetes provides a flexible and extensible networking model, with several options available for configuring networking within the cluster.
To help me improve my blog and correct my mistakes, I am available on LinkedIn as Sneha K S. Do reach me and I am open to suggestions and corrections.