在前面一篇文章中我们了解到了Pause镜像在Kubernetes中管理的最小单元Pod中的应用,这篇文章中我们来对Pause的源码进行解读以增强理解。

源码地址

  • https://github.com/kubernetes/kubernetes/blob/master/build/pause/pause.c

代码内容

/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>#define STRINGIFY(x) #x
#define VERSION_STRING(x) STRINGIFY(x)#ifndef VERSION
#define VERSION HEAD
#endifstatic 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(int argc, char **argv) {int i;for (i = 1; i < argc; ++i) {if (!strcasecmp(argv[i], "-v")) {printf("pause.c %s\n", VERSION_STRING(VERSION));return 0;}}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;
}

内容解读

无限循环中的pause函数

这是一个不复杂的C语言程序,有一些信号量处理经验的开发者能很容易的理解,加上注释也只有68行。核心的代码是如下两行:

  for (;;)pause();

这是一个无限循环,至于气候的fprintf是例行的写法,42这个宇宙的本质的答案再次以硬编码的形式霸气地出现在一个只有68行代码的程序中,这并不是我们关注的重点。这个无限循环中出现的pause函数是什么?

pause函数是unistd.h中用于处理信号量的,首先我们通过一个简单的示例来理解一下pause的使用方式:

liumiaocn:pause liumiao$ cat testpause.c
#include <unistd.h>
#include <signal.h>
#include <stdio.h>#define TIME_PERIOD 3void signal_handler(int period) {printf("sigal handler (thinking) begins ...\n");signal(SIGALRM,signal_handler);alarm(period); printf("sigal handler (thinking) ends   ...");
}int main(void)
{printf("Guess what LiuMiao wana tell you? ...\n");signal_handler(TIME_PERIOD);printf("\npause begins ...\n");printf("waiting ...\n\n");pause();printf("\npause ends   ...\n");printf("## Surprise: Nothing\n");return 0;
}
liumiaocn:pause liumiao$

代码说明:pause的作用是一直等待直到有信号量将其唤醒,示例中的signal_handler函数起到了这个作用,唤醒之前猜测问题,唤醒之后告诉答案。编译环境如下所示:

liumiaocn:pause liumiao$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.0 (clang-1100.0.33.16)
Target: x86_64-apple-darwin19.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
liumiaocn:pause liumiao$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.2
BuildVersion:   19C57
liumiaocn:pause liumiao$

编译

liumiaocn:pause liumiao$ gcc testpause.c -o testpause
liumiaocn:pause liumiao$ ls
testpause   testpause.c
liumiaocn:pause liumiao$

执行结果如下所示:

liumiaocn:pause liumiao$ ./testpause
Guess what LiuMiao wana tell you? ...
sigal handler (thinking) begins ...
sigal handler (thinking) ends   ...
pause begins ...
waiting ...sigal handler (thinking) begins ...
sigal handler (thinking) ends   ...
pause ends   ...
## Surprise: Nothing
liumiaocn:pause liumiao$

结合Pause的源码不难理解Pause容器大部分时间所起到的作用,就是等待唤醒,唤醒之后继续沉睡直到下次唤醒,周而复始永不停息,这也是在前面的文章中我们看到的使用docker inspect可以看到pause容器的CPUPeriod被设定为0, 结合源码也就比较容易理解了,绝大多数时间都在睡觉的一个容器。

Pid为1的进程

Linux中Pid为1的进程,占据此进程的目前主要有init和systemd,比如CentOS或者RHEL下面可能是这样的

[root@host131 Pod]# ps -ef |grep systemd |grep deserialize
root         1     0  0 19:51 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
[root@host131 Pod]#

而pause运行的时候,需要其pid为1,但是注意如果不为1并不是一个错误,不过没有必要过于纠结这一点,了解到其设计的思路是希望pause启动的作用即可。

  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(SIGCHLD, &(struct sigaction){.sa_handler = sigreap,.sa_flags = SA_NOCLDSTOP},NULL) < 0)return 3;

sigaction会捕获SIGCHLD信号,通过sigreap函数对进行进行处理

static void sigreap(int signo) {while (waitpid(-1, NULL, WNOHANG) > 0);
}

而waitpid中-1则表示等待子进程退出,而WNOHANG的指定表示 子进程未结束时不阻塞。所以虽然代码很少,还是能够起到很重要的作用的。

总结

Pause分担了init进行的作用,包括僵尸进程的处理,而这些都是Kubernetes所提供的平台基础功能的一部分,试想如果僵尸进程的处理需要Pod中运行的其他容器比如nginx来实现,而nginx本身又不提供这样的功能将会多么麻烦。

