일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- 도커
- Docker
- Kubernetes
- 멀티 쓰레드
- 리스트
- 인프런
- container
- 쓰레드
- 자바 입출력 스트림
- 시작하세요 도커 & 쿠버네티스
- 쿠버네티스
- Thread
- 스레드
- 실전 자바 고급 1편
- 동시성
- filewriter filereader
- LIST
- 자료구조
- java socket
- 자바
- java
- Collection
- 김영한
- 컨테이너
- 도커 엔진
- 자바 io 보조스트림
- Java IO
- 스레드 제어와 생명 주기
- java network
- Today
- Total
쌩로그
[Kubernetes] 쿠버네티스 파드(Pod) 본문
목록
- 포스팅 개요
- 본론
2-1. 파드 사용하기
2-2. 파드 vs. 도커 컨테이너
2-3. 완전한 애플리케이션으로서의 파드 - 요약
1. 포스팅 개요
이 포스팅은 위키북스 출판사의 '시작하세요! 도커/쿠버네티스'의 제 6장 쿠버네티스 시작하기를 학습하며 기록한 포스팅이다.
그 중 컨테이너를 다루는 기본 단위인 Pod에 대한 내용이다.
2. 본론
파드(Pod) : 컨테이너를 다루는 기본 단위
쿠버네티스에는 셀 수도 없을 만큼 많은 리소스 종류와 컴포넌트가 존재한다.
그중에서도 컨테이너 애플리케이션을 구동하기 위해 반드시 알아야 할 몇 가지 오브젝트가 있는데, 바로 파드(Pod), 레플리카셋(Replica Set), 서비스(Service), 디플로이먼트(Deployment)이다.
그중에 가장 기초가 되는 것이 파드디.
2-1. 파드 사용하기
- 쿠버네티스에서는 컨테이너 애플리케이션의 기본 단위를 파드(Pod) 라고 부른다.
- 파드는 1개 이상의 컨테이너로 구성된 컨테이너의 집합이다.
- 파드는 쿠버네티스에서 가장 기초적이고 중요한 개념이기 때문에 반드시 이해하고 넘어가는 것이 좋다.
- 도커 엔진에서는 기본 단위가 도커 컨테이너였고, 스웜 모드에서의 기본 단위는 여러 개의 컨테이너로 구성된 서비스(service)였다.
- 이와 비슷한 맥락으로 쿠버네티스에서는 컨테이너 애플리케이션을 배포하기 위한 기본 단위로 파드라는 개념을 사용한다.
- 1 개의 파드에는 1 개의 컨테이너가 존재할수도 있고, 여러 개의 컨테이너가 존재할 수도 있다.
- 간단한 예시를 들어 Nginx 웹 서비스를 쿠버네티스에서 생성하려면 컨테이너와 파드를 어떻게 사용할 수 있을까?
- 가장 쉬운 방법은 파드 1 개에 Nginx 컨테이너 1 개만을 포함해 생성하는 것다.
- 만약 동일한 Nginx 컨테이너를 여러 개 생성하고 싶다면 1 개의 Nginx 컨테이너가 들어 있는 동일한 파드를 여러 개 생성하면 된다.
- 이처럼 파드는 컨테이너 애플리케이션을 나타내기 위한 기본 구성 요소다.
- 간단한 예시를 들어 Nginx 웹 서비스를 쿠버네티스에서 생성하려면 컨테이너와 파드를 어떻게 사용할 수 있을까?

