Kubernetes: Pod basics summary

Blog: Blog Garden personal
Official documents The concept of Pod is introduced in detail.

concept

Pods are the smallest deployable units of computing that you can create and manage in Kubernetes.

In short, a Pod is a set of (or one) containers. These containers are scheduled together and regarded as a basic unit.

You can use the example test pod YML, a simple understanding of Pod:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
    - name: myapp-container
      image: busybox
      command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

establish:

kubectl create -f test-pod.yml 

View log:

[root@master-1 ~]# kubectl logs myapp-pod
Hello Kubernetes!

This is a very simple Pod sample. Its main fields are explained as follows:

  • apiVersion/kind: This is a basic field common to all resources, indicating the api version number and type.
    • apiVersion: indicates the group and version to which the resource belongs. The structure is generally < group / < version >, in which v1 is a special case, and its group is "", omitting the middle /. Generally, the core resources are v1, such as Namespace / Pod / ConfigMap, etc. Other resources have their own group and version.
    • kind: resource type, starting with uppercase.
  • metadata
    • Name: the name of the pod.
    • Labels: labels of pod.
    • Namespace: optional field. Resources in Kubernetes are divided into two categories: one belongs to namespace and the other does not. Pod belongs to namespace. If no namespace is written in yaml, it belongs to default namespace.
  • spec: the main information part of pod.
    • containers: a list, because there can be multiple container s.
    • Name: the name of this container. Multiple container names under a pod cannot conflict.
    • Image: the image information of this container.
    • Command: start the command. This is optional because the general mirror image has a default value.

Pod infrastructure

Required parameter

# The most basic yaml file of pod requires at least the following parameters
apiVersion: v1 # API version number. Note: there are multiple, and different objects may use different APIs
kind: Pod  # Object type, pod
metadata:  # metadata
  name: string # POD name
  namespace: string # The namespace to which it belongs
spec: # Specification of the resource content
  containers: # Container list
    - name: string # Container name
      image: string # Container mirroring

Labels and notes

# Put in metadata
metadata:
   labels: # Custom label name and value
     - key: value 
     - ...
    annotations: # The name and value of the custom comment
      - key: value 
      - ...

container

Common parameters
spec:
  containers:
    - name: string # Container name
# image
      image: string
      imagePullPolicy: [Always| Never | IfNotPresent] 
      # Image pull strategy. Always: always pull; Never: never pull; IfNotPresent: pull if it does not exist
# startup parameter
      command: [string] 
      # The container startup command list, which is equivalent to the ENDRYPOINT in Dockerfile, is unique. If not specified, the container itself is used. Example: ["/ bin/sh","-c"]
      args: [string] 
      # Container startup parameter list, equivalent to CMD in Dockerfile, example: ["- c"]
# Container working directory
      workingDir: string
# environment variable
      env:
        - name: string # Variable name
          value: * # Variable value
        - name: string 
          valueFrome: # Specifies the source of the value
            configMapkeyRef: # Get from ConfigMap
              name: string # Specify ConfigMap
              key: string # Specify the key in the configMap and assign it to the variable
# port  
      ports: # List of ports to be exposed
        - name: string # Port name
          containerPort: int  # Container port
          hostPort: int # The port number that the host of the container needs to listen to. The default is the same as the container IP. Generally, it can not be set
          protocol: string # The port protocol supports TCP and UDP, and the default is TCP
# mount           
      volumeMounts: # To mount a defined storage volume to a container, you need to define it through volumes
        - name: string # The name of the defined volume
          mountPath: string # Absolute path of the directory mounted in the container (less than 512 characters)
          readOnly: boolean(Boolean value) # Read only
Resource coordination

If a container only indicates limit without setting request, the value of request is equal to the limit value
The requests application range is from 0 to the maximum configuration of node nodes, while the limits application range is from requests to infinity, that is, 0 < = requests < = node allocatable, requests < = limits < = infinity.

When the CPU exceeds the limits, the pod will not be killed, but will only be limited. However, when the memory exceeds, it will be considered as a memory overflow (OOM) kill by the kernel.

