• Home
  • Docker
  • Kubernetes
  • Java
  • Ubuntu
  • Maven
  • Big Data
  • CI
  • Install
  • Samples
  • Archived
Kubernetes | Pods (pods|po)
  1. Notes
  2. Pods (pods|po)
  3. Manifest YAML file
  4. Manage Pods
  5. List detailled inforation about a Pod
  6. Define Pods resources (CPU, RAM)
  7. Define Init Containers
  8. Define Sidecar Containers
  9. Health Checks
  10. Labels
  11. Delete Pods

  1. Notes
    Please visit these pages for more details about Pods:
    https://kubernetes.io/docs/concepts/workloads/pods/
    https://kubernetes.io/docs/tasks/manage-kubernetes-objects/imperative-command/
    https://kubernetes.io/docs/concepts/security/controlling-access/
    https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
    https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
    https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
  2. Pods (pods|po)
    Pods are the atomic units of deployment in Kubernetes.
    A Pod is a special container that defines one or more containers that can run inside of it.
    Containers, running inside a Pod, share the Pod's resources: IP address, ports, hostname, volumes, ...
    They can communicate with each other using localhost interface.

    To share resources, containers leverage Linux features: Control groups (cgroups) and kernel namespaces.
    Control groups (cgroups) allow containers to use only their assigned resources: cpu, ram, and iops.
    Kernel namespaces (Network, UTS, IPC, ...) allow containers to have their own unique and limited view of the system resources (filesystem, network interfaces, disk, ...):

    It's recommended to have only one container inside a Pod.
    But there might be use cases where it will be acceptable to have more than one container running inside a Pod. For example, it's possible to co-locate multiple containers that provide services that are tightly coupled and/or they need to share the Pod's resources.
    It's also possible to have one main container inside the Pod and add one or more sidcar containers that provide additional features to the main container (for example: logging, monitoring, ...).

    To create/deploy a Pod, you need first to create a manifest file (YAML). The manifest file describe the Pod and its components (name, image, port, ...). You can use "kubectl" (or any rest client tool) to post the manifest file to the API server If applicable, the API server verifies that the request is authenticated, validates it's authorized, and runs the admission controllers on it. The API server verifies the manifest file and, if no issues, it writes a record for that manifest in the cluster store (etcd). The scheduler will then read the record and deploy it to a healthy worker node with enough available resources.

    The same behaviour, described above, applies if you use the imperative command ("kubectl create") to create the Pod.

    You can also use imperative commands (kubectl command-line tool) to create and manage Pods.

    Here's the list of events that leads to the creation of a Pod:
    • You define a Pod in a manifest file (YAML)

    • You post the manifest file to the API server.

    • The API server validates the manifest and persist it in the cluster store (etcd) as record of intent (desired state)

    • The scheduler reads the record, converts it into a PodSpec, and schedules the PodSpec to a healthy worker node with enough available resources.

    • The kubelet (a Kubernetes agent) accepts the PodSpec and start the creation of the Pod.

    • The Pod enters the Pending state while the container runtime, on the worker node, downloads the images and starts the containers.

    • The Pod remains in the Pending state until all of its containers are created.

    • The Pod enters the running state, if its containers are created successfully.

    • The Pod enters the succeeded state, if it successfully finishes its tasks.

    • The Pod enters the failed state, if one or more container failed.

    • The Pod won't be rescheduled if it fails to start.
  3. Manifest YAML file
    The hello-busybox-pod.yaml file provides a declarative configuration of a Pod:
    The Pod's name must be a valid DNS subdomain name:
    • Maximum 253 characters.
    • The name must contain only lowercase alphanumeric characters ([a-z0-9]), minus character ('-') and period character ('.').
    • The name must start and end with an alphanumeric character.

    To deploy the hello-busybox-pod.yaml file:

    The "hello-busybox-pod.yaml" file defines the following fields:
    • The apiVersion field defines the Kubernetes API group and the Kubernetes API version.
      Its value is written as following: <api-group>/<api-version>
      Example: storage.k8s.io/v1
      The Pods are defined in the core API group, which is the default if the api-group is not set.
      So in the case of Pods, only the api version needs to be provided.

    • The kind field defines the type of the Kubernetes object to be created (Pod).

    • The metadata field defines the Pod metadata (name, labels, namespace, ...).

    • The spec field defines the containers information (name, image, command, ports, ...).

    Note: The command field can also be written as following:



    Note: Managing Pods using the Manifest Yam file (declarative) is the recommended way, but in some cases you might want to use the imperative command "kubectl create" to create a Pod.

    The following command creates and run a Pod using the busybox image and opens an interactive shell:

    -i, --stdin: Keep stdin open on the container(s) in the pod, even if nothing is attached.
    -t, --tty: Allocated a TTY for each container in the pod.

    You can use the "--dry-run" flag to print the YAML file:

    You can use the "view-last-applied" flag to print the YAML file as it was applied the last time:
    You can edit and update the definition of a kubernetes object:
  4. Manage Pods
    • To list all Pods (kubectl get pods):

    • To list detailed information about all Pods (-o wide):

    • To see the info of a specific Pod (kubectl get pod <POD-NAME>):

    • To see detailed information about a specific Pod (-o wide):

    • To monitor the status of the Pods (--watch):

      A Pod is available when the field STATUS shows Running and the field READY shows the conainers ready (1/1). If a Pod has many containers, then the READY field should show the number of all its containers

    • To run a commands in a Pod (kubectl exec):

      -- (double dash) separate the kubectl arguments from the command (and its arguments) you want to run in the Pod.

      If more than one container are running in the Pod, then the command will be executed against the first container in the Pod. To execute the command against a specific container, you need to use the --container (-c) flag and give it the name of the container:

      The --container (-c) flag applies also to init containers.

    • To login into a Pod:

      -- (double dash) separate the kubectl arguments from the command (and its arguments) you want to run in the Pod.

      The options -it opens an interactive session with the Pod's remote shell by connecting the local shell's data streams to the Pod's data streams (stdin (standard input), stdout (standard out), and stderr (standard error)).
      -i, --stdin: Keep stdin open on the container(s) in the pod, even if nothing is attached.
      -t, --tty: Allocated a TTY for each container in the pod.

      If more than one container are running in the Pod, then the command will be executed against the first container in the Pod. To login to a specific container, you need to use the --container (-c) flag and give it the name of the container:

      The --container (-c) flag applies also to init containers.

    • To print the logs of a Pod (kubectl logs):

      If more than one container are running in the Pod, then the command will be executed against the first container in the Pod (see the command: kubectl describe pod hello-busybox). To print the logs of a specific container, you need to use the --container (-c) flag and give it the name of the container:

      The --container (-c) flag applies also to init containers.

      You can use the --follow (-f) flag to continusly stream the logs in your terminal.

      You can use the --previous (-p) flag to show the logs of a previous instance of the Pod.

    • To copy files from the local VM to a Pod (kubectl cp):

      To copy files from the Pod to the local VM:

      Note that the path to the file in the Pod doesn't have the leading character '/'. This was needed to avoid this warning "tar: removing leading '/' from member names".

    • To forward a port from the local VM to a Pod (kubectl port-forward):



      You can also use a Service to forward a port, but note that it will be bound to only one Pod of the Service:
  5. List detailled inforation about a Pod
    • To print the manifest file of a specific Pod as stored in the cluster store (etcd):

      Note: The printed yaml object contains more settings than what it was defined in the original manifest file.
      Some of the settings are the default values that Kubernets gives to the missing field in the manifest file.
      Some of the settings are runtime information set by Kubernets (node IP address, Pod IP address, container info, status, ...).

      The status field provides detailed information about the different transitional states of the Pod.

    • To describe a Pod (kubectl describe pod):

      The command provides detailed information about the Pod (node IP address, Pod IP address, container info, ...) and its current state.
      It also provide the list of the events (Scheduled, Pulled, Created, Started, ...) occurred while creating and running the Pod.

  6. Define Pods resources (CPU, RAM)
    You can define the resources ("memory", "cpu") required for the containers running inside the Pod.
    You can use the field "requests" to define the minimum resources required for a container.
    You can use the field "limits" to define the maximum resources to be allocated to a container.

    The resources required by a Pod is the sum of the resources requested by all the containers of that Pod.
    Kubernetes will check if a node has available resources required by the Pod before deploying it in that node.

    The field "memory" allows you to define the memory that you would like to be allocated to the container.
    You can provide a value for the memory on kilobyte (k), Megabyte (M), Gigabyte (G).
    You can also provide a value for the memory on kibibyte (ki), Mebibytes (Mi), Gibibyte (Gi).
    Note that kilobyte is a multiplier of 1000 bytes while kibibyte is 2 to the power of 10 bytes (1024 bytes).
    Note that Megabyte is represented by the uppercase character "M".
    The lowercase character "m" represents the Milli unit (1000m = 1M).
    The OOM killer will be triggered if the application tries to allocate more than the limit defined for the container (Exit Code 137).

    The field "cpu" allows you to define the CPU core that you would like to be allocated to the container.
    You can provide a value for the the CPU cores on milicores (m).
    You can also provide a numerical value for the the CPU cores (0.5 for half a core (1024/2 = 512m), 2 for two cores (1024*2 = 2048m)).
    If the CPU usage exceds the limits, then the processes inside the container will be throttled (slowed).

    If a Pod doesn't define a limit for the memory then in theory it can use more memory if available in the node but in such case Kubernetes won't be able to claim back the extra memory used by the Pod to give it to the new Pods. If no memory left on the node, then Kubernetes will check all the Pods that are using more memory than what they requested and terminate them. Any restarted Pod will need to be scheduled on a node that has the requested memory.

    If a Pod doesn't define a limit for the CPU cores then in theory it can use more cores if available in the node but if new Pods need to be installed on that node then Kubernetes will claim back the cpu used by the Pod and tries to divide the cores on all the pods with respect to the value of the "requests" field of each Pod.


    You can define a "ResourceQuota" to set the maximum resources (requests and limits) for all the objects to be created within a namespace.

    If you try to create an object that doesn't define a requests or limits, you will get an error:

    To check the resources usage:

    You can also define a "LimitRange" to set the maximum resources (requests and limits) for all the objects of a specific type.

    You will get an error, if you try to create an object that define values for requests or limits that exceeds the values in the ResourceQuota or LimitRange.
  7. Define Init Containers
    You can define init containers to perform special tasks before the main container get created.
    All init containers need to execute and complete succefully before the main container get created.



    Note that the column READY is showing "1/1" which means that the Pod has only 1 container and it's running.

  8. Define Sidecar Containers
    You can define sidcar containers to run before the main container get created.
    All sidcar containers need to run succefully before the main container get created.



    Note that the column READY is showing "2/2" which means that two containers are running.

  9. Health Checks
    Kubernetes allow you to define probes to check the health of the Pod.
    You can define the liveness, readiness, and the startup probes.

    The startup probes ensure that the Pod complete all its tasks before Kubernetes starts monitoring its liveness and readiness.
    The liveness probes ensure that the Pod was started properly.
    The readiness probes ensure that the Pod is ready to process requests.

    If the startup probes fail then the Pod is restarted.
    The same for the liveness probes, if they fail then the Pod is restarted.
    If the readiness probes fail then the Pod is flagged as not willing to serve requests but it won't be restarted.

    Note that by default, the Pods are configured to always restart after a termination.
    This behaviour is managed by the restartPolicy field which support three settings: Always (default), OnFailure (non-zero exit status), Never.

    The probes have there settings:
    • initialDelaySeconds (default: 0): tells Kubernetes to wait the configured number of seconds before executing the first probe.

    • timeoutSeconds (default: 1): tells Kubernetes to timeout the probe if its execution last more than the configured number of seconds.

    • periodSeconds (default: 10): tells Kubernetes to execute the probe every x seconds.

    • failureThreshold (default: 3): tells Kubernetes to fail the probes check after x consecutive failures.

    • successThreshold (default: 1): tells Kubernetes to succeed the probes check after x consecutive successes (must be 1 for liveness and startup probes).

    • terminationGracePeriodSeconds (default: 30): tells Kubernetes to wait the defined number of seconds to let the Pod to terminate gracefully before forcing its termination (cannot be defined for the readiness probes).

    There are four means to check the health of the Pod using a probe:
    • exec: Execute a command inside the Pod. The probe is considered successful if the command exit with a status code of zero.

    • tcpSocket: Execute a tcp check against the Pod using the provided IP address and port. The probe is considered successful if the connection succeeds (port open).


    • httpGet: Execute an HTTP GET request against the Pod using the provided IP address, port, and path. The probe is considered successful if the response has a satus code >=200 and <<400.

    • grpc: Execute an RPC (remote procedure call) against the Pod. The probe is considered successful if the response is SERVING.

    Let's define a Pod that declares the the liveness, readiness, and the startup probes:

    Let's create the Pod:

    Let's check the Pod:
  10. Labels
    Labels are key/value pairs (strings) that can be added to Kubernetes objects to group them so it can be easy to query and identify them (i.e. selector query).

    Labels can be written using the following format: key-prefix/key-name: value

    The key-prefix is optional and must be a valid DNS subdomain name.

    The key-name is mandatory and must respect the following constraints:
    • Maximum 63 characters.
    • The name can contain alphanumeric characters ([a-zA-Z0-9]), minus character ('-'), underscore character ('_'), and period character ('.').
    • The name must start and end with an alphanumeric character.

    The label value is any string that respect the same constraints as the key-name.

    Let's define a simple Pod with a Label:

    Let's deploy the hello-labels-busybox-pod.yaml file:

    To add, update, or delete a label, you can update and apply the manifest file of the Pod. You can also use the imperative command kubectl label to add, update, or delete labels.

    To add a new label to the pod:

    To show the labels attached to the Pod:

    You can use the option "--label-columns" ("-L") to present the label names as columns in the output of the command.
    The option accepts a comma separated list of labels names. You can also specify the options multiple times (-L label1 -L label2).
    Note that the labels names are case-sensitive.

    To update a label of a pod:

    You need to use the option "--overwrite", otherwise you will get an error:
    error: 'label1-key/label1-name' already has a value (label1-value), and --overwrite is false

    To delete a label of a pod:

    To show the labels changes:

    You can use the option "--selector" ("-l") to filter Pods based on their label names.
    Note that the labels names/values are case-sensitive.
    The option supports the following operators:
    • key1=value1: Select all objects that have a label key "key1" and its value is equal to "value1".
    • key1!=value1: Select all objects that doesn't have a label key "key1" that its value is equal to "value1".
    • key1 in (value1, value2): Select all objects that have a label key "key1" and its value is equal to "value1" or "value2".
    • key1 notin (value1, value2): Select all objects that doesn't have a label key "key1" that its value is equal to "value1" or "value2".
    • key1: Select all objects that have a label key "key1".
    • !key1: Select all objects that doesn't have a label key "key1".

    Example using the "=" operator:

    Example using the "!" operator.
    Make sure to wrap the selector within single notes otherwise you will get an error (-bash: !label2: event not found).
  11. Delete Pods
    To delete a Pod: using manifest file (kubectl delete):

    To delete a Pod using its name:

    By default, the Pod takes 30 seconds to gracefully shut down before it get completely terminated. Meanwhile the pod will show the state "Terminating".< br /> To delete a Pod immediately:
© 2025  mtitek