Kubernetes pod里的pause

63次阅读
没有评论

共计 2981 个字符,预计需要花费 8 分钟才能阅读完成。

这篇文章主要介绍“Kubernetes pod 里的 pause-amd64 容器有什么用”,在日常操作中,相信很多人在 Kubernetes pod 里的 pause-amd64 容器有什么用问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Kubernetes pod 里的 pause-amd64 容器有什么用”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!

docker ps 的命令返回的结果:

[root@k8s-minion1 kubernetes]# docker ps |grep pause
c3026adee957 gcr.io/google_containers/pause-amd64:3.0  /pause  22 minutes ago Up 22 minutes k8s_POD.d8dbe16c_redis-master-343230949-04glm_default_ce3f60a9-095d-11e7-914b-0a77ecd65f3e_66c108d5
202df18d636e gcr.io/google_containers/pause-amd64:3.0  /pause  24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-proxy-js0z0_kube-system_2866cfc2-0891-11e7-914b-0a77ecd65f3e_c8e1a667
072d3414d33a gcr.io/google_containers/pause-amd64:3.0  /pause  24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-flannel-ds-tsps5_default_2866e3fb-0891-11e7-914b-0a77ecd65f3e_be4b719e
[root@k8s-minion1 kubernetes]#

Kubernetes 的官网解释:

it s part of the infrastructure. This container is started first in all Pods to setup the network for the Pod.

意思是:pause-amd64 是 Kubernetes 基础设施的一部分,Kubernetes 管理的所有 pod 里,pause-amd64 容器是第一个启动的,用于实现 Kubernetes 集群里 pod 之间的网络通讯。

对这个特殊容器感兴趣的朋友,可以阅读其源代码:
https://github.com/kubernetes/kubernetes/tree/master/build/pause

我们查看这个 pause-amd64 镜像的 dockerfile,发现实现很简单,基于一个空白镜像开始:

FROM scratch
ARG ARCH
ADD bin/pause-${ARCH} /pause
ENTRYPOINT [/pause]

ARG 指令用于指定在执行 docker build 命令时传递进去的参数。

这个 pause container 是用 C 语言写的:

https://www.ianlewis.org/en/almighty-pause-container

在运行的 Kubernetes node 上运行 docker ps,能发现这些 pause container:

pause container 作为 pod 里其他所有 container 的 parent container,主要有两个职责:

是 pod 里其他容器共享 Linux namespace 的基础

扮演 PID 1 的角色,负责处理僵尸进程

这两点我会逐一细说。在 Linux 里,当父进程 fork 一个新进程时,子进程会从父进程继承 namespace。目前 Linux 实现了六种类型的 namespace,每一个 namespace 是包装了一些全局系统资源的抽象集合,这一抽象集合使得在进程的命名空间中可以看到全局系统资源。命名空间的一个总体目标是支持轻量级虚拟化工具 container 的实现,container 机制本身对外提供一组进程,这组进程自己会认为它们就是系统唯一存在的进程。

在 Linux 里,父进程 fork 的子进程会继承父进程的命名空间。与这种行为相反的一个系统命令就是 unshare:

再来聊聊 pause 容器如何处理僵尸进程的。

Pause 容器内其实就运行了一个非常简单的进程,其逻辑可以从前面提到的 Pause github 仓库上找到:

static void sigdown(int signo) { psignal(signo,  Shutting down, got signal  exit(0);
}static void sigreap(int signo) { while (waitpid(-1, NULL, WNOHANG)   0);
}int main() { if (getpid() != 1) /* Not an error because pause sees use outside of infra containers. */
 fprintf(stderr,  Warning: pause should be the first process\n  if (sigaction(SIGINT,  (struct sigaction){.sa_handler = sigdown}, NULL)   0) return 1; if (sigaction(SIGTERM,  (struct sigaction){.sa_handler = sigdown}, NULL)   0) return 2; if (sigaction(SIGCHLD,  (struct sigaction){.sa_handler = sigreap,
 .sa_flags = SA_NOCLDSTOP}, NULL)   0) return 3; for (;;)
 pause(); fprintf(stderr,  Error: infinite loop terminated\n  return 42;}

这个 c 语言实现的进程,核心代码就 28 行:

其中第 24 行里一个无限循环 for(;;), 至此大家能看出来 pause 容器名称的由来了吧?

这个无限循环里执行的是一个系统调用 pause,

因此 pause 容器大部分时间都在沉睡,等待有信号将其唤醒。

接收什么信号呢?

一旦收到 SIGCHLD 信号,pause 进程就执行注册的 sigreap 函数。

看下 SIGCHLD 信号的帮助:

SIGCHLD,在一个进程正常终止或者停止时,将 SIGCHLD 信号发送给其父进程,按系统默认将忽略此信号,如果父进程希望被告知其子系统的这种状态,则应捕捉此信号。

pause 进程注册的信号处理函数 sigreap 里,调用另一个系统调用 waitpid 来获得子进程终止的原因。

到此,关于“Kubernetes pod 里的 pause-amd64 容器有什么用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计2981字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)