# Settings for resources and requests
      resource:
        limits: # Resource constraints
          cpu: string # CPU limit. The two methods can be used to specify the number of cores directly or in m. 
                      # 0.5: equivalent to 0.5
          			  # The total CPU of a server is equal to the number of cores multiplied by 1000. If the number of cores of the machine is two, the total amount is 2000m. At this time, setting the CPU limit to 100m is equivalent to using 100 / 2000, that is, 5%. At this time, 0.5=500m
          memory: string # Memory limit.
                         # Unit: directly use positive integer to represent Byte;k;m;g;t;p
                         # Case insensitive (Kilobyte,Megabyte,Gigabyte,Terabyte,Petabyte)
         requests:  # The resource request setting, that is, the initial resource request when the container is started, is generally the same as limits, but not set
           cpu: string
           memory: string
health examination

There are three ways of health examination

  • Script or command
  • httpGet
  • tcp detection
  livenessProbe: # If the probe fails, the container will be restarted
    exec: # By executing commands or scripts in the container, if the command execution status code is 0, the detection is regarded as successful
      command: [string]
    httpGet: # Access the container IP address through http get and specify the port and path. If the response code is 2xx or 3xx, it will be regarded as successful
      path: string # Access path, that is, UPI example: / index html
      port: number # Access port
      host: string # The host name to be accessed. The default is the container IP. It can not be set
      scheme: string # The protocol used for connection. The default is http. It is optional
      httpHeaders: # Custom request header
        - name: string # name
          value: string # value
    tcpSocket: # The port is detected through tcp protocol. If the port can be connected, the detection is regarded as successful
      port: number
# Detection parameter configuration
     initialDelaySeconds: number # The initial delay in seconds, which is how long after the container is started
     timeoutSeconds: number # Response timeout
     periodSeconds: number # Detection cycle, that is, detection time interval

Storage volume

spec:
  volumes: # There are many types of storage volumes, and the following are some common types
    - name: string # Storage volume name
      emptyDir: {} # This kind of storage volume is a directory generated temporarily, which is synchronized with the pod life cycle
    - name: string 
      hostPath: # The directory where the host is mounted
        path: string   # Directory for mounting
    - name: string
      nfs:
        server: string # Service IP address
        path: string # Directory for mounting
    - name: string
      persistentVolumeClaim: # Call the persistent volume that has been created
            claimName: string # The name of the persistent volume declaration
    - name: string
      configMap: # Mount ConfigMap into container
        name: string # Name of ConfigMap
        items: # The keys and values to be called will be written to the file. You can set multiple. When called by volumeMounts, these files will be placed together in the mount directory or in a file
          - key: string
            path: string  # file name
    - name: string
      secret: # Mount the secret into the container
        secretname: string
        items:
          - key: string
            path: string

Restart scheduling

spec:
  restartPolicy: [Always|Never|OnFailure] # Restart strategy                       # OnFailure: restart only when the pod exits with a non-zero code
  nodeSelector: # According to the specified node node to which the label is scheduled, the node needs to be labeled before use
     key: value # Use the command kubectl label nodes node name key = value 
   imagePullSecrets: # Specify the account password to use when pulling the image. You need to save it to Secret first
      - name: string
   hostNetwork: false # Whether to use the host network. The default is false

Pod life cycle

The Pod follows a predefined life cycle, starting from the Pending phase. If at least one of the main containers starts normally, it enters the Running phase. Then, it depends on whether any container in the Pod ends in the Failed state and enters the Succeeded or Failed phase.

The status field of Pod is a PodStatus object, which contains a phase field.

The Phase of a Pod is a simple macro overview of where a Pod is in its life cycle. This stage is not a comprehensive summary of container or Pod States, nor is it intended to become a complete state machine.

The number and meaning of Pod stages are strictly defined. In addition to the contents listed in this document, Pod should not be assumed to have other phase values.

Here are the possible values of phase:

Value describe
Pending Pod has been accepted by Kubernetes system, but one or more containers have not been created or run. This stage includes the time to wait for the pod to be scheduled and the time to download the image through the network. If it is always in pending status, please refer to the previous article Check.
Running The Pod has been bound to a node, and all containers in the Pod have been created. At least one container is still running, or is in a startup or restart state.
Succeeded All containers in the Pod have been successfully terminated and will not be restarted.
Failed All containers in the Pod have been terminated, and at least one container has been terminated due to failure. That is, the container exits in a non-zero state or is terminated by the system.
Unknown The status of the Pod could not be obtained for some reason. This is usually because the communication with the host where the Pod is located fails.

