赞
踩
K8S的网络模型假定了所有pod都在一个可以直接连通的扁平的网络空间中(所有的pod都可以通过对方的ip直接"到达")。
本文主要研究
在K8S的pod容器中,多容器之间共享网络堆栈,所以容器直接可以使用localhost访问其他容器。由于网络共享,因此每个容器不能有一样的端口号。如下图所示,图中有一个pause容器,k8s在启动容器的时候会先启动一个pause容器,这个容器的作用是
1.可以根据pause根容器为依据,评估整个Pod健康状态。
2.实现Pod内部中容器间网络共享
参考文章
https://zhuanlan.zhihu.com/p/81666226
docker ps -a 查看
每个pod中都会有一个pause容器
1:为什么要pause容器?
在Linux中,当我们运行一个新的进程时,这个进程会继承父进程的命名空间。而运行一个进程在一个新的命名空间,是通过“unsharing”父进程的命名空间从而创建一个新的命名空间。这里举个例子,使用unshare工具来运行一个具有新PID,UTS,IPC以及mount命名空间的shell。
sudo unshare --pid --uts --ipc --mount -f chroot rootfs /bin/sh
随后通过如下命令加入创建好的pause命名空间
docker run xxx --net=container:pause --ipc=container:pause --pid=container:pause nginx
子进程的结束和父进程的运行是一个异步过程
僵尸进程是指它的父进程已经退出(父进程没有等待(调用wait/waitpid)它),而该进程dead之后没有进程接受,就成为僵尸进程,也就是(zombie)进程。
每个进程在系统进程表里有存在一条记录。它记录了关于进程状态和退出码的相关信息。当子进程已经结束运行时,它在进程表中的记录仍然存在,只有当父进程通过使用wait系统调用取回了它的退出码。这个过程就叫做回收僵尸进程。
在容器中,每个PID命名空间必须有一个进程作为init进程。Docker中每个容器通常有自己的PID命名空间,入口点进程是init进程。但是,在kubernetes pod中,我们可以使容器在另一个容器的命名空间中运行。在这种情况下,一个容器必须承担init进程的角色,而其他容器则作为init进程的子元素添加到命名空间中。
Pause容器内其实就运行了一个非常简单的进程
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; }
其中第24行里一个无限循环for(;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。