Kubernetes pod里一个特殊的容器:pause-amd64

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

大家在使用Docker容器或者Kubernetes时,遇到过这个容器么?gcr.io/google_containers/pause-amd64

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,主要有两个职责:

  1. 是pod里其他容器共享Linux namespace的基础
  2. 扮演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里的pause容器有所帮助。感谢阅读。

本文来自云栖社区合作伙伴“汪子熙”,了解相关信息可以关注微信公众号"汪子熙"。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
10天前
|
存储 Kubernetes C++
【专栏】Kubernetes VS Docker Swarm:哪个容器编排工具更适合你?
【4月更文挑战第27天】对比Kubernetes和Docker Swarm:K8s在可扩展性和自动化方面出色,有强大社区支持;Swarm以简易用著称,适合初学者。选择取决于项目需求、团队技能和预期收益。高度复杂项目推荐Kubernetes,快速上手小项目则选Docker Swarm。了解两者特点,助力选取合适容器编排工具。
|
7天前
|
Kubernetes Perl 容器
在 Kubernetes 中重启 pod 的 3 种方法
【4月更文挑战第25天】
18 1
在 Kubernetes 中重启 pod 的 3 种方法
|
9天前
|
Kubernetes 网络协议 调度
kubernetes最小调度单元pod详解(二)
kubernetes最小调度单元pod详解(二)
|
9天前
|
Kubernetes 应用服务中间件 调度
kubernetes最小调度单元pod详解(一)
kubernetes最小调度单元pod详解(一)
|
13天前
|
运维 Kubernetes Linux
10分钟搭建Kubernetes容器集群平台(kubeadm)
10分钟搭建Kubernetes容器集群平台(kubeadm)
|
13天前
|
Kubernetes Ubuntu Linux
Kubernetes(K8S)集群管理Docker容器(部署篇)
Kubernetes(K8S)集群管理Docker容器(部署篇)
|
13天前
|
存储 Kubernetes Docker
Kubernetes(K8S)集群管理Docker容器(概念篇)
Kubernetes(K8S)集群管理Docker容器(概念篇)
|
应用服务中间件 调度 nginx
Kubernetes-项目中pod调度使用法则
前言kubernetes中部署的pod默认根据资源使用情况自动调度到某个节点。可在实际项目的使用场景中都会有更细粒度的调度需求,比如:某些pod调度到指定主机、某几个相关的服务的pod最好调度到一个节点上、Master节点不允许某些pod调度等。
2018 0
|
Kubernetes 应用服务中间件 调度
Kubernetes之Pod调度
Kubernetes调度器根据特定的算法与策略将pod调度到工作节点上。在默认情况下,Kubernetes调度器可以满足绝大多数需求,例如调度pod到资源充足的节点上运行,或调度pod分散到不同节点使集群节点资源均衡等。
1414 0
|
Kubernetes 应用服务中间件 调度
Kubernetes之Pod调度
本文讲的是Kubernetes之Pod调度【编者的话】Kubernetes调度器根据特定的算法与策略将pod调度到工作节点上。在默认情况下,Kubernetes调度器可以满足绝大多数需求,例如调度pod到资源充足的节点上运行,或调度pod分散到不同节点使集群节点资源均衡等。
2736 0

相关产品

  • 容器服务Kubernetes版