Practical Getting Started 1Pod Introduction

Pod introduction

Pod structure

Each Pod can contain one or more containers, which can be divided into two categories:

  • The number of containers where user programs reside can be large or small

  • The Pause container, which is a root container that every Pod will have, has two functions:

    • It can be used as a basis to evaluate the health status of the entire Pod

    • You can set the Ip address on the root container, and other containers have this Ip (Pod IP) to achieve network communication within the Pod

      here is Pod internal communications, Pod The communication between them is realized by virtual two-layer network technology. Our current environment uses Flannel
      
Pod definition

The following is the resource list of Pod:

apiVersion: v1     #Mandatory, version number, such as v1
kind: Pod         #Required, resource type, such as Pod
metadata:         #required, metadata
  name: string     #Required, Pod name
  namespace: string  #The namespace that the Pod belongs to, the default is "default"
  labels:           #Custom label list
    - name: string                 
spec:  #Mandatory, the detailed definition of the container in the Pod
  containers:  #Required, list of containers in the Pod
  - name: string   #Required, container name
    image: string  #Required, the image name of the container
    imagePullPolicy: [ Always|Never|IfNotPresent ]  #Strategy for obtaining mirrors 
    command: [string]   #The list of start commands for the container, if not specified, use the start command used when packaging
    args: [string]      #The container's startup command parameter list
    workingDir: string  #The working directory of the container
    volumeMounts:       #Storage volume configuration mounted inside the container
    - name: string      #To refer to the name of the shared storage volume defined by the pod, the volume name defined in the volumes[] section is required
      mountPath: string #The absolute path of the storage volume to mount in the container, which should be less than 512 characters
      readOnly: boolean #Is it in read-only mode
    ports: #List of port library numbers that need to be exposed
    - name: string        #port name
      containerPort: int  #The port number that the container needs to listen on
      hostPort: int       #The port number that the host where the container is located needs to listen to, which is the same as the Container by default
      protocol: string    #Port protocol, support TCP and UDP, default TCP
    env:   #A list of environment variables that need to be set before the container runs
    - name: string  #environment variable name
      value: string #the value of the environment variable
    resources: #Resource Limits and Request Settings
      limits:  #Resource limit settings
        cpu: string     #Cpu limit, the unit is the number of core s, will be used for docker run --cpu-shares parameter
        memory: string  #Memory limit, the unit can be Mib/Gib, will be used for docker run --memory parameter
      requests: #Settings for Resource Requests
        cpu: string    #Cpu request, the initial available number of containers started
        memory: string #Memory request, the initial available amount of container startup
    lifecycle: #life cycle hook
        postStart: #Execute this hook immediately after the container starts. If the execution fails, it will restart according to the restart policy
        preStop: #Execute this hook before the container terminates, regardless of the result, the container will terminate
    livenessProbe:  #For the health check settings of each container in the Pod, the container will be automatically restarted after several times of no response to the detection
      exec:         #Set the inspection mode in the Pod container to exec mode
        command: [string]  #The command or script that needs to be formulated in exec mode
      httpGet:       #To set the health check method of each container in the Pod to HttpGet, you need to specify the Path and port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #Set the health check mode of each container in the Pod to tcpSocket mode
         port: number
       initialDelaySeconds: 0       #The first detection time after the container is started, in seconds
       timeoutSeconds: 0          #The timeout for waiting for a response to the container health check probe, in seconds, defaults to 1 second
       periodSeconds: 0           #Periodic detection time setting for container monitoring checks, in seconds, once every 10 seconds by default
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged: false
  restartPolicy: [Always | Never | OnFailure]  #Pod restart strategy
  nodeName: <string> #Setting NodeName means scheduling the Pod to the node node specified to the name
  nodeSelector: obeject #Setting NodeSelector means scheduling the Pod to the node containing this label
  imagePullSecrets: #The secret name used when pulling the image, specified in key:secretkey format
  - name: string
  hostNetwork: false   #Whether to use the host network mode, the default is false, if set to true, it means to use the host network
  volumes:   #Define a list of shared storage volumes on the pod
  - name: string    #Shared storage volume name (there are many types of volumes)
    emptyDir: {}       #A storage volume of type emtyDir, a temporary directory with the same lifecycle as the Pod. is null
    hostPath: string   #A storage volume of type hostPath, indicating the directory where the host where the Pod is mounted
      path: string                #The directory of the host where the Pod is located will be used for the mount directory during the same period
    secret:          #A storage volume of type secret, mount the cluster and the defined secret object into the container
      scretname: string  
      items:     
      - key: string
        path: string
    configMap:         #A storage volume of type configMap, which mounts a predefined configMap object into the container
      name: string
      items:
      - key: string
        path: string
