| 除了第二节讨论的开发者自己赋予 entrypoint 进程管理多进程的能力,这里我更推荐借助 Kubernetes  来做这件事情。我想现在应该也没有人对容器进行人工管理了,大部分人应该都转向了容器编排和调度工具 Kubernetes 阵营了(对于那些还在使用 Swarm  的一小波人,我劝你们早日弃暗投明 :))。 Kubernetes 中可以将多个容器编排到一个 Pod 里面,共享同一个 Linux NameSpace。这项技术的本质是使用 Kubernetes  提供一个 pause 镜像,展开来说就是先用 pause 镜像实例化出 NameSpace,然后其他容器加入这个 NameSpace 从而实现  NameSpace 共享。突然意识到这块需要有容器和 NameSpace  的技术背景,限于篇幅,希望你可以自行搜索这种技术背景。或者我下一篇文章讨论一下容器技术的本质。 言归正传,我们来介绍一下 pause。pause 是 Kubernetes 在 1.16 版本引入的技术,要使用 pause,我们只需要在 Pod 创建的  yaml 中指定 shareProcessNamespace 参数为 true,如下: apiVersion: v1 kind: Pod metadata: name: nginx spec: shareProcessNamespace: true containers: - name: nginx image: nginx - name: shell image: busybox securityContext:   capabilities:     add:     - SYS_PTRACE stdin: true tty: true 
 创建 Pod: kubectl apply -fshare-process-namespace.yaml 
 attach 到 Pod 中,ps 查看进程列表: / # ps ax PID   USER     TIME  COMMAND 1 root      0:00 /pause 8 root      0:00 nginx: master process nginx -g daemon off; 14 101       0:00 nginx: worker process 15 root      0:00 sh 21 root      0:00 ps ax 
 我们可以看到 Pod 中的 1 号进程变成了 /pause,其他容器的 entrypoint 进程都变成了 1  号进程的子进程。这个时候开始逐渐逼近事情的本质了:/pause 进程是如何处理将孤儿进程的父进程置为 1 号进程进而避免僵尸进程的呢?我们看一下源码,git  repo: pause.c: #define STRINGIFY(x) #x #define VERSION_STRING(x) STRINGIFY(x)  #ifndef VERSION #define VERSION HEAD #endif  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(int argc, char **argv) { int i; for (i = 1; i < argc; ++i) { if (!strcasecmp(argv[i], "-v")) {   printf("pause.c %sn", 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 processn");  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 terminatedn"); return 42; }  
 (编辑:南平站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |