2022-06-18

Kubernetes Pod

What is Pod in Kubernetes

In Kubernetes, a Pod is the smallest deployable unit that can be created and managed. It is a group of one or more containers with shared storage/network resources, and a specification for how to run the containers. The containers in a Pod are automatically co-located and co-scheduled on the same physical or virtual machine (VM) in the cluster. They also have a shared context and can communicate with each other using localhost.

How Pods Work

Pods are designed to support multiple cooperating processes (as containers) that are relatively tightly coupled. For instance, a Pod might consist of a web server and a separate process that fetches content to be published by the web server. The containers in the Pod share an IP Address and port space, and can find each other via localhost. They can also communicate with each other using standard inter-process communications like SystemV semaphores or POSIX shared memory. Containers in different Pods have distinct IP addresses and do not share IPC namespace.

Each Pod is isolated by several kernel namespace and network spaces. This means that while processes in a Pod can see each other and communicate freely, they are isolated from processes running in other Pods.

Pod as Virtual Host

In Kubernetes, a Pod behaves like a virtual host. It is capable of running multiple containers inside it. All containers inside a single Pod share the same network namespace, which means they share the same IP address and port space. Containers within the same Pod can communicate with one another using localhost. The containers in the same Pod also share the same storage volumes, allowing them to read and write the same files.

Getting Hands-on with Pods

I'll take a practical approach to understand and work with Pods in Kubernetes. I'll be deploying a simple application to a Kubernetes cluster using Minikube.

Setting up Minikube

Minikube is a tool that allows you to run a single-node Kubernetes cluster locally on your machine. It is convenient for developers who want to experiment with Kubernetes or develop with it day-to-day.

Start Minikube by running the following command in your terminal:

bash
$ minikube start

This command creates and configures a virtual machine that runs a single-node Kubernetes cluster.

Deploying Application

Now that Minikube is running, let's deploy a simple application.

To create a Pod running helloworld application, execute the following command:

bash
$ kubectl run --image=bhargavshah86/kube-test:v0.1 --restart=Never helloworld

pod/helloworld created

Listing Pods

To see the list of running Pods, use the following command:

bash
$ kubectl get pods

NAME         READY   STATUS    RESTARTS   AGE
helloworld   1/1     Running   0          59s

Viewing Logs of a Pod

You can check the logs generated by the containers in a Pod. To check the logs of the helloworld Pod, use the following command:

bash
$ kubectl logs helloworld

2022/06/18 00:25:38 Server listening on port 8080

Inspecting Pod Metadata

To view more detailed information about the Pod, including configuration and status, use the describe command:

bash
$ kubectl describe pod helloworld

Executing Commands Inside a Running Container

Sometimes, you may need to execute a command inside a running container. You can use the kubectl exec command for this. For example, to open a shell inside the container running in the helloworld Pod, use the following command:

bash
$ kubectl exec -it helloworld sh
/usr/share/nginx/html #

Once you are done, you can type exit to leave the shell.

/usr/share/nginx/html # exit

Deleting a Pod

To delete the helloworld Pod, use the following command:

bash
$ kubectl delete pod helloworld

Configuring the Environment Variables of a Container

You can define environment variables for the container in the Pod at the time of creating the Pod. For example, let’s create a new Pod named helloworld-env and set an environment variable named TEST_ENV:

bash
$ kubectl run helloworld-env --env TEST_ENV=hello_world --image bhargavshah86/kube-test:v0.1 --restart Never

To check that the environment variable was set correctly, you can open a shell inside the container and use the env command:

bash
$ kubectl exec -it helloworld-env sh
/usr/share/nginx/html # env

PWD=/usr/share/nginx/html
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
NJS_VERSION=0.3.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_VERSION=1.16.0
TERM=xterm
PKG_RELEASE=1
HOME=/root
SHLVL=1
HOSTNAME=helloworld-env
TEST_ENV=hello_world
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443

You should see TEST_ENV=hello_world in the list of environment variables.

Type exit to leave the shell.

Changing the Host Port Mapped to the Container

You can map host port by adding --port flag.

bash
$ kubectl run --port 8080 --image bhargavshah86/kube-test:v0.1 --restart Never helloworld

Pod Networking

I will explain the inner workings of networking within a Kubernetes environment with a focus on Pod communication, the role of the Minikube environment, and exposing Pods to external networks.

Testing Access to the HelloWorld Pod from Other Pods within the Cluster

In a Kubernetes cluster, Pods can communicate with each other directly using their IP addresses. This is essential for microservices which often rely on inter-service communication.

Let’s test this by accessing our HelloWorld Pod from another Pod within the cluster.

First, create helloworld Pod and check its IP address:

bash
$ kubectl run --image gcr.io/google-samples/hello-app:1.0 --restart Never helloworld
$ kubectl get pod,svc -o wide

NAME             READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
pod/helloworld   1/1     Running   0          17s   10.244.0.11   minikube   <none>           <none>

Then, create a temporary Pod with the curl image for testing purposes:

bash
$ kubectl run --restart Never --image curlimages/curl:7.68.0 -it --rm curl sh

Now, use curl to send a request to the helloworld Pod:

/ $ curl 10.244.0.11:8080

Hello, world!
Version: 1.0.0
Hostname: helloworld
/ $ curl 10.244.0.11
curl: (7) Failed to connect to 10.244.0.11 port 80: Connection refused
/ $ curl 10.244.0.11:8080
Hello, world!
Version: 1.0.0
Hostname: helloworld

You should see the Hello, world! message response. This demonstrates that Pods within the same Kubernetes cluster can communicate with each other using their IP addresses.

Why Can’t You Connect to Pod IP from the Host OS

We cannot connect to the Pod from the host OS.

bash
$ kubectl get pods -o=jsonpath='{.items[0].status.podIP}'
$ curl $(kubectl get pods -o=jsonpath='{.items[0].status.podIP}'):8080

The above command will time out.

Minikube Environment

Minikube is a tool that helps you run a single-node Kubernetes cluster locally. It runs the cluster inside a VM. This introduces an additional layer of networking.

In Minikube, the Kubernetes cluster runs inside a VM, and this VM has its network configuration. Because of this, the host OS (e.g., MacOS, Windows) is on a different network than the Kubernetes cluster inside the VM.

The host machine has its IP range (e.g., 192.168.88.15), and the VM has a different one (e.g., 192.168.64.1). Within the VM, Kubernetes may use another IP range for Pods (e.g., 172.17.0.1). Due to these different IP ranges and networks, the host machine cannot directly access the Pod IP addresses.

Exposing Pods to External Networks

Since Pods are not directly accessible from the host machine or external networks, we need to use Kubernetes "Services" to expose them.

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!