Kubernetes pods in depth analysis

Kubernetes pods in depth analysis. In this article I will go deep on the pod behavior. If you want to get a high level understanding, first, please take a look at this other post.

Pods are defined using yaml files. This picture that is also on the other post is the base of what I am showing here.

Kubernetes pods
Kubernetes pods

This example I am giving is a pure theoretical example. I don’t see any value in having a CentOS container and a Debian container on a pod, except for the sake of understanding the functionality of a pod.

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: default
spec:
  containers:
  - name: container1
    image: centos:latest
    command: [ "/bin/sh", "-c", "--" ]
    args: [ "while true; do sleep 30; done;" ]
    resources:
      limits:
        memory: "200Mi"
        cpu: "1"
      requests:
        memory: "100Mi"
        cpu: "0.5"
    volumeMounts:
      - name: vol1
        mountPath: "/mountoncentos"
  - name: container2
    image: debian:latest
    command: [ "/bin/sh", "-c", "--" ]
    args: [ "while true; do sleep 30; done;" ]
    resources:
      limits:
        memory: "200Mi"
        cpu: "1"
      requests:
        memory: "100Mi"
        cpu: "0.5"
    volumeMounts:
      - name: vol1
        mountPath: "/mountondebian"
  volumes:
    - name: vol1
      persistentVolumeClaim:
        claimName: filesystempvc

As you see here, I have CPU, Memory and Disk Definitions. That is all you have to worry about since the IP Address will be provided to the pod automatically from the CIDR IP range. After we deploy this yaml file, the pod description will look like:

[root@client ~]# oc describe pod mypod
Name:         mypod
Namespace:    default
Priority:     0
Node:         worker1.ocp4.ibm.lab/192.168.122.14
Start Time:   Fri, 03 Jul 2020 14:38:12 -0400
Labels:       <none>
Annotations:  k8s.v1.cni.cncf.io/networks-status:
                [{
                    "name": "openshift-sdn",
                    "interface": "eth0",
                    "ips": [
                        "10.130.0.80"
                    ],
                    "dns": {},
                    "default-route": [
                        "10.130.0.1"
                    ]
                }]
              kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"mypod","namespace":"default"},"spec":{"containers":[{"args":["while t...
Status:       Running
IP:           10.130.0.80
IPs:
  IP:  10.130.0.80
Containers:
  container1:
    Container ID:  cri-o://b2e115d1fb8d54af07ff5efbc7e66f1f9da5f889db5fc476d0f2f9f276e522be
    Image:         centos:latest
    Image ID:      docker.io/library/centos@sha256:4062bbdd1bb0801b0aa38e0f83dece70fb7a5e9bce223423a68de2d8b784b43b
    Port:          <none>
    Host Port:     <none>
    Command:
      /bin/sh
      -c
      --
    Args:
      while true; do sleep 30; done;
    State:          Running
      Started:      Fri, 03 Jul 2020 14:38:49 -0400
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     1
      memory:  200Mi
    Requests:
      cpu:        500m
      memory:     100Mi
    Environment:  <none>
    Mounts:
      /mountoncentos from vol1 (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-kg69w (ro)
  container2:
    Container ID:  cri-o://e74a0617314d4b98a449be861a1cfa5f3230f446187aba8ea85ba8f53b77030f
    Image:         debian:latest
    Image ID:      docker.io/library/debian@sha256:20a8caca41c7dcb4fb902988198825cbb63012c0ea244ebb06dcfeab35f5866e
    Port:          <none>
    Host Port:     <none>
    Command:
      /bin/sh
      -c
      --
    Args:
      while true; do sleep 30; done;
    State:          Running
      Started:      Fri, 03 Jul 2020 14:38:53 -0400
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     1
      memory:  200Mi
    Requests:
      cpu:        500m
      memory:     100Mi
    Environment:  <none>
    Mounts:
      /mountondebian from vol1 (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-kg69w (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  vol1:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  filesystempvc
    ReadOnly:   false
  default-token-kg69w:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-kg69w
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/memory-pressure:NoSchedule
                 node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From                                       Message
  ----    ------     ----       ----                                       -------
  Normal  Scheduled  <unknown>  default-scheduler                          Successfully assigned default/mypod to worker1.ocp4.ibm.lab
  Normal  Pulling    52m        kubelet, worker1.ocp4.ibm.lab  Pulling image "centos:latest"
  Normal  Pulled     51m        kubelet, worker1.ocp4.ibm.lab  Successfully pulled image "centos:latest"
  Normal  Created    51m        kubelet, worker1.ocp4.ibm.lab  Created container container1
  Normal  Started    51m        kubelet, worker1.ocp4.ibm.lab  Started container container1
  Normal  Pulling    51m        kubelet, worker1.ocp4.ibm.lab  Pulling image "debian:latest"
  Normal  Pulled     51m        kubelet, worker1.ocp4.ibm.lab  Successfully pulled image "debian:latest"
  Normal  Created    51m        kubelet, worker1.ocp4.ibm.lab  Created container container2
  Normal  Started    51m        kubelet, worker1.ocp4.ibm.lab  Started container container2

In this case you can see the IP defined as 10.130.0.80. In the specification, the containers mounts the persistent volume claim on different mount points on both containers.

Now we will rsh into the containers. This will allow to show the containers behavior on the pod. First on the container 1 that is the CentOS. I will show the command sequence “uname -a”, “cat /etc/os-release”, “df -k” and “ip a sh”

[root@client ~]# oc rsh -c container1 mypod
sh-4.4# uname -a
Linux mypod 4.18.0-147.8.1.el8_1.ppc64le #1 SMP Wed Feb 26 04:11:20 UTC 2020 ppc64le ppc64le ppc64le GNU/Linux
sh-4.4# cat /etc/os-release
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8:server"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="8"

sh-4.4# df -k
Filesystem                                                                                                        1K-blocks      Used  Available Use% Mounted on
overlay                                                                                                           117209068  60877696   56331372  52% /
tmpfs                                                                                                                 65536         0      65536   0% /dev
tmpfs                                                                                                              66978432         0   66978432   0% /sys/fs/cgroup
shm                                                                                                                   65536         0      65536   0% /dev/shm
tmpfs                                                                                                              66978432     37760   66940672   1% /etc/hostname
ces.ocp4.gdl.stglabs.ibm.com:/ocpgpfs/provisioner/default-filesystempvc-pvc-0f8bfad1-a83d-454d-a51b-210cc157798f 2016583680 338072576 1678511104  17% /mountoncentos
/dev/mapper/coreos-luks-root-nocrypt                                                                              117209068  60877696   56331372  52% /etc/hosts
tmpfs                                                                                                              66978432       256   66978176   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                                                                                                              66978432         0   66978432   0% /proc/scsi
tmpfs                                                                                                              66978432         0   66978432   0% /sys/firmware
sh-4.4# ip a sh
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0@if90: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    link/ether 0a:58:0a:82:00:50 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.130.0.80/23 brd 10.130.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::7c4b:41ff:fe66:d8a5/64 scope link
       valid_lft forever preferred_lft forever
sh-4.4# exit
exit

You can see the IP 10.130.0.80 on eth0@if90. The PVC is mounted on /mountoncentos like we specified on the pod definition and you also see the os-release pointing to a CentOS. Then, now, I will run the same commands on the container2.

[root@client ~]# oc rsh -c container2 mypod
# uname -a
Linux mypod 4.18.0-147.8.1.el8_1.ppc64le #1 SMP Wed Feb 26 04:11:20 UTC 2020 ppc64le GNU/Linux
# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
# df -k
Filesystem                                                             1K-blocks      Used          Available     Use%  Mounted on
overlay                                                                  117209068   60877756   56331312   52%   /
tmpfs                                                                    65536          0                65536        0%    /dev
tmpfs                                                                    66978432     0                66978432  0%    /sys/fs/cgroup
shm                                                                      65536         0      65536   0% /dev/shm
tmpfs                                                                    66978432     37760   66940672   1% /etc/hostname
ces.ocp4.gdl.stglabs.ibm.com:/ocpgpfs/provisioner/default-filesystempvc-pvc-0f8bfad1-a83d-454d-a51b-210cc157798f 2016583680 338072576 1678511104  17% /mountondebian
/dev/mapper/coreos-luks-root-nocrypt                    117209068  60877756   56331312  52% /etc/hosts
tmpfs                                                                   66978432       256   66978176   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                                                                   66978432         0   66978432   0% /proc/scsi
tmpfs                                                                   66978432         0   66978432   0% /sys/firmware
# ip a sh
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0@if90: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    link/ether 0a:58:0a:82:00:50 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.130.0.80/23 brd 10.130.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::7c4b:41ff:fe66:d8a5/64 scope link
       valid_lft forever preferred_lft forever
#

As you can see, the container number2 has the same IP address. This is so because both containers are getting it from the pod. Like we specified at the pod definition, the mount point mounts on /mountondebian.

Kubernetes pods in depth – behavior between containers

In this part I will show the behavior of the pod. First let’s write on the CentOS container.

sh-4.4# ls -la /mountoncentos
total 1
drwxrwxrwx. 2   99   99 4096 Jul  3 21:01 .
drwxr-xr-x. 1 root root   50 Jul  3 18:38 ..
sh-4.4# touch /mountoncentos/writtenfromcentos
sh-4.4# ls -lai /mountoncentos
total 1
   137941 drwxrwxrwx. 2   99   99 4096 Jul  3 21:01 .
318826592 drwxr-xr-x. 1 root root   50 Jul  3 18:38 ..
   357287 -rw-r--r--. 1   99   99    0 Jul  3 21:01 writtenfromcentos

Now we check the result on the debian container and also create a file.

# ls -lai /mountondebian
total 1
  137941 drwxrwxrwx. 2   99   99 4096 Jul  3 21:01 .
14897785 drwxr-xr-x. 1 root root  116 Jul  3 18:38 ..
  357287 -rw-r--r--. 1   99   99    0 Jul  3 21:01 writtenfromcentos
# touch /mountondebian/writtenfromdebian
# ls -lai /mountondebian
total 1
  137941 drwxrwxrwx. 2   99   99 4096 Jul  3 21:06 .
14897785 drwxr-xr-x. 1 root root  116 Jul  3 18:38 ..
  357287 -rw-r--r--. 1   99   99    0 Jul  3 21:01 writtenfromcentos
  357281 -rw-r--r--. 1   99   99    0 Jul  3 21:06 writtenfromdebian
#

You can see we can read and write on both containers on the volume. This behavior is true, even for Read Write Once volumes (RWO). This example show that this is the case here:

[root@client ~]# oc get pvc
NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
filesystempvc   Bound    pvc-0f8bfad1-a83d-454d-a51b-210cc157798f   10Gi       RWO            managed-nfs-storage   5d8h
[root@client ~]#

Check back the site, I will post an in depth analysis of Persistent Volumes and Persistent Volume claims next week to explain what this means.