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.

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.