#K8S #Pods

#K8S #Pods


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 docker-compose.yml for kubernetes.

yaml manifests must have three fields like apiVersion`, `kind`, `metadata`. We can deploy pod `nginx` with `nginx-container`, like in previous terminal example, but using `yml manifests:

./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 ./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 manifest.

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 nginx` with `nginx container:

kubectl run nginx --image=nginx --restart=Never

--restart flag must be exist in this command becouse of kubernetes specifics.

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 minikube itself and check containers inside:

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 docker exec -it <container> <command>, as you can see:

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 -c` flag do exec on first defined container in `yml manifest

# 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 kubectl logs logs-learning -c nginx-container command:

/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
Author
  • TBS093A 00x097

    DevOps Engineer & Python Developer

    Big fan of automation, workflow patterns, knowledge sharing and all defined experiments.


Leave a Reply

Your email address will not be published. Required fields are marked *

Latest posts

DONATions

BTC: bc1q77txutxfg54a7x06u0nzy8cyemz7qldh2lzntx

ETH: 0x2F7AEF7cdd204CD293bBD0f09E1dEF5dd0308Ba6