内容:纪录k8d的pod中的一个特殊容器:pause容器

场景:

当我们在k8s创建了pod对象后,我们登录到node节点后,使用docker ps可以发现很多pause容器

docker ps
CONTAINER    ID                                        IMAGE COMMAND ...
3b45e983c859 gcr.io/google_containers/pause-amd64:3.1/pause”
dbfc35b00062 gcr.io/google_containers/pause-amd64:3.1/pause”
c4e998ec4d5d gcr.io/google_containers/pause-amd64:3.1/pause”
508102acf1e7 gcr.io/google_containers/pause-amd64:3.1/pause”

pause容器的来源:

pause容器其实是node上的kubelet组件在创建pod的容器的时候,一起为pod创建出来的一个
附带容器

pause容器作用:

pause作为Pod中第一个容器,它是为整个Pod提供网络基础设施设定的,所以整体的Network
Settings中也只在pause容器中有所设定。

原则上,任何人都可以配置 Docker 来控制容器组之间的共享级别——你只需创建一个父容器,
并创建与父容器共享资源的新容器,然后管理这些容器的生命周期。在 Kubernetes 中,
pause 容器被当作 Pod 中所有容器的“父容器”并为每个业务容器提供以下功能:

1、在 Pod 中它作为共享 Linux Namespace(Network、UTS 等)的基础;
启用 PID Namespace 共享,它为每个 Pod 提供 1 号进程,并收集 Pod 内的僵尸进程。
是pod中其他容器共享linux namespace的基础,基础设施

PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
	
网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。
	
IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。
	
UTS命名空间:Pod中的多个容器共享一个主机名;Volumes(共享存储卷):
	
Pod中的各个容器可以访问在Pod级别定义的Volumes

2. 负责处理僵尸进程(因为它是1号进程,是所有进程的父进程)

pause容器的dockerfile

FROM scratch
ARG ARCH
ADD bin/pause-${ARCH} /pause
ENTRYPOINT ["/pause"]

pause容器的源码:

/*
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 at
    http://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 <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

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;
}

源码解析:

学过网络编程的人看起来应该会觉得很简单的逻辑,就是注册信号处理函数,然后witpad回收
僵尸进程。然后本身是pause()函数,也就是什么都不做。只等待子进程结束后,收到信号去回收。
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