如果这个世界上没有pod是什么样的?
如果我们没有pod, 转而把容器当成最小部署单元会怎样?
现在假设你站在K8s诞生的时间点上, 你想要设计出一个"容器编排"系统, 现在在这种背景下, 如果你不用容器作为最小调度单元, 转而设计出pod作为最小调度单元, 那你最好有一个充分的理由, 否则你很容易会被当成闲着蛋疼没事找事.
回答一个问题, 我们怎么设计的容器? 容器想让你跑一个进程(而不是一组进程), 比如MySQL容器让你跑MySQL进程这样. 在我们的蓝图里, 一个容器就是一个进程, 那么, 负责管理编排容器的, 就对应着管理进程的操作系统, 这就是我们叫"容器编排工具"为操作系统的原因. 现在, 你终于对这句抽象晦涩的描述, 有了一个更深的理解.
更进一步的, 容器是想让你只跑一个进程, 但是我们实际上发现很多场景下我们都不止跑一个, 而是跑好几个进程组合在一起形成某种服务的, 这怎么办? 你想想这怎么办? 当然你可以选择通过 Affinity 来把这些容器布置在同一台宿主机上, 但这又不够原子了吧? 不如想一招把这几个容器塞到一个球里, 然后把这个球当成最小单元就行了吧? ok, pod诞生了.
# 你看, 负责系统日志的rsyslogd服务, 他就由
# main / imklog / imuxsock 三者组合构成
$ pstree -g
systemd(1)
|-rsyslogd(1632)-+-{in:imklog}(1632)
| |-{in:imuxsock) S 1(1632)
| `-{rs:main Q:Reg}(1632)
pod = pause + n*continer也就是说在任何pod里除了你自己定义出的容器, 还都会有一个pause容器, 如果我们想要理解K8s的网络模型, 一定要先理解pause容器
上学的时候就知道, 某个进程fork出一个子进程, 但如果父进程没有通过 wait() 等待子进程结束就直接退出, 这种情况下子进程就会直接变成僵尸进程, 继而成为1号进程的子进程. (科普: 子进程在运行完成以后, 它的进程条目表仍然得到保留, 直到父进程通过wait明确得知子进程已经结束, 并清理进程条目才算彻底结束, 明明已经死了却没人帮你从进程条目表里清除, 故得名"僵尸")
收养: 但是书上好像没有说1号进程会怎么处理这些僵尸进程? 这时候1号进程就应该负责调用wait() 并等待僵尸进程终止, 但这件事并不是所有人都能做到的, 就好像nginx并不会管这些事, 因此pause会负责干这件事, 所有容器都共享pid-namespace, 而其中pause成为他们的1号进程, 负责收集其他容器的僵尸进程, 这样这个pod里就不会到处都是僵尸进程
防止误杀: 于此同时我们要求pause进程必须屏蔽某些信号, 比如Ctrl+C之类的信号, 防止这个进程也被误杀, 从侧面印证nginx还是无法成为1号进程.
多说一句docker容器里的事, 你每次执行docker kill的时候其实就是在kill容器里的init进程
这个init进程可以是ENTRYPOINT, 也可以是docker run ubuntu xxx , 一旦容器里的init进程被杀了, 整个pid-namespace下的所有进程都将终止 (所以JDOS求求你不要杀掉那个sleep 9999d)