In this article I will show how pods works in K8S. We will started from defining yaml manifests, next I will described simply operations related to pods control and debuging. At last I will show practical example of pod based on Nginx & Ubuntu containers. Let’s go!
# YAML Manifests
manual usage by terminal is very problematic, you can define manifest file like for kubernetes.docker-compose.yml
yaml manifests must have three fields like manifests:apiVersion`, `kind`, `metadata`. We can deploy pod `nginx` with `nginx-container`, like in previous terminal example, but using `yml
./example/first.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: nginx:1.17
for use this file, execute this command:
kubectl apply -f ./example/first.yml
you can check container / pod status:
kubectl get pods
you can see more details about this pod:
kubectl describe pod nginx
you can see more detailed yml manifest (defined inside kubernetes):
kubectl edit pod nginx
it shows default defined fields, who is not overrided by manifest../example/first.yml` file. you can also edit this file, and patches will be integrated before. You can do that on every kubernetes object defined in custom `yml
Kubernetes pods are placed in phisical nodes which are invoke some pods. you can show nodes with this command (on minikube it not needed because of minikube is an container with dind (docker inside docker) privilege, it allow minikube to imitation of Kubernetes environment):
kubectl get nodes
for show pods:
kubectl get po
# OR
kubectl get pods
# OR get hidden pods
kubectl get po -A
run pod named as container:nginx` with `nginx
kubectl run nginx --image=nginx --restart=Never
flag must be exist in this command becouse of kubernetes specifics.--restart
details of pod you can get from command:
kubectl describe pod nginx
this command shows events in this pod, like that:
Name: nginx
Namespace: default
Priority: 0
Service Account: default
Node: minikube/192.168.49.2
Start Time: Thu, 23 Mar 2023 16:05:35 +0100
Labels: run=nginx
Annotations: <none>
Status: Running
IP: 10.244.0.8
IPs:
IP: 10.244.0.8
Containers:
nginx:
Container ID: docker://cc9f969ac872a6b2eb9acded0f5c4036bdfda43d72fc1bae759d9efc7afa8e2b
Image: nginx
Image ID: docker-pullable://nginx@sha256:5bf62196c1ce39936ebdbce511127c57c06a944c51da2aef7fd27f4793cce239
Port: <none>
Host Port: <none>
State: Running
Started: Thu, 23 Mar 2023 16:05:57 +0100
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-5m8wf (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-5m8wf:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 69s default-scheduler Successfully assigned default/nginx to minikube
Normal Pulling 68s kubelet Pulling image "nginx"
Normal Pulled 47s kubelet Successfully pulled image "nginx" in 21.038861796s (21.038947282s including waiting)
Normal Created 47s kubelet Created container nginx
Normal Started 47s kubelet Started container nginx
you can also log in itself and check containers inside:minikube
minikube ssh
docker ps
it shows every container without splitting by pods.
at last we can down pod, like that:
kubectl delete pod nginx
# Exec inside containers
for test it, run:
kubectl apply -f ./ubuntu.yml
you can copy manifest of mentioned file:
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- name: ubuntu-container
image: ubuntu:18.04
command: [ "sleep", "inf" ]
its simmilar to , as you can see:docker exec -it <container> <command>
kubectl exec <pod> -- <command>
kubectl exec ubuntu -- ls
kubectl exec ubuntu -- ps aux # show all container processes
you can also run interactive exec mode, like that:
kubectl exec -it ubuntu -- /bin/bash
if you have more containers in pod, you can define specific container like that:
kubectl exec -c ubuntu-container -it ubuntu -- /bin/bash
by default, command without manifest-c` flag do exec on first defined container in `yml
# Get container logs
for test it, run:
kubectl apply -f ./example/logs.yml
when pod has only one container, this command will worked:
kubectl logs logs-learning
but on this case is not working, try this:
kubectl logs logs-learning -c nginx-container
we must define container name with -c flag (c means container name – DNS).
# Test Nginx logs and Ubuntu -> How POD works
for first we need IP for test connection between nginx & ubuntu. You can get IP from kubectl describe po logs-learning:
[...]
Annotations: <none>
Status: Running
IP: 10.244.0.14
[...]
let’s login into ubuntu-container inside logs-learning pod:
kubectl exec -c ubuntu-container -it logs-learning -- /bin/bash
let’s update package repo sources && install curl for test nginx connection:
apt update && apt install curl
and let’s check connection, like that:
curl http://10.244.0.14:80
you should get this response:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@logs-learning:/# curl http://10.244.0.14:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
better way of usage is using DNS instead IP. when we allow containers to port sharing, it will be share on pod address on defined port:
[...]
- name: nginx-container
image: nginx
ports:
- containerPort: 80
[...]
it means the port 80 of logs-learning pod is reserved for nginx-container:80, and you can get access (from ubuntu-container) like that:
curl http://logs-learning:80
everything works fine becouse this address replaced default IP of pod thanks inside kubernetes-pod DNS. connection through 127.0.0.1 / localhost is also works fine, like previus example with DNS.
check nginx logs with command:kubectl logs logs-learning -c nginx-container
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/03/23 16:14:53 [notice] 1#1: using the "epoll" event method
2023/03/23 16:14:53 [notice] 1#1: nginx/1.23.3
2023/03/23 16:14:53 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2023/03/23 16:14:53 [notice] 1#1: OS: Linux 6.1.19-1-MANJARO
2023/03/23 16:14:53 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/03/23 16:14:53 [notice] 1#1: start worker processes
2023/03/23 16:14:53 [notice] 1#1: start worker process 30
2023/03/23 16:14:53 [notice] 1#1: start worker process 31
2023/03/23 16:14:53 [notice] 1#1: start worker process 32
10.244.0.14 - - [23/Mar/2023:16:32:40 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.58.0" "-"
10.244.0.14 - - [23/Mar/2023:16:34:38 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.58.0" "-"
10.244.0.14 - - [23/Mar/2023:16:36:54 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.58.0" "-"
10.244.0.14 - - [23/Mar/2023:16:41:27 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.58.0" "-"
as you can see, everything works fine. you can get logs in live mode, just add -f flag on end of last command:
kubectl logs logs-learning -c nginx-container -f
pod is an network layer group who shares networkspace for containers inside. It means that the behaviour of pod (from network view) is really simmilar to virtual machine (VM) who hosted a lot of applications on one IP / DNS. Pod just hosts docker containers like VM hosts installed applications (or docker-compose / docker containers).
# Fundamentals
## Theory
on single Kubernetes cluster you can initialize:
- no more than 5000 nodes
- no more than 150000 total pods
- no more than 300000 total containers
- no more than 100 pods per node





