加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 综合聚焦 > 移动互联 > 评测 > 正文

为什么说容器是单进程模型

发布时间:2019-09-23 20:17:53 所属栏目:评测 来源:阿娇
导读:副标题#e# Go 语言现在的一个主要应用领域就是云原生技术,包括容器(以 Docker 为代表)、Kubernetes、Prometheus 等。后面将写一系列文章来介绍一下云原生技术栈中的关键技术。 过去两年很多大公司的一个主要技术方向就是将应用上云,在这个过程中的一个典

除了第二节讨论的开发者自己赋予 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,如下:

  1. apiVersion: v1 
  2. kind: Pod 
  3. metadata: 
  4. name: nginx 
  5. spec: 
  6. shareProcessNamespace: true 
  7. containers: 
  8. - name: nginx 
  9. image: nginx 
  10. - name: shell 
  11. image: busybox 
  12. securityContext: 
  13.   capabilities: 
  14.     add: 
  15.     - SYS_PTRACE 
  16. stdin: true 
  17. tty: true 

创建 Pod:

  1. kubectl apply -fshare-process-namespace.yaml 

attach 到 Pod 中,ps 查看进程列表:

  1. / # ps ax 
  2. PID   USER     TIME  COMMAND 
  3. 1 root      0:00 /pause 
  4. 8 root      0:00 nginx: master process nginx -g daemon off; 
  5. 14 101       0:00 nginx: worker process 
  6. 15 root      0:00 sh 
  7. 21 root      0:00 ps ax 

我们可以看到 Pod 中的 1 号进程变成了 /pause,其他容器的 entrypoint 进程都变成了 1 号进程的子进程。这个时候开始逐渐逼近事情的本质了:/pause 进程是如何处理将孤儿进程的父进程置为 1 号进程进而避免僵尸进程的呢?我们看一下源码,git repo: pause.c:

  1. #define STRINGIFY(x) #x 
  2. #define VERSION_STRING(x) STRINGIFY(x) 
  3.  
  4. #ifndef VERSION 
  5. #define VERSION HEAD 
  6. #endif 
  7.  
  8. static void sigdown(int signo) { 
  9. psignal(signo, "Shutting down, got signal"); 
  10. exit(0); 
  11.  
  12. static void sigreap(int signo) { 
  13. while (waitpid(-1, NULL, WNOHANG) > 0) 
  14.  
  15. int main(int argc, char **argv) { 
  16. int i; 
  17. for (i = 1; i < argc; ++i) { 
  18. if (!strcasecmp(argv[i], "-v")) { 
  19.   printf("pause.c %sn", VERSION_STRING(VERSION)); 
  20.   return 0; 
  21.  
  22. if (getpid() != 1) 
  23. /* Not an error because pause sees use outside of infra containers. */ 
  24. fprintf(stderr, "Warning: pause should be the first processn"); 
  25.  
  26. if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) 
  27. return 1; 
  28. if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) 
  29. return 2; 
  30. if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap, 
  31.                                          .sa_flags = SA_NOCLDSTOP}, 
  32.             NULL) < 0) 
  33. return 3; 
  34.  
  35. for (;;) 
  36. pause(); 
  37. fprintf(stderr, "Error: infinite loop terminatedn"); 
  38. return 42; 
  39. }  

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读