2주차 [2] - 파드와 PAUSE 컨테이너

  • Pause 컨테이너가 무엇이고, 파드의 네트워크 구성은 어떻게 되는것인지 알아보자

1. 파드 & Pause 컨테이너

  • 파드는 1개 이상의 컨테이너로 구성된 컨테이너의 집합이다.

  • PAUSE 컨테이너Network/IPS/UTS 네임스페이스를 생성하고 공유하여 POD간 동일한 네트워크 네임스페이스를 가지게 됩니다.

1.1 k8s CRI

  • CRI란?

    • 쿠버네티스 컨테이너 런타임 인터페이스로, kubelet과 컨테이너와의 결합도를 낮추기 위해 도입되었습니다.

    • 1.0 에서는 cri-containerd와 containerd1.0 은 여전히 2개의 다른 데몬으로 구현되었고, 불필요한 통신 오버헤드가 발생했습니다.

  • 이에 대해 CRI-Containerd가 플러그인으로 리팩토링되어서, CRI 플러그인은 직접 함수 호출을 통해 containerd와 상호 작용할 수 있게 변경되 었습니다.

  • 이렇게 kubelet 클라이언트는 UNIX 소켓을 통해 CRI와 통신하고, 컨테이너 수명 주기와 POD를 관리하게 됩니다.

1.2 파드란?

  • 파드란, 컨테이너 애플리케이션의 기본 단위로 불리며, 1개 이상의 컨테이너로 구성된 컨테이너의 집합입니다.

  • Pod 내에 실행되는 컨테이너들은 동일한 노드에 할당 된다.

  • Pod IP 는 노드 IP와 별개로 클러스터 내에서 접근 가능한 IP를 할당 받는다.

    • 다른 노드에서도 POD에 NAT 없이 접근이 가능하다 (CNI의 기능)

  • IP 공유는 어떻게 일어날까?

    • PAUSE 컨테이너가 부모 처럼 Network 네임스페이스를 생성한다.

    • 해당 네임스페이스를 내부 컨테이너들이 공유하게 된다.

  • PAUSE 컨테이너는 두가지 핵심 책임이 있습니다.

    • 첫째, 포드에서 Linux 네임스페이스 공유의 기반 역할을 한다.

    • 둘째, PID 네임스페이스 공유가 활성화 되면, 각 포드에 대한 PID 1역할을 한다.

1.3 배포후 NET, IPC, UTS 네임스페이스 공유 확인

1.3.1 Pod 배포 및 격리 확인

# kind 클러스터 설치 확인
docker port myk8s-worker
(⎈|kind-myk8s:N/A) root@kind:~# docker port myk8s-worker
30000/tcp -> 0.0.0.0:30000
30001/tcp -> 0.0.0.0:30001