#hint:
#   Here, one command can be used to view the configurable items of each resource
#   kubectl explain resource type View the configurable first-level attributes of a resource
#   kubectl explain resource type.property View the subproperties of the property
[root@k8s-master01 ~]# kubectl explain pod
KIND:     Pod
VERSION:  v1
FIELDS:
   apiVersion   <string>
   kind <string>
   metadata     <Object>
   spec <Object>
   status       <Object>

[root@k8s-master01 ~]# kubectl explain pod.metadata
KIND:     Pod
VERSION:  v1
RESOURCE: metadata <Object>
FIELDS:
   annotations  <map[string]string>
   clusterName  <string>
   creationTimestamp    <string>
   deletionGracePeriodSeconds   <integer>
   deletionTimestamp    <string>
   finalizers   <[]string>
   generateName <string>
   generation   <integer>
   labels       <map[string]string>
   managedFields        <[]Object>
   name <string>
   namespace    <string>
   ownerReferences      <[]Object>
   resourceVersion      <string>
   selfLink     <string>
   uid  <string>

In kubernetes, the first-level attributes of basically all resources are the same, mainly including 5 parts:

  • apiVersion version, defined internally by kubernetes, the version number must be queried with kubectl api-versions
  • kind type, defined internally by kubernetes, the version number must be queried with kubectl api-resources
  • metadata Metadata, mainly resource identification and description, commonly used are name, namespace, labels, etc.
  • spec description, which is the most important part of the configuration, contains detailed descriptions of various resource configurations
  • status status information, the content inside does not need to be defined, it is automatically generated by kubernetes

Among the above attributes, spec is the focus of the next research, continue to look at its common sub-attributes:

  • containers <[]Object> container list, used to define the details of the container
  • nodeName dispatches the pod to the specified Node node according to the value of nodeName
  • nodeSelector <map[]> According to the information defined in NodeSelector, select to schedule the Pod to the Node containing these label s
  • hostNetwork Whether to use the host network mode, the default is false, if set to true, it means to use the host network
  • volumes <[]Object> Storage volume, used to define the storage information hung on the Pod
  • restartPolicy Restart strategy, indicating the processing strategy of the Pod when it encounters a failure

Pod configuration

This section mainly studies the pod.spec.containers property, which is also the most critical configuration in the pod configuration.

[root@k8s-master01 ~]# kubectl explain pod.spec.containers
KIND:     Pod
VERSION:  v1
RESOURCE: containers <[]Object>   # Array, representing multiple containers
FIELDS:
   name  <string>     # container name
   image <string>     # The mirror address required by the container
   imagePullPolicy  <string> # Mirror pull strategy 
   command  <[]string> # The list of start commands for the container, if not specified, use the start command used when packaging
   args     <[]string> # A list of parameters required by the container's start command
   env      <[]Object> # Configuration of container environment variables
   ports    <[]Object>     # A list of port numbers that the container needs to expose
   resources <Object>      # Settings for resource limits and resource requests
basic configuration

Create a pod-base.yaml file with the following content:

apiVersion: v1
kind: Pod
metadata:
  name: pod-base
  namespace: dev
  labels:
    user: heima
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  - name: busybox
    image: busybox:1.30

The configuration of a relatively simple Pod is defined above, which contains two containers:

  • nginx: Created with the nginx image of version 1.17.1, (nginx is a lightweight web container)
  • busybox: Created with the busybox image version 1.30, (busybox is a small collection of linux commands)
# Create pods
[root@k8s-master01 pod]# kubectl apply -f pod-base.yaml
pod/pod-base created

# View Pod Status
# READY 1/2 : Indicates that there are 2 containers in the current Pod, 1 of which is ready and 1 is not ready
# RESTARTS : The number of restarts, since 1 container failed, the Pod has been restarting trying to recover it
[root@k8s-master01 pod]# kubectl get pod -n dev
NAME       READY   STATUS    RESTARTS   AGE
pod-base   1/2     Running   4          95s

