All technological notes.
| Pod Phase | Description |
|---|---|
Pending |
Since object is accepted, until one of the container is running |
Running |
Since At least one of containers is running |
Unknown |
The state of the Pod cannot be determined. Kubelet has stopped reporting. |
Finite Pod: pod that is not intended to run indefinitely| Pod Phase | Description |
|---|---|
Succeeded |
All containers complete successfully |
Failed |
At least one of the container terminates unsuccessfully |
Pod Condition
PodScheduled: Whether the pod has been scheduled to a node.Initialized: Whether the init containers have all completed.ContainersReady: Whether all containers in the pod are ready.Ready: Whether the readiness gates are all reporting that all containers are ready.| Condition Type | Description |
|---|---|
PodScheduledHas |
Whether the Pod been assigned to a node by the Scheduler |
Initialized |
Whether all Init Containers have finished successfully |
ContainersReady |
Whether all containers are in the Pod currently ready |
Ready |
Whether the Pod’s Readiness Probes are passed |
PodReadyToStartContainers |
Whether the sandbox and network are set up so the Kubelet can start pulling images |
kubectl run web --image=nginx
# pod/web created
kubectl describe pod web
# Conditions:
# Type Status
# PodScheduled True
# Initialized True
# ContainersReady True
# Ready True
# PodReadyToStartContainers True
kubectl get pod web -o yaml
# status:
# conditions:
# - type: PodScheduled
# status: "True"
# observedGeneration: 1
# lastTransitionTime: "2026-01-02T19:26:06Z"
# lastProbeTime: null
# - type: Initialized
# status: "True"
# observedGeneration: 1
# lastTransitionTime: "2026-01-02T19:26:06Z"
# lastProbeTime: null
# - type: PodReadyToStartContainers
# status: "True"
# observedGeneration: 1
# lastTransitionTime: "2026-01-03T17:28:37Z"
# lastProbeTime: null
# - type: ContainersReady
# status: "True"
# observedGeneration: 1
# lastTransitionTime: "2026-01-03T17:28:37Z"
# lastProbeTime: null
# - type: Ready
# status: "True"
# observedGeneration: 1
# lastTransitionTime: "2026-01-03T17:28:37Z"
# lastProbeTime: null
initialization stage
init containers runrun stage
regular containers of the pod runtermination stage
init containers run
Before each init container is started, its container image is pulled to the worker node
containers.imagePullPolicy field
Always:
Never:
ErrImageNeverPull eventIfNotPresent
:latest: defaults to AlwaysIfNotPresentrepeated process of init containers
All init containers must run to completion before the regular containers can start
init container terminates with an error
restart policy == Always/OnFailure
init container is restartedrestart policy == Never
init containers and the pod’s regular containers are never startedInit:Error
post-start hook error impact a containerRegular containers are created synchronously in the order they are defined in the pod’s spec.regular containers execute parallelly.
post-start hook runs asynchronously with the Regular container process
post-start hook handler blocks the creation and start of the its container.container might restart based on the restart policycontainers is performed in parallel.pre-stop hooks of the containers are all invoked at the same time
pre-stop hook blocks the shutdown of the container in which it is definedimage is pulled from the image registry, following the pod’s imagePullPolicy.
container is created.Even if a container image can’t be pulled, the other containers in the pod are started nevertheless.
main container process starts.post-start hook runs asynchronouslystartup probe started
liveness probe is startedcontainer is terminated if:
startup probe failsliveness probe failspost-start hook failsContainer restarts based on the restartPolicy
restartPolicy == Never, container remain in the Terminated statestartup hook fails + restartPolicy == Never: pod status == Completedtermination grace period:
pod.spec.terminationGracePeriodSeconds field
pre-stop hook is calledTERM signal is sent if no hook is definedprocess is still running after the termination grace period has expired, it’s terminated by force via the KILL signal.
stage when the pod object is deleted.
Terminating.the pod’s containers are terminated in parallel
pre-stop hook is not called
TERM signals are sent to containerif pre-stop hook is called,
TERM signals are sent to containerKILL signal if the deletion grace period expiresAfter all the containers in the pod have stopped running, the pod object is deleted.
containers to shut down on their own.field metadata.deletionGracePeriodSeconds
spec.terminationGracePeriodSeconds field
30sit is advisable to extend it if the application usually needs more time to shut down gracefully.
apiVersion: v1
kind: Pod
metadata:
name: kiada-ssl-shortgraceperiod
spec:
terminationGracePeriodSeconds: 50
containers:
# give the pod 10s to shut down
kubectl delete po kiada-ssl --grace-period 10
# check the log for TERM signal
kubectl logs POD_NAME -c CONTAINER_NAME -f
# demo_pod_state.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: web
name: web
spec:
containers:
- image: nginx
name: web
# terminal A:
kubectl apply -f demo_pod_state.yaml
# pod/web created
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# web 0/1 Pending 0 0s
# web 0/1 Pending 0 0s
# web 0/1 ContainerCreating 0 0s
# web 1/1 Running 0 8s
# demo_pod_state.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: web-app # updated
name: web
spec:
containers:
- image: nginx
name: web
# terminal A:
kubectl apply -f demo_pod_state.yaml
# pod/web configured
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# web 1/1 Running 0 14s
# web 1/1 Running 0 64s
# web 1/1 Running 0 64s
# web 1/1 Running 1 (5s ago) 69s
# edit: update image: nginx:1.29.4-alpine
kubectl edit pod web
# pod/web edited
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# web 1/1 Running 1 (42s ago) 106s
# terminal A:
kubectl delete -f demo_pod_state.yaml
# pod "web" deleted from default namespace
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# web 1/1 Running 1 (4m50s ago) 5m54s
# web 1/1 Terminating 1 (7m12s ago) 8m16s
# web 1/1 Terminating 1 (7m12s ago) 8m16s
# web 0/1 Completed 1 (7m13s ago) 8m17s
# web 0/1 Completed 1 8m18s
# web 0/1 Completed 1 8m18s
# web 0/1 Completed 1 8m18s
# terminal A:
kubectl run web --image=xnign
# pod/web created
kubectl delete pod web
# pod "web" deleted from default namespace
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# web 0/1 Pending 0 0s
# web 0/1 Pending 0 0s
# web 0/1 ContainerCreating 0 0s
# web 0/1 ErrImagePull 0 1s
# web 0/1 ImagePullBackOff 0 16s
# web 0/1 ErrImagePull 0 31s
# web 0/1 ImagePullBackOff 0 42s
# web 0/1 ErrImagePull 0 56s
# web 0/1 ImagePullBackOff 0 71s
# web 0/1 ErrImagePull 0 101s
# web 0/1 ImagePullBackOff 0 116s
# web 0/1 Terminating 0 2m59s
# web 0/1 Terminating 0 2m59s
# web 0/1 Terminating 0 3m
# web 0/1 ContainerStatusUnknown 0 3m1s
# web 0/1 ContainerStatusUnknown 0 3m1s
# web 0/1 ContainerStatusUnknown 0 3m1s
# ...
--restart=Never# terminal A:
kubectl run demo --image=busybox --restart=Never -- sleep 10
# pod/demo created
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# demo 0/1 Pending 0 0s
# demo 0/1 Pending 0 0s
# demo 0/1 ContainerCreating 0 0s
# demo 1/1 Running 0 3s
# demo 0/1 Completed 0 13s
# demo 0/1 Completed 0 14s
# terminal A:
kubectl get pod
# NAME READY STATUS RESTARTS AGE
# demo 0/1 Completed 0 78
kubectl delete pod demo
# pod "demo" deleted from default namespace
kubectl get pod
# No resources found in default namespace.
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# demo 0/1 Completed 0 114s
# demo 0/1 Completed 0 2m
# demo 0/1 Completed 0 2m
--restart=Never# terminal A:
kubectl run demo --image=busybox --restart=Never -- slep 10 # incoreect command
# pod/demo created
kubectl get pod
# NAME READY STATUS RESTARTS AGE
# demo 0/1 ContainerCannotRun 0 67s
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# demo 0/1 Pending 0 0s
# demo 0/1 Pending 0 0s
# demo 0/1 ContainerCreating 0 0s
# demo 0/1 ContainerCannotRun 0 3s
# demo 0/1 ContainerCannotRun 0 4s
# terminal A:
kubectl delete pod demo
# pod "demo" deleted from default namespace
kubectl get pod
# No resources found in default namespace.
# terminal B:
kubectl get pod --watch
# NAME READY STATUS RESTARTS AGE
# demo 0/1 ContainerCannotRun 0 2m42s
# demo 0/1 ContainerCannotRun 0 2m49s
# demo 0/1 ContainerCannotRun 0 2m49s