If a node dies or loses contact with other nodes in the cluster, Kubernetes will implement a strategy to set the phase of all pods running on the lost node to Failed.

Once the scheduler assigns a Pod to a node, kubelet starts creating a container for the Pod through the container runtime. The container has three states: Waiting, Running, and Terminated.

Pod Topology Distribution constraints

In V1 In Kubernetes before 18, if you want to use Pod topology extension constraints, you must enable the evenpodspread feature gating in the API server and scheduler. Evenpodspread: enables Pod to balance scheduling between topology domains.

Topology Spread Constraints can control the distribution of fault domains in the cluster, such as regions, zones, nodes and other user-defined topology domains, so as to achieve high availability and improve resource utilization.

Example

To view and configure node labels:

[root@master-1 tmp]# kubectl get nodes --show-labels
NAME       STATUS   ROLES                  AGE    VERSION    LABELS
master-1   Ready    control-plane,master   128d   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master-1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
node-1     Ready    <none>                 128d   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-1,kubernetes.io/os=linux
node-2     Ready    <none>                 128d   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-2,kubernetes.io/os=linux
[root@master-1 tmp]# kubectl label nodes node-1 address=Hangzhou
node/node-1 labeled
[root@master-1 tmp]# kubectl label nodes node-2 address=Chengdu
node/node-2 labeled
[root@master-1 tmp]# kubectl get nodes --show-labels
NAME       STATUS   ROLES                  AGE    VERSION    LABELS
master-1   Ready    control-plane,master   128d   v1.20.11   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master-1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
node-1     Ready    <none>                 128d   v1.20.11   address=Hangzhou,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-1,kubernetes.io/os=linux
node-2     Ready    <none>                 128d   v1.20.11   address=Chengdu,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-2,kubernetes.io/os=linux

New Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: nginx

establish:

[root@master-1 test]# kubectl create -f nginx.yml 
deployment.apps/nginx-test created
[root@master-1 test]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nginx-55649fd747-h4c8z   1/1     Running   0          20s   10.16.84.136   node-1   <none>           <none>
nginx-55649fd747-ncj5l   1/1     Running   0          20s   10.16.84.135   node-1   <none>           <none>

It can be seen that two pods are distributed to the same node.

Configure distribution constraints:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx:latest
          name: nginx
      topologySpreadConstraints:
        - topologyKey: address
          maxSkew: 1
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: nginx

explain:

  • maxSkew describes the degree of uneven distribution of pod. This is the maximum allowable difference between matched pods in any two topology domains in a given topology type. It must be greater than zero. Depending on the value of whenUnsatisfiable, its semantics will be different.
    • When when unsatisfiable is equal to "DoNotSchedule", maxSkew is the difference between the number of matched pods in the target topology domain and the global minimum.
    • When when unsatisfiable is equal to "schedule anyway", the scheduler will prefer the topology domain that can reduce the deviation value.
  • topologyKey is the key of the node label. If two nodes are marked with this key and have the same label value, the scheduler treats the two nodes as being in the same topology domain. The scheduler attempts to place a balanced number of pods in each topology domain.
  • whenUnsatisfiable indicates what to do if the Pod does not meet the distribution constraints:
    • DoNotSchedule (default) tells the scheduler not to schedule.
    • The ScheduleAnyway tells the scheduler to continue scheduling and just sort the nodes according to how to minimize the deviation.
  • labelSelector is used to find a matching Pod. Pods matching this label will be counted to determine the number of pods in the corresponding topology domain.

Check that the pod has been dispatched to different node s:

[root@master-1 test]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nginx-58c948c775-h69xr   1/1     Running   0          39s   10.16.247.18   node-2   <none>           <none>
nginx-58c948c775-nlcn2   1/1     Running   0          39s   10.16.84.137   node-1   <none>           <none>

Keywords: Kubernetes cloudnative pod

Added by DeepakJ on Tue, 25 Jan 2022 17:59:34 +0200