Profile picture

[k8s] Deep Dive - Pod

JaehyoJJAng2023년 04월 04일

▶︎ Pod

파드는 하나 이상의 컨테이너로 구성된 그룹이며 쿠버네티스의 기본 빌딩 블록이다.

  • 파드는 언제라도 죽을 수 있고 쿠버네티스는 이를 가정하고 설계하였음
  • 파드는 항상 두 개 이상의 컨테이너를 포함하는 것을 의미하지 않음. 일반적으로 파드는 하나의 컨테이너만 포함됨.
  • 모든 컨테이너는 항상 하나의 워커노드에서 실행되며 여러 워커노드에 걸쳐 시행되지 않음.

image


▶︎ Pod 이해하기

Pod를 이용함으로서 아래와 같은 기대효과를 얻을 수 있다.

  • 컨테이너가 제공하는 모든 기능을 활용하는 동시 프로세스가 함께 실행됨.
  • 이들을 격리된 상태로 유지함

Pod를 통해 컨테이너가 제공하는 모든 기능을 활용하는 동시에 프로세스가 함께 실행되는 것처럼 보이게 할 수 있음


같은 Pod에서 Container 간 부분 격리

Pod 안에 있는 컨테이너가 특정한 리소스를 공유하기 위해 각 컨테이너가 완벽하게 격리되지 않도록 함. 쿠버네티스는 파드 안에 있는 모든 컨테이너가 자체 네임스페이스가 아닌 동일한 리눅스 네임스페이스를 공유하도록 도커를 설정한다.

  • 모든 컨테이너는 동일한 네트워크 네임스페이스와 UTS 네임스페이스 안에서 실행되기 때문에 모든 컨테이너는 같은 호스트 이름과 네트워크 인터페이스를 공유한다.
  • 모든 컨테이너는 동일한 IPC 네임스페이스 아래에서 실행되어 IPC를 통해 서로 통신할 수 있다.
  • 최근 동일한 PID 네임스페이스를 공유할 수 있지만 기본적으로 활성화 되어 있지 않다.
  • Filesystem에 한해서는 조금 다르다. 대부분 컨테이너 파일 시스템은 컨테이너 이미지에서 나오기에, 파일시스템은 다른 컨테이너와 완전히 분리된다.

UTS namespace (Unix Timesharing System)

system의 hostname을 namespace 별로 격리시켜 준다.

Linux System Call 중 하나인 uname에서 struct에 정의된 식별자 중 nodename을 isolate하는 것이다.

IPC namespace (Inter-Process Communication)

프로세스간 서로 데이터를 주고 받는 경로를 의미한다.

Linux에서 사용되는 대표적인 IPC 방식은 Signal, Socket, pipe 등이 있다. 이러한 IPC resource를 격리 시켜 제공한다.


▶︎ 컨테이너가 동일한 IP와 포트공간을 공유하는 방법

파드안의 컨테이너가 동일한 네트워크의 네임스페이스에서 실행되기에 동일한 IP 주소와 포트 공간을 공유하게 됨.

  • 동일한 파드 안 컨테이너에서 실행 중인 프로세스가 같은 포트 번호를 사용하지 않도록 주의
    • 동일한 포트 번호를 사용할 경우 포트 충돌 발생
  • 다른 Pod의 경우 서로 다른 포트 공간을 가지기에 포트 충돌이 일어나지 않음
  • Pod 안에 있는 모든 컨테이너는 동일한 루프백 네트워크 인터페이스를 가지기에 컨테이너들이 Localhost를 통해 서로 통신가능

▶︎ Pod 간 Flat Network

파드는 논리적인 호스트로서 컨테이너가 아닌 환경에서의 물리적 호스트 혹은 VM과 유사하게 동작함.

  • 클러스터의 모든 Pod는 하나의 Flat한 공유 네트워크 주소 공간에 상주한다.
  • 모든 Pod는 다른 Pod의 IP 주소를 사용하여 접근하는 것이 가능하다.
    • (Pod간 어떠한 NAT도 존재하지 않으며 마치 LAN처럼 통신이 가능하다.)
  • 두 파드가 서로 네트워크 패킷을 보내면, 상대방의 실제 IP주소를 패킷 안에 있는 출발지 IP 주소에서 찾을 수 있다.

image


▶︎ Pod 실습

‣ Manifest 작성

Pod를 정의하는 간단한 manifest
pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: kubia-manual
spec:
  containers:
    - name: kubia
      image: luksa/kubia
      ports:
        - containerPort: 8080
          protocol: TCP

‣ Pod 생성

$ kubectl apply -f ./pod.yaml

💡 kubectl create vs kubectl apply

kubectl create : 명령형 (Imperative)

kubectl apply : 선언형 (Declarative)

create 명령은 각 오브젝트의 구성이 그 구성파일 내에 완전하게 정의되고 기록되어질 경우 잘 작동한다. 하지만 활성 오브젝트가 업데이트 되고, 구성파일 안에 병합하지 않으면 업데이트 내용은 다음 replace가 될 때 삭제될 것이다. 동일 오브젝트에 대하여 여러 명의 작성자들로부터 지원이 필요할 경우 오브젝트를 관리하기 위해 kubectl apply를 사용할 수 있다.


‣ 실행중인 파드 전체 정의 출력

1. 파드 전체 정의 출력

$ kubectl get pod/kubia-manual -o yaml

2. JSON 형식으로 보고 싶다면 아래처럼

$ kubectl get pod/kubia-manual -o json

‣ Application 로그 확인

  • 존재하는 파드의 컨테이너 로그만 가져올 수 있음
  • 어떠한 웹 요청도 Node.js 서버로 오지 않았기에 서버가 시작할 때 남긴 로그 한 줄만 표시됨.
$ kubectl logs pod/kubia-manual -c kubia

Loading script...