1

Author: Shen Yajun

A member of the R&D team of Aikesheng, responsible for the back-end development of the company's DMP products, his hobbies are too broad, he can't finish talking for three days and three nights, low-key and low-key...

Source of this article: original contribution

*The original content is produced by the open source community of Aikesheng, and the original content shall not be used without authorization. For reprinting, please contact the editor and indicate the source.


what is pod

A Pod is a set of cooperating containers, the smallest deployable unit that we can create and manage in Kubernetes. Containers within the same pod share network and storage, and are addressed and scheduled as a whole. When we create a pod in Kubernetes, all the containers in the pod are created, and all the resources of the container are allocated to a node.

Why do you need pods

Think about the following questions, why not deploy containers directly in kubernetes? Why do you need to treat multiple containers as a whole? Why not use the scheme of running multiple processes inside the same container?

When an application contains multiple processes and communicates via IPC , it needs to run on the same host. If the processes deployed in the kubernetes environment need to run in containers, one of the possible solutions is to run multiple processes in the same container to achieve a deployment mode similar to that on the same host. But the design of the container is that each container runs a separate process, unless the process itself will create multiple child processes. Of course, if you choose to run multiple unrelated processes in the same container, you need to manage other processes yourself, including The life cycle of each process (restarting the hung process), log cutting, etc. If multiple processes are logging on stdout and stderr, it can lead to messy logs, so docker and kubernetes expect us to have only one process running inside a container.

After excluding the solution of running multiple processes in the same container, we need a higher-level organizational structure to bind multiple containers together to form a unit. This is the origin of the concept of pod and the benefits brought by pod:

  1. As a service unit that can run independently, Pod simplifies the difficulty of application deployment, and provides great convenience for application deployment management with a higher level of abstraction.
  2. As the smallest application instance, Pod can run independently, so it can be easily deployed, horizontally expanded and contracted, and facilitated for scheduling management and resource allocation.
  3. Containers in a Pod share the same data and network address space, and unified resource management and allocation are also performed between Pods.

pause container

Because containers are separated by Linux Namespace and cgroups, the pod implementation needs to figure out how to break this separation. In order to realize that the containers of the same pod can share some resources, the pause container is introduced. The image of the pause container is very small and runs a very simple process. It performs almost no function and blocks itself forever when it starts. Each Kubernetes Pod contains a pause container, which is the basis for namespace sharing within the pod.

Running a process in the linux environment will inherit all the namespace of the parent process, and can also use the unsharing method to create a new namespace . Use the unshare method to run the shell and create a new PID, UTS, IPC, and mount namespace as follows.

 sudo unshare --pid --uts --ipc --mount -f chroot rootfs /bin/sh

Other processes can use the system call setns to be added to the new namespace. The implementation of pod is similar. The following command demonstrates how to manually create a simple pod

 ## 首先运行一个 pause 容器
docker run -d --name pause -p 8880:80 --ipc=shareable gcr.io/google_containers/pause-amd64:3.0

## 创建 nginx 容器,并将其加入到 pause 容器 net ipc 和 pid namespace
$ cat <<EOF >> nginx.conf
error_log stderr;
events { worker_connections  1024; }
http {
    access_log /dev/stdout combined;
    server {
        listen 80 default_server;
        server_name example.com www.example.com;
        location / {
            proxy_pass http://127.0.0.1:2368;
        }
    }
}
EOF

docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf --net=container:pause --ipc=container:pause --pid=container:pause nginx

## 运行 ghost 容器 并将其加入到 pause 容器 network ipc 和 pid namespace
docker run -d --name ghost --net=container:pause --ipc=container:pause --pid=container:pause ghost

Use ps in the ghost container to see the pause and nginx processes,

 USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   1032     4 ?        Ss   10:06   0:00 /pause
root         8  0.0  0.1   8864  3120 ?        Ss   10:15   0:00 nginx: master process nginx -g daemon off;
101         38  0.0  0.1   9312  3088 ?        S    10:15   0:00 nginx: worker process
node        48  0.3  6.9 969996 142296 ?       Ssl  10:18   0:09 node current/index.js

Visit the ghost page through localhost:8080, you should be able to see the ghost running through the Nginx proxy, because the pause, nginx and ghost containers share the network namespace, as shown in the following figure:

pod common way

Pod usage can be divided into two types:

  1. There is only one container running inside a pod. In this case, the pod can be regarded as a wrapper for the container, and kubernetes manages the container by managing the pod;
  2. A pod runs multiple containers that need to work closely together on shared resources. As shown in the figure below, the two containers share files through Volume, the Filer Puller updates the files from the remote end, and the Web Server is responsible for the display of the files.

Whether to allocate two containers in different or the same pod, usually need to consider the following points:

  1. Are they necessary to run on the same kubernetes node?
  2. Do they represent a whole, or are they separate components?
  3. Do they need to scale up or down as a whole?

Use of Pods

Create Pod

Create a pod by kubectl apply -f nginx-pod.yaml kubectl get pod and check the status of the pod by ---42f8c3e2f24d9e94fbbb5d65ea9204ec---, as shown below.

 apiVersion: v1 
kind: Pod
metadata:
  name: nginx  # pod 名称
spec:
  containers:   # 容器列表
  - name: nginx # 容器名称
    image: nginx:1.14.2 # 容器使用镜像
    ports:  # 容器端口映射
    - containerPort: 80

Execute kubectl describe pod nginx to view the status of the pod. The following shows some information about the pod. The Status field is a summary of the pod in its life cycle.

 Name:         nginx
Namespace:    default
.....
Start Time:   Sat, 04 Jun 2022 09:24:36 +0000
Labels:       <none>
.....
Status:       Running
IP:           10.42.1.139
Containers:
  nginx:
    Container ID:   docker://xxxx
    Image:          nginx:1.14.2
    Image ID:       docker-pullable://
.....

pod life cycle

After the Pod is created, it follows the defined life cycle, starting from the Pending phase. If at least one container in the pod starts normally, it enters the Running phase, and then enters the Succeeded or Failed phase depending on whether any container in the Pod terminates due to a failure. The life cycle may be in the following states

  • Pending: The Pod has been accepted by the Kubernetes cluster, but one or more containers are not ready to run. This includes the time Pods spend waiting to be scheduled and the time spent downloading container images over the network.
  • Running: Pod is bound to a node and all containers are created. At least one container is still running or in the process of being started or restarted.
  • Succeeded: All containers in the Pod terminated successfully and will not be restarted.
  • Failed: All containers in the Pod have terminated, and at least one container has terminated due to a failure. That is, the container either exited with a non-zero status or was terminated by the system.
  • Unknown: The status of the Pod could not be obtained for some reason. This phase usually occurs due to an error communicating with the node where the Pod should be running.

pod creation process

All Kubernetes components Controller, Scheduler, and Kubelet use the Watch mechanism to monitor the API Server to obtain object change events. The general process of creating a pod is as follows:

  1. The user submits the Pod` description file to the API Server through Kubectl;
  2. API Server stores the information of the Pod object in Etcd;
  3. The creation of Pod will generate events and return them to API Server;
  4. Controller listens to events;
  5. If the Pod needs to mount a disk, the Controller will check whether there is a PV that meets the conditions;
  6. If the PV meets the conditions, the Controller will bind the Pod and the PV, and notify the API Server of the binding relationship;
  7. API Server writes binding information to Etcd;
  8. Generate Pod Update events;
  9. The Scheduler listens to the Pod Update event;
  10. Scheduler will choose Node for Pod;
  11. If there is a Node that meets the conditions, the Scheduler will bind the Pod and Node, and notify the API Server of the binding relationship;
  12. API Server writes binding information to Etcd;
  13. Generate Pod Update events;
  14. The Kubelet listens to the Pod Update event and creates a Pod;
  15. Kubelet tells CRI (Container Runtime Interface) to download the image;
  16. Kubelet tells CRI to run the container;
  17. CRI calls Docker to run the container;
  18. Kubelet tells Volume Manager to mount the disk to Node and mount it to Pod at the same time;
  19. CRI calls CNI (Container Network Interface) to configure container network;

爱可生开源社区
426 声望209 粉丝

成立于 2017 年,以开源高质量的运维工具、日常分享技术干货内容、持续的全国性的社区活动为社区己任;目前开源的产品有:SQL审核工具 SQLE,分布式中间件 DBLE、数据传输组件DTLE。