# You can view the internal details through describe
# At this point, a basic Pod is running, although it has temporary problems
[root@k8s-master01 pod]# kubectl describe pod pod-base -n dev
mirror pull

Create a pod-imagepullpolicy.yaml file with the following content:

apiVersion: v1
kind: Pod
metadata:
  name: pod-imagepullpolicy
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Never # Used to set the image pull strategy
  - name: busybox
    image: busybox:1.30

imagePullPolicy, used to set the image pull policy, kubernetes supports configuration of three pull policies:

  • Always: Always pull the image from the remote warehouse (always download remotely)
  • IfNotPresent: If there is a local mirror, use the local mirror, if there is no local mirror, pull the mirror from the remote warehouse (if there is a local mirror, if there is no local remote download)
  • Never: Only use the local image, never go to the remote warehouse to pull it, and report an error if there is no local one (always use the local one)

Description of default values:

If the image tag is a specific version number, the default policy is: IfNotPresent

If the image tag is: latest (final version), the default policy is always

# Create pods
[root@k8s-master01 pod]# kubectl create -f pod-imagepullpolicy.yaml
pod/pod-imagepullpolicy created

# View Pod Details
# At this point, it is obvious that the nginx image has a step of Pulling image "nginx:1.17.1"
[root@k8s-master01 pod]# kubectl describe pod pod-imagepullpolicy -n dev
......
Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  <unknown>         default-scheduler  Successfully assigned dev/pod-imagePullPolicy to node1
  Normal   Pulling    32s               kubelet, node1     Pulling image "nginx:1.17.1"
  Normal   Pulled     26s               kubelet, node1     Successfully pulled image "nginx:1.17.1"
  Normal   Created    26s               kubelet, node1     Created container nginx
  Normal   Started    25s               kubelet, node1     Started container nginx
  Normal   Pulled     7s (x3 over 25s)  kubelet, node1     Container image "busybox:1.30" already present on machine
  Normal   Created    7s (x3 over 25s)  kubelet, node1     Created container busybox
  Normal   Started    7s (x3 over 25s)  kubelet, node1     Started container busybox
start command

In the previous case, there has been a problem that has not been resolved, that is, the busybox container has not been successfully run, so what caused the failure of this container?

It turns out that busybox is not a program, but a collection of tools. After the kubernetes cluster is started and managed, it will automatically shut down. The solution is to keep it running, which uses the command configuration.

Create a pod-command.yaml file with the following content:

apiVersion: v1
kind: Pod
metadata:
  name: pod-command
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]

command, used to run a command after the container in the pod is initialized.

Explain the meaning of the above command a little bit:

"/bin/sh", "-c", use sh to execute the command

touch /tmp/hello.txt; create a /tmp/hello.txt file

while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done; Write the current time to the file every 3 seconds

# Create pods
[root@k8s-master01 pod]# kubectl create  -f pod-command.yaml
pod/pod-command created

# View Pod status
# At this point, both pod s are found to be running normally.
[root@k8s-master01 pod]# kubectl get pods pod-command -n dev
NAME          READY   STATUS   RESTARTS   AGE
pod-command   2/2     Runing   0          2s

# Enter the busybox container in the pod to view the file content
# Add a command: kubectl exec pod name -n namespace -it -c container name /bin/sh Execute commands inside the container
# Use this command to enter the interior of a container and perform related operations
# For example, you can view the contents of the txt file
[root@k8s-master01 pod]# kubectl exec pod-command -n dev -it -c busybox /bin/sh
/ # tail -f /tmp/hello.txt
14:44:19
14:44:22
14:44:25
Special Note:
    found through the above command The functions of starting commands and passing parameters can already be completed, why do we need to provide a args option, for passing parameters?This is actually related to docker somewhat related, kubernetes middle command,args The two items actually achieve coverage Dockerfile middle ENTRYPOINT function.
 1 if command and args are not written, then use Dockerfile Configuration.
 2 if command wrote, but args not written, then Dockerfile The default configuration will be ignored, and the input command
 3 if command not written, but args wrote, then Dockerfile configured in ENTRYPOINT The command will be executed, using the current args parameters
 4 if command and args all written, then Dockerfile The configuration is ignored, execute command and append with args parameter
environment variable

Create a pod-env.yaml file with the following content:

apiVersion: v1
kind: Pod
metadata:
  name: pod-env
  namespace: dev
