• Home
  • About
    • lahuman photo

      lahuman

      열심히 사는 아저씨

    • Learn More
    • Facebook
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

#2 파드소개 & PAUSE 컨테이너

19 Jan 2022

Reading time ~5 minutes

파드소개 & PAUSE 컨테이너

  • 파드(Pod) : K8s 에서는 컨테이너 애플리케이션의 기본 단위를 파드(Pod)라고 부르며, 파드는 1개 이상의 컨테이너로 구성된 컨테이너의 집합입니다. - 링크 code

  • Pod 는 1개 이상의 컨테이너를 가질 수 있습니다 ==> sidecar 패턴 등 - 링크
  • Pod 내에 실행되는 컨테이너들은 반드시 동일한 노드에 할당되며 동일한 생명 주기를 갖습니다 → Pod 삭제 시, Pod 내 모든 컨테이너가 삭제
  • Pod IP - Pod 는 노드 IP 와 별개로 클러스터 내에서 접근 가능한 IP를 할당 받으며, 다른 노드에 위치한 Pod 도 NAT 없이 Pod IP로 접근 가능 ⇒ CNI 가 처리
  • IP 공유 - Pod 내에 있는 컨테이너들은 서로 IP를 공유, 컨테이너끼리는 localhost 통해 서로 접근하며 포트를 이용해 구분
    • pause 컨테이너가 ‘parent’ 처럼 network namespace 를 만들어 주고, 내부의 나머지 컨테이너들은 해당 net ns 를 공유
  • volume 공유 - Pod 안의 컨테이너들은 동일한 볼륨과 연결이 가능하여 파일 시스템을 기반으로 서로 파일을 주고받을 수 있음
  • IPC & UDS 관련 정보 링크 - UDS 소개2 IPC방법들

사이드카 & PAUSE 컨테이너

PAUSE 컨테이너는 POD와 함께 기본적으로 생성되며, Network namespace와 IPC namespace를 제공하는 역할을 합니다.

이번 실습은 컨테이너를 2개를 가진 POD를 생성하고 내부 Network를 확인해봅니다.

아래와 같은 yaml 생성합니다.

apiVersion: v1
kind: Pod
metadata:
  name: myweb2
spec:
  containers:
  - name: myweb2-nginx
    image: nginx
    ports:
    - containerPort: 80
      protocol: TCP

  - name: myweb2-netshoot
    image: nicolaka/netshoot
    command: ["/bin/bash"]
    args: ["-c", "while true; do sleep 5; curl localhost; done"] # 포드가 종료되지 않도록 유지합니다

  terminationGracePeriodSeconds: 0

배포 후 podDML NET IPC 공유를 확인합니다.

# 파드 생성
$ kubectl apply -f https://raw.githubusercontent.com/gasida/NDKS/main/3/myweb2.yaml

# 확인
# pod 정보 READY 에 2/2 를 확인 : pod 내 모든 컨테이너가 정상이여야지 status 가 Running 가 됨
$ kubectl get pod -owide
NAME     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
myweb2   2/2     Running   0          63s   172.16.46.6   k8s-w2   <none>           <none>

# 배포된 워커노드에서 docker ps 로 확인
$ docker ps --format "table \t\t" | grep myweb2
nicolaka/netshoot        Up About a minute   k8s_myweb2-netshoot_myweb2_default_829cf80a-f55d-4ea6-b458-45e2b73620e7_0
nginx                    Up About a minute   k8s_myweb2-nginx_myweb2_default_829cf80a-f55d-4ea6-b458-45e2b73620e7_0
k8s.gcr.io/pause:3.4.1   Up 2 minutes        k8s_POD_myweb2_default_829cf80a-f55d-4ea6-b458-45e2b73620e7_0

# Pod 상세 정보에 컨테이너 2개 정보가 보인다
$ kubectl describe pod myweb2
Name:         myweb2
...
Containers:
  myweb2-nginx:
    Container ID:   docker://2717dd093ee5c69a918c6c52461f47cf5f0c0330378730ce717d1fcabb0fc748
    Image:          nginx
...
  myweb2-netshoot:
    Container ID:  docker://e3e3aef9ee53ef805336d4b6e0986f63e23c767b1648d18ff09948815c5f06a9
    Image:         nicolaka/netshoot
...

# 파드의 각각 컨테이너 IP 확인 >> IP가 같다!
$ kubectl exec myweb2 -c myweb2-netshoot -- ip addr
$ kubectl exec myweb2 -c myweb2-nginx -- apt update
$ kubectl exec myweb2 -c myweb2-nginx -- apt install -y net-tools
$ kubectl exec myweb2 -c myweb2-nginx -- ifconfig

# 워커 노드에서 컨테이너 프로세스 정보 확인
$ ps -ef | grep 'nginx -g' | grep -v grep
root       14508   14483  0 09:23 ?        00:00:00 nginx: master process nginx -g daemon off;

$ ps -ef | grep 'curl' | grep -v grep
root       14596   14574  0 09:23 ?        00:00:00 /bin/bash -c while true; do sleep 5; curl localhost; done

