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