Kubernetes에서 Pod 내에 특별한 역할을 하는 컨테이너가 있다. 바로 pause container 이다.

puase container는 각 파드 내에서 kubernetes가 관리하는 내부 컨테이너이다.
pause container의 주요 목적은 Pod 내부의 컨테이너들이 공유할 수 있는 네임스페이스를 제공하는 것이다. 이는 pod의 안정성을 높이고 네트워크, IPC, UTS 네임스페이스를 공유하게 한다.
pod에 컨테니어를 배포하려 할 때, kubernetes는 pod에 pause container를 생성한다.
Network Namespace
pause container는 네트워크 네임스페이스를 다른 모든 컨테이너와 공유한다. 이는 같은 Pod 내의 컨테이너들이 동일한 IP 주소와 포트 공간을 공유하여 서로 통신할 수 있게 한다.
IPC Namespace
마찬가지로, Pod 내의 컨테이너들이 IPC 네임스페이스를 공유하게 하여 시스템 V IPC 및 POSIX 메시지 큐와 같은 프로세스 간 통신 메커니즘을 사용할 수 있다.
Docker에서 두 개의 컨테이너를 생성하면 이러한 컨테이너는 서로 다른 네트워크 네임스페이스에서 실행되기 때문에 localhost를 통해 통신할 수 없다.
$ docker run -d --name web1 -e PORT=3000 webratio/nodejs-http-server
$ docker run -d --name web2 -e PORT=3001 webratio/nodejs-http-server
$ docker exec -it web1 bash
$ curl -I localhost:3000
HTTP/1.1 200 OK
$ curl -I localhost:3001
curl: (7) Failed to connect to localhost port 2222: Connection refused
그러면 kubernetes에서 pod 내에 두개의 컨테이너를 만들어보자
multiple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: http-server
spec:
containers:
- image: webratio/nodejs-http-server
name: web1
env:
- name: PORT
value: "3000"
- image: webratio/nodejs-http-server
name: web2
env:
- name: PORT
value: "3001"
$ kubectl apply -f multiple-pod.yaml
$ kubectl exec -it http-server --container web1 -- /bin/bash
http-server:/# curl -I localhost:3000
HTTP/1.1 200 OK
http-server:/# curl -I localhost:3001
HTTP/1.1 200 OK
pod 내에서 web1, web2의 localhost 통신이 가능하다.
docker로 pause 컨테이너를 만들어보자
$ docker run -d --name pause --ipc=shareable k8s.gcr.io/pause
--ipc=shareable : 컨테이너의 IPC 네임스페이스를 공유 가능하게 설정한다. 다른 컨테이너가 이 컨테이너와 IPC 네임스페이스를 공유할 수 있게 합니다.
$ docker run -d --name web1 --net=container:pause -e PORT=3000 webratio/nodejs-http-server
$ docker run -d --name web2 --net=container:pause -e PORT=3001 webratio/nodejs-http-server
$ sudo exec -it web1 bash
2c71884d5677:/# curl -I localhost:3000
HTTP/1.1 200 OK
2c71884d5677:/# curl -I localhost:3001
HTTP/1.1 200 OK
container:pause는 이미 실중인 pause라는 이름의 컨테이너와 네트워크 네임스페이스를 공유하겠다는 의미이다. 이렇게 하면 web1 컨테이너는 pause 컨테이너와 동일한 네트워크 인터페이스를 사용하게 됩니다.
pause container는 실제 애플리케이션 코드를 실행하지 않고, 네임스페이스의 플레이스홀더 역할을 하기 떄문에 스템 리소스를 거의 소비하지 않는다.
Kubernetes는 pause container를 자동으로 생성하고 관리한다. 사용자는 이를 직접 볼 필요가 없으며, Pod가 시작될 때 생성되고 Pod가 삭제될 때 종료된다.
pause container 의 코드이다.
https://github.com/kubernetes/kubernetes/blob/v1.28.1/build/pause/linux/pause.c
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;
pause container는 SIGINT, SIGTERM 시그널을 받기 전까지 동작하지 않고 pod 내에서 sleep 상태로 대기한다.
애플리케이션 컨테이너는 불안정할 수 있으며, 죽거나 재시작될 수 있다. 만약 애플리케이션 컨테이너가 네임스페이스를 제공한다면, 컨테이너가 죽을 때마다 네임스페이스도 사라진다. 이를 방지하기 위해, 안정적인 pause container가 네임스페이스를 제공함으로써 Pod의 다른 컨테이너들이 네임스페이스를 안정적으로 사용할 수 있게 한다.
따라서 불안정적인 App Container가 아닌, 안정적인 Pause Container의 Namespace를 공유한다.
Refer