파드의 개념을 좀 더 정확히 이해하기 위해서 Nginx 컨테이너로 구성된 파드를 직접 생성해보자.
다음 내용을 nginx-pod.yaml 이라는 이름으로 작성하자.
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-pod
spec:
containers:
- name: my-nginx-container
image: nginx:latest
ports:
- containerPort: 80
protocol: TCP
작성한 YAML 파일의 의미는 아래와 같다.
쿠버네티스의 YAML 파일은 일반적으로 apiVersion
, kind
, metadata
, spec 네 가지 항목으로 구성한다.
apiVersion
: YAML 파일에서 정의한 오브젝트의 API 버전을 나타낸다.- 오브젝트의 종류 및 개발 성숙도에 따라
apiVersion
의 설정값이 달라질 수 있다
- 오브젝트의 종류 및 개발 성숙도에 따라
kind
: 이 리소스의 종류를 나타낸다.- 위의 YAML 파일에서 생성하려고 하는 것이 파드이기 때문에
Pod
를 입력했다. kind
항목에서 사용할 수 있는 리소스 오브젝트 종류는kubectl api-resources
명령어의 KIND 항목에서 확인할 수 있다.
- 위의 YAML 파일에서 생성하려고 하는 것이 파드이기 때문에
$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
...
pods po v1 true Pod
metadata
: 라벨 주석(Annotation
), 이름 등과 같은 리소스의 부가 정보들을 입력한다.- 위 예시에서는
name
항목에서 파드의 고유한 이름을my-nginx-pod
로 설정했다.
- 위 예시에서는
spec
: 리소스를 생성하기 위한 자세한 정보를 입력한다.- 위 예시에서는 파드에서 실행될 컨테이너 정보를 정의하는
containers
항목을 작성한 뒤, 하위 항목인image
에서 사용할 도커 이미지를 지정했다. name
항목에서는 컨테이너의 이름을ports
항목에서는 Nginx 컨테이너가 사용할 포트인 80을 입력했다.
- 위 예시에서는 파드에서 실행될 컨테이너 정보를 정의하는
작성한 YAML 파일은 kubectl apply -f
명령어로 쿠버네티스에 생성할 수 있다.
다음 명령어를 사용해 새로운 파드를 생성하자.
$ kubectl apply -f nginx-pod.yaml
pod/my-nginx-pod created
kubectl get〈오브젝트 이름
〉을 사용하면 특정 오브젝트의 목록을 확인할 수 있다.- 예를 들어,
kubectl get pods
명령어는 현재 쿠버네티스에 존재하는 파드의 목록을 출력다. - 방금 생성한 파드 1개가 출력될 것이다.
- 예를 들어,
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-pod 1/1 Running 0 9s
이 Nginx 파드를 생성할 때. YAML 파일에 사용할 포트(containerPort)를 정의하긴 했지만, 아직 외부에서 접근할 수 있도록 노출된 상태는 아니다.
따라서 파드의 Nginx 서버로 요청을 보내려면 파드 컨테이너의 내부 IP로 접근해야 한다.
kubectl describe
명령어를 사용하면 생성된 리소스의 자세한 정보를 얻어올 수 있다.- 예를 들어, 파드의 자세한 정보를 출력하고 싶다면
kubectl describe pods <파드 이름>
처럼 명령어를 사용하면 된다. - 이 명령어로 파드의 IP를 확인해보자.
- 예를 들어, 파드의 자세한 정보를 출력하고 싶다면
$ kubectl describe pods my-nginx-pod
...
Status: Running
IP: 192.168.xx.xx # 일부러 가림(그냥)
Containers:
my-nginx-container:
Container ID: containerd:// ....
Image: nginx:latest
Image ID: docker.io/library/nginx@sha256:...
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 25 Feb 2025 05:19:51 +0000
Ready: True
위처럼 Nginx 파드에 대한 많은 정보가 출력될 것이다.
그중 파드의 IP 항목도 포함돼 있으며, 출력 결과에서 알 수 있듯이 파드의 IP가 나와있다.
- 앞서 말했던 것처럼 이 IP는 외부에서 접근할 수 있는 IP가 아니기 때문에 클러스터 내부에서만 접근할 수 있다.
docker run
명령어에서-p
옵션 없이 컨테이너를 실행한 것과 비슷하다고 생각하면 이해가 쉬울 것이다.- 쿠버네티스 외부 또는 내부에서 파드에 접근하려면 서비스(service)라고 하는 쿠버네티스 오브젝트를 따로 생성해야 한다.
- 지금은 서비스 오브젝트 없이 IP만으로 Nginx 파드에 접근해 보자.
- 클러스터의 노드 중 하나에 접속한 뒤 다음과 같이 Nginx 파드의 IP로 HTTP 요청을 전송하자.
- 이로써 Nginx 파드가 정상적으로 실행 중인 것을 알 수 있다.
$ curl <describe에서 알려주고 있는 IP>
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
참고
클러스터의 노두로 접속하는 것이 여의치 않은 상황이라면 다음 명령어로 클러스터 내부에 테스트용 파드를 생성해 임시로 사용할 수도 있다.
일반적으로 클러스터 내부에서는 파드의 IP로 접근할 수 있다.
$ kubectl run -i --tty --rm debug --image=alicek106/ubuntu:curl --restart=Never bash
If you don\'t see a command prompt, try pressing enter.
root@debug:/# curl <IP>
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@debug:/# exit # 테스트용 파드에서 빠져나오면 삭제된다.
pod "debug" deleted
pod default/debug terminated (Error)
이번에는 파드 컨테이너 내부로 직접 들어가보자.docker exec
명령어와 비슷하게 쿠버네티스에서도 kubectl exec
명령으로 파드의 컨테이너에 명령어를 전달할 수 있다.
예를 들어 다음과 같이 my-nginx-pod
에서 배시 셸을 실행하되, -it
옵션으로 셸을 유지할 수 있다.
# 아래의 명령어를 사용하자. $ kubectl exec -it my-nginx-pod bash
$ kubectl exec my-nginx-pod -i -t -- bash
root@my-nginx-pod:/# ls /etc/nginx/
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
root@my-nginx-pod:/# exit # 파드에서 파져나온다.
도커에서 docker logs
명령어를 사용했던 것처럼 쿠버네티스에서도 kubectl logs
명령어로 파드의 로그를 확인할 수 있다.
다음 명령어를 사용하면 Nginx 파드의 표준 출력 로그를 확인할 수 있다.
Nginx 서버에 접근했던 기록이 출력된다.
$ kubectl logs my-nginx-pod
...
192.168.x.x - - [25/Feb/2025:05:36:21 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0" "-"
192.168.y.y - - [25/Feb/2025:05:42:25 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.35.0" "-"
오브젝트 삭제
쿠버네티스의 오브젝트는 kubectl delete -f
명령어로 쉽게 삭제할 수 있다.
다음 명령어는 nginx-pod.yaml
에 정의된 Nginx 파드를 삭제하는 명령어다.
$ kubectl delete -f nginx-pod.yaml
# or
$ kubectl delete pod <파드 이름>
# 예시 : 필자는 이렇게 지웠다.
$ kubectl delete pod my-nginx-pod
pod "my-nginx-pod" deleted
2-2. 파드 vs. 도커 컨테이너
- 위의 기능들만 놓고 본다면 파드는
docker run
으로 생성한 단일 nginx 컨테이너와 크게 다르지 않아 보이기도 한다. - 파드는
- 컨테이너 IP 주소를 가지고 있어 쿠버네티스 클러스터 내부에서 접근할 수 있고,
kubectl exec
명령어로 파드 컨테이너 내부로 들어갈 수도 있으며,kubectl logs
명령어로 파드의 로그를 확인할 수도 있다.
쿠버네티스는 왜 도커 컨테이너'가 아니라 굳이 '파드'라는 새로운 개념을 사용하는 것일까?
쿠버네티스가 파드를 사용하는 이유는 컨테이너 런타임의 인터페이스 제공 등 여러 가지가 있지만, 그 이유 중 하나는 여러 리눅스 네임스페이스(namespace)를 공유하는 여러 컨테이너들을 추상화된 집합으로 사용하기 위해서이다.
이를 쉽게 이해할 수 있게 파드를 사용하는 예시를 하나 더 살펴보자.
kubectl get pods
명령어로 파드의 목록을 출력했을 때, READY 항목에서 1/1이라는 출력을 봤을 것이다.
Nginx 파드에는 1개의 컨테이너가 정의돼 있으며, 이 컨테이너는 정상적으로 준비됐다는 뜻이다.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-pod 1/1 Running 0 9s
실제로 대부분 쿠버네티스의 컨테이너 애플리케이션은 이처럼 1개의 컨테이너로 파드를 구성해 사용한다.
그런데 1/1이라는 항목에서 알 수 있듯이, 파드는 반드시 1개의 컨테이너로 구성해야하는 것은 아니다.
READY 항목은 파드의 컨테이너 개수에 따라 2/2도 될 수 있고, 3/3도 될 수 있 습니다.
그렇다면 이번에는 Nginx 파드에 새로운 우분투 컨테이너를 추가해 보겠습니다. 이전에 사용한 YAML 파일을 확장해 아래 내용으로 새로운 YAML 파일을 작성하자.
curl
이 미리 설치된 우분투 이미지인 alicekl06/rr-test:curl
을 사용했으며, 이 컨테이너는 종료되지 않기 위해 tail -f /dev/ null
이라는 단순한 동작만을 실행한다.
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-pod
spec:
containers:
- name: my-nginx-container
image: nginx:latest
ports:
- containerPort: 80
protocol: TCP
- name: ubuntu-sidecar-container
image: alicek106/rr-test:curl
command: ["tail"]
args: ["-f", "/dev/null"] # 컨테이너가 종료되지않도록 유지한다.
YAML에서 대시(-
) 를 사용하는 항목은 여러 개의 항목을 정의할 수 있음을 의미한다.
예를 들어 위에서 사용한 spec.containers
의 하위 항목은 "-name: my-nginx-container"
와 같이 대시로 구분되며, 여러 개의 컨테이너를 정의할 수 있다.
따라서 이번에는 파드에 우분투 컨테이너 (ubuntu-sidecar-container
) 를 하나 더 추가했다.
참고
- 파드의 YAML 파일에서 사용되는 command와 args는 컨테이너 내부에서 가장 먼저 실행될 프로세스를 지정한다.
- YAML 파일에서의 command는 도커 컨테이너의 Entrypoint와 동일하고, 파드에서의 args는 도커 컨테이너의 Cmd(커맨드)와 동일하다고 이해하면 쉽다.
앞서 파드를 생성했던 것처럼 kubectl apply -f
명령을 사용해 YAML 파일을 쿠버네티스에 적용한다.
시간이 조금 지나면 Nginx 파드에 2개의 컨테이너가 실행 중인 것을 확인할 수 있다,
$ kubectl apply -f nginx-pod-with-ubuntu.yaml
pod/my-nginx-pod created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-pod 0/2 ContainerCreating 0 13s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-pod 2/2 Running 0 26s
kubectl exec
명령어를 이용해 새롭게 추가된 우분투 컨테이너의 내부로 들어가 보자.kubectl exec
,logs
등과 같은 명령어를 사용할 때는-c
옵션을 이용해 파드의 어떤 컨테이너에 대해 명령어를 수행할지 명시할 수 있다.- 다음 명령어는 앞서 파드에 추가한 컨테이너인
ubuntu-sidecar-container
에서 배시 셸을 실행한다.
# 아래 명령어는 안 된다. 그 아래 것으로 하자.
#$ kubetctl exec my-nginx-pod -i -t -- bash -c ubuntu-sidecar-container
$ kubectl exec my-nginx-pod -c ubuntu-sidecar-container -i -t -- bash
root@my-nginx-pod:/#
ubuntu-sidecar-container
컨테이너 내부에서 로컬호스트로 HTTP 요청을 전송하면 Nginx 서버의 응답이 도착하는 것을 확인할 수 있다.
root@my-nginx-pod:/# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
이전 장에서 도커를 많이 사용해 봤다면 여기에서 뭔가 이상한 것을 눈치챘을 것다.
우분투 컨테이너가 Nginx 서버를 실행하고 있지 않은데도, 우분투 컨테이너의 로컬호스트에서 Nginx 서버로 접근이 가능하다.
이는 파드 내의 컨테이너들이 네트워크 네임스페이스 등과 같은 리눅스 네임스페이스를 공유해 사용하기 때문이다.
참고
네트워크 네임스페이스는 컨테이너의 고유한 네트워크 환경을 제공해주는 역할을 담당한다.
예를 들어 docker run
명령어로 docker0
브리지에 연결된 컨테이너가 생성됐다면, 그 컨테이너는 자기 자신만의 고유한 네트워크 네임스페이스를 가지게 된다.
그렇기 때문에 호스트 및 다른 컨테이너와 다른 고유한 IP를 유지할 수 있는 것이다.
도커의 네트워크 구조에는 docker run --net container:(컨테이너 이름)
옵션을 사용하는 “컨테이너 네트워크" 종류가 있다.
간단하게 상기하자면 컨테이너 네트워크 타입은 네트워크 네임스페이스를 컨테이너 간에 공유해 사용할 수 있도록 설정하기 때문에 여러 개의 컨테이너가 동일한 네트워크 환경을 가지게 된다.
쿠버네티스의 파드 또한 이러한 리눅스 네임스페이스의 공유 개념을 사용하고 있는 것이다.

그러나 파드가 공유하는 리눅스 네임스페이스에 네트워크 환경만 있는 것은 아니다.
1개의 파드에 포함된 컨테이너들은 여러 개의 리눅스 네임스페이스를 공유한다.
즉 “파드 내부의 컨테이너들은 네트워크와 같은 리눅스 네임스페이스를 공유한다”라고 알고 넘어가자.
2-3. 완전한 애플리케이션으로서의 파드
- 실제 쿠버네티스 환경에서는 1개의 컨테이너로 구성된 파드를 사용하는 경우가 많으며, 이후 다룰 대부분의 예시 또한 그러할 것이다.
- 그렇다면 왜 하나의 파드에 여러 개의 컨테이너가 함께 포함돼야 하는지에 대해 의문점이 생길 수도 있다.
- 여기서 한 가지 유의해야 할 점은 '하나의 파드는 하나의 완전한 애플리케이션'이라는 점이다.
Nginx 컨테이너는 그 자체만으로도 완전한 애플리케이션이기 때문에 하나의 파드에 2개의 Nginx 컨테이너가 정의되는 것은 바람직하지 않다.
따라서 우리가 처음에 생성했던 파드에서는 1개의 Nginx 컨테이너만을 정의했다.

컨테이너가 실행되기 위해 부가적인 기능이 필요하다면
- 만약 Nginx 컨테이너가 실행되기 위해 부가적인 기능을 필요로 한다면 어떨까???
- 예를 들어, Nginx의 설정 파일의 변경사항을 갱신해주는 설정 리로더(reloader) 프로세스나 로그를 수집해주는 프로세스는 Nginx 컨테이너와 함께 실행돼야 할 수 있다.
- 이런 경우 파드의 주 컨테이너를 Nginx로 하되, 기능 확장을 위한 추가 컨테이너를 함께 파드에 포함시킬 수 있다.
- 이렇게 파드에 정의된 부가적인 컨테이너를 사이드카(sidecar) 컨테이너라고 부르며, **사이드카 컨테이너는 파드 내의 다른 컨테이너와 네트워크 환경 등을 공유한다.
- 때문에 파드에 포함된 컨테이너들은 모두 같은 워커 노드에서 함께 실행된다.
이러한 구조 및 원리에 따라 파드에 정의된 여러 개의 컨테이너는 하나의 완전한 애플리케이션으로서 동작하게 된다.
이것이 도커 컨테이너와 쿠버네티스 파드의 차이점이다.
참고
파드의 네트워크 네임스페이스는 Pause
라는 이름의 컨테이너로부터 네트워크를 공유받아 사용한다.Pause
컨테이너는 네임스페이스를 공유하기 위해 파드별로 생성되는 컨테이너이며, Pause
컨테이너는 각 파드에 대해 자동으로 생성된다.
$ ps aux | grep pause
...
65535 22318 0.0 0.0 996 512 ? Ss 05:06 0:00 /pause
...
도커 엔잔을 컨테이너 런타임으로 쓰고 있다면 docker ps 명령어로 pause 컨테이너를 직접 확인할 수 있다.
$ docker ps | grep nginx
# 나는 나오지 않는다.
3. 요약
- 컨테이너 애플리케이션의 기본 단위를 파드(Pod) 라고 부른다.
- 파드는 1개 이상의 컨테이너로 구성된 컨테이너의 집합이다.
- 하나의 파드는 하나의 완전한 애플리케이션이라는 컨셉을 가진다.
- 파드 내의 컨테이너들은 네트워크 네임스페이스 등과 같은 리눅스 네임스페이스를 공유해서 사용한다.
- 파드에 정의된 부가적인 컨테이너를 사이드카(sidecar) 컨테이너라고 부르며, 사이드카 컨테이너는 파드 내의 다른 컨테이너와 네트워크 환경 등을 공유한다.
Pod에 대해 알아보면서 사용해봤고 도커의 컨테이너와는 어떻게 다른지, 어떤 컨셉을 가지는 지 알아봤다.
'Deploy > Kubernetes' 카테고리의 다른 글
[Kubernetes] 쿠버네티스 디플로이먼트(Deployment) (0) | 2025.03.04 |
---|---|
[Kubernetes] 쿠버네티스 레플리카셋(ReplicaSet) (14) | 2025.02.25 |
[Kubernetes] 쿠버네티스 설치 (1) | 2025.02.25 |
[Kubernetes] 쿠버네티스 시작 전 알고가기 (1) | 2025.02.25 |
[Kubernetes] 쿠버네티스의 특징 (0) | 2025.02.24 |