# kube-ops-view
(⎈|kind-myk8s:N/A) root@kind:~# helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30000 --set env.TZ="Asia/Seoul" --namespace kube-system
"geek-cookbook" has been added to your repositories
NAME: kube-ops-view
LAST DEPLOYED: Sun Sep  8 06:32:08 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace kube-system -o jsonpath="{.spec.ports[0].nodePort}" services kube-ops-view)
  export NODE_IP=$(kubectl get nodes --namespace kube-system -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kube-ops-view   0/1     1            0           9s

NAME                                 READY   STATUS              RESTARTS   AGE
pod/kube-ops-view-657dbc6cd8-h9s54   0/1     ContainerCreating   0          9s

NAME                    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kube-ops-view   NodePort   10.96.250.240   <none>        8080:30000/TCP   9s

NAME                      ENDPOINTS   AGE
endpoints/kube-ops-view   <none>      9s

# 설치 확인 myk8s-worker bash 진입해서 확인
root@myk8s-worker:/# crictl ps
CONTAINER           IMAGE               CREATED             STATE               NAME                ATTEMPT             POD ID              POD
f7f0fc62dbced       a645de6a07a3d       5 minutes ago       Running             kube-ops-view       0                   736c5d3b5d0ff       kube-ops-view-657dbc6cd8-h9s54
b0cd6fdb2a647       12968670680f4       16 minutes ago      Running             kindnet-cni         0                   48580ffa1480d       kindnet-nsfh4
8419bcab57746       af3ec60a3d89b       16 minutes ago      Running             kube-proxy          0                   786aa48c01215       kube-proxy-pgtrq


# 네임스페이스 특정 확인
pstree -aclnpsS
|-pause,1158,ipc,mnt,net,pid,uts  ## pause 컨테이너 1158번 프로세스 
|-python3,1222,cgroup,ipc,mnt,net,pid,uts -m kube_ops_view ## kubeops server 프로세스

# 루트의 네임스페이스 확인
root@myk8s-worker:/# lsns -p 1
        NS TYPE   NPROCS PID USER COMMAND
4026531834 time       16   1 root /sbin/init
4026531837 user       16   1 root /sbin/init
4026532229 mnt         9   1 root /sbin/init
4026532230 uts        14   1 root /sbin/init
4026532231 ipc         9   1 root /sbin/init
4026532242 pid         9   1 root /sbin/init
4026532243 net        14   1 root /sbin/init
4026532335 cgroup     14   1 root /sbin/init

# pause 컨테이너의 네임스페이스 확인
root@myk8s-worker:/# lsns -p 1158
        NS TYPE   NPROCS   PID USER  COMMAND
4026531834 time       15     1 root  /sbin/init
4026531837 user       15     1 root  /sbin/init
4026532335 cgroup     13     1 root  /sbin/init
4026532583 net         2  1158 65535 /pause
4026532642 mnt         1  1158 65535 /pause
4026532643 uts         2  1158 65535 /pause
4026532644 ipc         2  1158 65535 /pause
4026532645 pid         1  1158 65535 /pause

# kubeops 컨테이너의 네임스페이스 확인

root@myk8s-worker:/# lsns -p 1222
        NS TYPE   NPROCS   PID USER  COMMAND
4026531834 time       16     1 root  /sbin/init
4026531837 user       16     1 root  /sbin/init
4026532583 net         2  1158 65535 /pause
4026532643 uts         2  1158 65535 /pause
4026532644 ipc         2  1158 65535 /pause
4026532646 mnt         1  1222 1000  python3 -m kube_ops_view
4026532647 pid         1  1222 1000  python3 -m kube_ops_view
4026532648 cgroup      1  1222 1000  python3 -m kube_ops_view
  • pause container가 가지고있는 net, uts, ipc 를 다른 컨테이너에서 사용하는 것을 확인

  • mnt, pid, cgroup은 자신의 컨테이너 것을 사용하는 것을 확인

1.3.2 myweb2 파드 2개 배포후 공유 네임스페이스 확인

# 위의 그림의 파드를 생성합니다.
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

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

# 생성 확인
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get pod -owide
NAME     READY   STATUS    RESTARTS   AGE     IP           NODE           NOMINATED NODE   READINESS GATES
myweb2   2/2     Running   0          7m13s   10.244.1.3   myk8s-worker   <none>           <none>


# 파드의 컨테이너 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

# NET SHOOT 의 IP ADDR
2: eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 8e:16:40:c0:47:48 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.1.3/24 brd 10.244.1.255 scope global eth0
       valid_lft forever preferred_lft forever
# NGINX 의 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.244.1.3  netmask 255.255.255.0  broadcast 10.244.1.255

# 두개의 ip가 같은것을 확인 가능하다.

# 각각 PID 를 변수에 지정
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

PAUSEPID=<각자 자신의 pause PID>

# PAUSE 의 NET 네임스페이스 PID 확인 및 IP 정보 확인
pstree -aclnpsS
lsns -t net
nsenter -t $PAUSEPID -n ip -c addr
nsenter -t $NGINXPID -n ip -c addr
nsenter -t $NETSHPID -n ip -c addr

(⎈|kind-myk8s:N/A) root@kind:~# nsenter -t $PAUSEPID -n ip -c addr
nsenter -t $NGINXPID -n ip -c addr
nsenter -t $NETSHPID -n ip -c addr
# PAUSE 컨테이너
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 86:fa:97:cd:e8:43 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.1.2/24 brd 10.244.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::84fa:97ff:fecd:e843/64 scope link
       valid_lft forever preferred_lft forever
# NGINX PID
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 8e:16:40:c0:47:48 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.1.3/24 brd 10.244.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::8c16:40ff:fec0:4748/64 scope link
       valid_lft forever preferred_lft forever
# NETSH PID 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 8e:16:40:c0:47:48 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.1.3/24 brd 10.244.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::8c16:40ff:fec0:4748/64 scope link
       valid_lft forever preferred_lft forever

1.3.3 Pause 컨테이너는 왜 필요한가??

  • 인프라 컨테이너로 불린 pause 컨테이너는 pod 간 유연한 통신을 위해 필요하다고 한다.

Last updated