# docker top <컨테이너 ID 혹은 NAME>
$ docker top k8s_myweb2-nginx_myweb2_default_333e6cd3-40c1-43ba-8517-2eaf14d2968a_0
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                68723               68695               0                   08:47               ?                   00:00:00            nginx: master process nginx -g daemon off;
systemd+            68764               68723               0                   08:47               ?                   00:00:00            nginx: worker process
systemd+            68765               68723               0                   08:47               ?                   00:00:00            nginx: worker process

# 각각 프로세스를 변수에 지정
$ NGINXPID=$(ps -ef | grep 'nginx -g' | grep -v grep | awk '{print $2}')
$ echo $NGINXPID

$ NETSHPID=$(ps -ef | grep 'curl' | grep -v grep | awk '{print $2}')
$ echo $NETSHPID

# 한 파드 내의 각 컨테이너의 네임스페이스 정보 확인
## cgroup, user 네임스페이스는 따로 격리하지 않음
## mnt, uts, pid 네임스페이스는 컨테이너별로 격리
## ipc, net 네임스페이스는 파드 내의 컨테이너 간 공유 (IPC : 컨테이너 프로세스간 공유 - signal, socket, pipe 등)
## Pause 컨테이너는 IPC, Network 네임스페이스를 생성하고 유지 -> 나머지 컨테이너들은 해당 네임스페이스를 공유하여 사용
## 유저가 실행한 특정 컨테이너가 비정상 종료되어 컨터이너 전체에서 공유되는 네임스페이스에 문제가 발생하는 것을 방지
$ lsns -p $NGINXPID
	NS TYPE   NPROCS   PID USER COMMAND
	4026531835 cgroup    126     1 root /sbin/init
	4026531837 user      126     1 root /sbin/init
	4026532211 ipc         6 14385 root /pause
	4026532214 net         6 14385 root /pause
	4026532287 mnt         3 14508 root nginx: master process nginx -g daemon off;
	4026532288 uts         3 14508 root nginx: master process nginx -g daemon off;
	4026532289 pid         3 14508 root nginx: master process nginx -g daemon off;

$ lsns -p $NETSHPID
	NS TYPE   NPROCS   PID USER COMMAND
	4026531835 cgroup    126     1 root /sbin/init
	4026531837 user      126     1 root /sbin/init
	4026532211 ipc         6 14385 root /pause
	4026532214 net         6 14385 root /pause
	4026532290 mnt         2 14596 root /bin/bash -c while true; do sleep 5; curl localhost; done
	4026532291 uts         2 14596 root /bin/bash -c while true; do sleep 5; curl localhost; done
	4026532292 pid         2 14596 root /bin/bash -c while true; do sleep 5; curl localhost; done

# 컨테이너의 ID 변수 지정
$ NGINXCID=$(docker ps --format "table \t\t" | grep nginx | awk '{print $1}')
$ NETSHCID=$(docker ps --format "table \t\t" | grep netshoot | awk '{print $1}')
$ PAUSECID=$(docker ps --format "table \t\t" | grep POD_myweb2 | awk '{print $1}')
$ echo $NGINXCID
$ echo $NETSHCID
$ echo $PAUSECID

# 컨테이너의 IP 확인 >> IP가 같다!
$ docker exec $NGINXCID ifconfig
$ docker exec $NETSHCID ip addr

# 컨테이너의 네트워크모드 정보와 PAUSE 컨테이너의 Id 정보 확인
# 아래 처럼 위 pause 컨네이너를 nginx, netshoot 컨테이너가 공유하고 있음을 확인
# 즉, 내부 컨테이너가 pause 컨테이너의 network namespace 를 공유
$ docker inspect $NGINXCID | grep NetworkMode
$ docker inspect $NETSHCID | grep NetworkMode
$ docker inspect $PAUSECID | egrep 'Id|Pid\"'

# PAUSE 의 NET 네임스페이스 PID 확인 및 IP 정보 확인
$ lsns -t net
$ PAUSEPID=$(docker inspect $PAUSECID | grep 'Pid\"' | awk '{print $2}' | cut -d "," -f 1)
$ echo $PAUSEPID
$ nsenter -t $PAUSEPID -n ip -c addr
$ nsenter -t $NGINXPID -n ip -c addr
$ nsenter -t $NETSHPID -n ip -c addr

마치며

다른 분들이 정리한 것에 비해서 내 정리는 제공되는 자료를 따라하는 정도밖에 안되네요. 사실 네트워크에 대하여 깊게 알고 있지 않아서 따라가는 것으로 충분하게 벅차네요.

3주를 기대하며 마칩니다.

참고 자료

  • K8S Docs - Components & Cluster Architecture & Pods & Learn Kubernetes Basics & 치트 시트
  • K8S Blog (v1.22) - New Peaks & Nginx-Ingress & API
  • CNCF - 링크 & CNCF Landscape - 링크
  • 44bits(Youtube) - 초보를 위한 쿠버네티스 안내서 & Subicura(WebSite) - 실습편
  • [devinjeon] Container & Pod - 링크
  • [learnk8s] Tracing the path of network traffic in Kubernetes - 링크
  • (심화) ETCD 기본 동작 원리의 이해 - 링크 & ETCD? - 링크


kangcniflannel Share Tweet +1