Kubernetes基础:Pause镜像源码解读相关推荐

  1. boost thread 判断是否正在运行_java高端基础:Thread源码解读

    阅读本篇文章之前建议先了解线程的生命周期以及状态之间的可能的转换 Java高端基础:线程的生命周期 wait() 使当前线程等待,直到其他线程调用该对象的notify()或者notifyAll()方法 ...

  2. jpcsp源码解读5:umd光盘镜像(.iso)

    这次的状况稍显复杂. 首先说一下umd光盘镜像文件的内部组织方式.注意,这些内容全部是从源码解读而来,而不是来自关于这种文件格式的标准文档. java科普之文件操作: fileReader = new ...

  3. Openkruise/rollouts 源码解读

    Openkruise/rollouts 源码解读 最近因为工作需要的原因,无意中接触到了 rollouts 这个开源项目.它是由阿里巴巴开源的一个k8s相关的一个工具. 其主要作用是工作负载(work ...

  4. spring-cloud-context源码解读

    spring-cloud-context源码解读 1. The Bootstrap Application Context Understanding source code 2. Applicati ...

  5. 利用yolov5训练自己的数据集; yolov5的安装与使用 ; yolov5源码解读

    *免责声明: 1\此方法仅提供参考 2\搬了其他博主的操作方法,以贴上路径. 3* 场景一:Anconda环境基本操作 场景二:yolov5的使用 场景三:yolo v5训练自己的数据集 场景四:yo ...

  6. ios html zfplayer,【iOS】ZFPlayer源码解读中

    前言 本篇继ZFPlayer源码解读基础之上,主要解析说明控制层与播放器,因为在上篇文章至现在并未提及丝毫关于这两个类业务的实现. 首先说下这两个类各自的职责. 控制层:主要负责响应与用户之间的交互, ...

  7. Bert系列(三)——源码解读之Pre-train

    https://www.jianshu.com/p/22e462f01d8c pre-train是迁移学习的基础,虽然Google已经发布了各种预训练好的模型,而且因为资源消耗巨大,自己再预训练也不现 ...

  8. PyTorch 源码解读之即时编译篇

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 作者丨OpenMMLab 来源丨https://zhuanlan.zhihu.com/ ...

  9. AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilityManager

    做ios开发,AFNetworking 这个网络框架肯定都非常熟悉,也许我们平时只使用了它的部分功能,而且我们对它的实现原理并不是很清楚,就好像总是有一团迷雾在眼前一样. 接下来我们就非常详细的来读一 ...

  10. Java Review - LinkedHashMap LinkedHashSet 源码解读

    文章目录 Pre 概述 数据结构 类继承关系 构造函数 方法 get() put() remove() LinkedHashSet 使用案例 - FIFO策略缓存 Pre Java Review - ...

最新文章

  1. Apache 流框架 Flink,Spark Streaming,Storm对比分析(一)
  2. ieda中快捷搜索_IntelliJ IDEA IDE设置系列教程(十):在工具窗口中快速搜索
  3. Shell脚本实战之文件批量创建和修改
  4. PL/SQL DEVELOPER 使用的一些技巧
  5. 报表没完没了怎么办? | 润乾集算器提效报表开发
  6. Java压缩技术(二) ZIP压缩——Java原生实现
  7. 科目三电子路考哪些情况会被评判不合格
  8. 要提升asp.net工作能力。应急于提升的是哪些技术?
  9. 【数据结构与算法】循环队列的Java实现
  10. mysql 亿级高并发_亿级流量系统架构之如何设计每秒十万查询的高并发架构.md
  11. java window.onload_JavaScript window.onload
  12. SQL数据库被置疑后的恢复步骤(附详细图解)-虽然转载但是亲自实现过
  13. 数据仓库与数据挖掘的OLAP技术----韩家炜教授的《数据挖掘概念与技术》学习笔记
  14. Gameplay - 多人游戏关卡设计
  15. CleanMyMac最新2020注册机
  16. 第五篇:风控模型监控预警
  17. 关于电子科技大学成电讲坛类门票获取的调查报告
  18. IOS苹果手机下载DNF韩服手游手机版ios版下载
  19. 文献分析-利用CNKI自带的可视化分析工具
  20. 【历史上的今天】6 月 5 日:洛夫莱斯和巴贝奇相遇;公钥密码学先驱诞生;函数语言设计先驱出生

热门文章

  1. 微信小程序,短信验证码登录,设置密码,密码强度校验
  2. 手机网页点击按钮给指定号码发送短信
  3. Druid监控页面配置与使用
  4. 修改ftp服务器地址,ftp服务器ip地址修改
  5. 周子明:大道无疆,“驰”之以恒,在数字化时代纵横驰骋
  6. 混乱之子第七季/全集Sons of Anarchy迅雷下载
  7. 编写一个Linux虚拟网卡来实现类NVI
  8. 文件关联后即时生效代码
  9. 机器学习-朴素贝叶斯(高斯、多项式、伯努利)
  10. Beta周王者荣耀交流协会第六次会议