spec:
  containers:
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
    env: # Set the list of environment variables
    - name: "username"
      value: "admin"
    - name: "password"
      value: "123456"

env, environment variable, is used to set environment variables in the container in the pod.

# Create pods
[root@k8s-master01 ~]# kubectl create -f pod-env.yaml
pod/pod-env created

# Enter the container and output environment variables
[root@k8s-master01 ~]# kubectl exec pod-env -n dev -c busybox -it /bin/sh
/ # echo $username
admin
/ # echo $password
123456

This method is not very recommended. It is recommended to store these configurations separately in the configuration file, which will be introduced later.

port settings

This section introduces the port settings of the container, that is, the ports option of containers.

First look at the sub-options supported by ports:

[root@k8s-master01 ~]# kubectl explain pod.spec.containers.ports
KIND:     Pod
VERSION:  v1
RESOURCE: ports <[]Object>
FIELDS:
   name         <string>  # Port name, if specified, must ensure that the name is unique in the pod		
   containerPort<integer> # The port on which the container should listen (0<x<65536)
   hostPort     <integer> # The port to be exposed by the container on the host. If set, only one copy of the container can run on the host (generally omitted) 
   hostIP       <string>  # The host IP to bind the external port to (generally omitted)
   protocol     <string>  # port protocol. Must be UDP, TCP or SCTP. The default is "TCP".

Next, write a test case, create pod-ports.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-ports
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: # Set the list of ports exposed by the container
    - name: nginx-port
      containerPort: 80
      protocol: TCP
# Create pods
[root@k8s-master01 ~]# kubectl create -f pod-ports.yaml
pod/pod-ports created

# view pod s
# The configuration information can be clearly seen below
[root@k8s-master01 ~]# kubectl get pod pod-ports -n dev -o yaml
......
spec:
  containers:
  - image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - containerPort: 80
      name: nginx-port
      protocol: TCP
......

To access the program in the container, you need to use Podip:containerPort

resource quota

To run a program in a container, it must occupy certain resources, such as cpu and memory. If the resources of a certain container are not limited, it may consume a large amount of resources, causing other containers to fail to run. In response to this situation, kubernetes provides a mechanism for quotas on memory and cpu resources. This mechanism is mainly implemented through the resources option, which has two sub-options:

  • limits: Used to limit the maximum resource usage of the runtime container. When the container resource usage exceeds the limits, it will be terminated and restarted
  • requests : Used to set the minimum resources required by the container. If the environment resources are not enough, the container will fail to start

The upper and lower limits of resources can be set through the above two options.

Next, write a test case, create pod-resources.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-resources
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    resources: # resource quota
      limits:  # Limit resources (upper limit)
        cpu: "2" # CPU limit, the unit is the number of core s
        memory: "10Gi" # memory limit
      requests: # Request resource (lower limit)
        cpu: "1"  # CPU limit, the unit is the number of core s
        memory: "10Mi"  # memory limit

Here is a description of the units of cpu and memory:

  • cpu: core number, can be integer or decimal
  • memory: memory size, you can use Gi, Mi, G, M, etc.
# run pods
[root@k8s-master01 ~]# kubectl create  -f pod-resources.yaml
pod/pod-resources created

# Check that the pod is running normally
[root@k8s-master01 ~]# kubectl get pod pod-resources -n dev
NAME            READY   STATUS    RESTARTS   AGE  
pod-resources   1/1     Running   0          39s   

# Next, stop the Pod
[root@k8s-master01 ~]# kubectl delete  -f pod-resources.yaml
pod "pod-resources" deleted

# Edit the pod and modify the value of resources.requests.memory to 10Gi
[root@k8s-master01 ~]# vim pod-resources.yaml

# start the pod again
[root@k8s-master01 ~]# kubectl create  -f pod-resources.yaml
pod/pod-resources created

# Check the Pod status and find that the Pod failed to start
[root@k8s-master01 ~]# kubectl get pod pod-resources -n dev -o wide
NAME            READY   STATUS    RESTARTS   AGE          
pod-resources   0/1     Pending   0          20s    

# Check the pod details and you will find the following tips
[root@k8s-master01 ~]# kubectl describe pod pod-resources -n dev
......
Warning  FailedScheduling  35s   default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 Insufficient memory.(Not enough storage)

Tags: Docker Kubernetes Operation & Maintenance

Posted by BobLennon on Wed, 30 Nov 2022 18:42:48 +1030