본문 바로가기
Framework and Tool/Kubernetes

Kubernetes - Pod

by ocwokocw 2022. 10. 9.

- 출처: Kubernetes in action

- 파드

파드는 하나 이상의 컨테이너 그룹이다. 쿠버네티스는 컨테이너를 개별적으로 배포하지 않으며 컨테이너 그룹인 파드를 배포 및 운영한다. 파드에 속한 컨테이너 그룹은 하나의 워커 노드에 배포된다. 즉 파드 내의 컨테이너들은 각각 다른 워커 노드에 배포되지 않는다.
 
단순히 기술적인 관점에서는 여러 프로세스를 하나의 컨테이너에서 실행시킬 수 있다. 하지만 이 방법은 권고되지 않는다.
 
컨테이너는 단일 프로세스를 실행할 목적으로 설계되었다. (자식 프로세스를 생성하는 경우는 예외) 만약 단일 컨테이너에서 여러 프로세스를 실행하면 아래와 같은 문제가있다.
 
  • 여러 프로세스가 로그를 동일 표준 출력에 기록하면 관리하기가 난해하다.
  • 프로세스별로 재시작하는 매커니즘을 원한다면 수동으로 구현해야 한다.
 
따라서 각 프로세스를 개별 컨테이너로 실행하는것이 도커와 쿠버네티스를 올바르게 사용하는 방법이다.
 

- 파드의 특징

앞에서 각 프로세스를 개별 컨테이너로 실행하는것이 올바른 방법이라고 했다. 하지만 이런 컨테이너 그룹을 관리할 수 있는 어떤 것이 필요하기도한데 이를 파드로 정했다. 컨테이너의 모든 기능은 누리면서 프로세스가 함께 실행되는것처럼 보이는 뷰도 갖게된것이다.
 
동일 파드내의 컨테이너들은 특정 리소스를 공유하기 위해 완벽하게 격리 되지는 않는다. 파드 내의 모든 컨테이너는 동일한 리눅스 네임 스페이스를 공유하도록 도커를 설정한다. 컨테이너간 어떤 네임 스페이스는 동일한것을 공유하며 어떤 네임 스페이스는 격리된다.
 
  • 동일 네임 스페이스: 네트워크 네임 스페이스, UTS 네임 스페이스, IPC 네임 스페이스
  • 분리된 네임 스페이스: 파일 시스템
 
네트워크, UTS를 공유 하므로 같은 호스트 이름과 네트워크 인터페이스를 공유한다. 하지만 파일 시스템은 다른 컨테이너와 분리된다.
 
파드 내 컨테이너들은 같은 네트워크 네임 스페이스를 공유 하므로 프로세스의 포트번호를 다르게 설정해야 한다. 또한 동일한 루프백 인터페이스를 공유하므로 로컬 호스트를 통해 서로 통신이 가능하다.
 
클러스터내의 모든 파드는 flat한 공유 네트워크 주소공간에 있으므로 모든 파드는 서로의 IP 주소를 이용해 접근할 수 있다. 이때 파드가 서로 같은 워커노드인지 여부와는 상관이 없다.
 

- 파드와 컨테이너 구성

파드를 머신의 개념으로 이해할수도 있지만 특정 앱만 호스팅한다고 이해하는것이 더 정확한 관점이다. 파드는 가벼워서 오버헤드가 적기 때문에 모든 것을 하나의 파드에 몰아넣기 보다는 앱을 여러 파드에 구성하는것이 더 일반적이며 적절하다.
 
쿠버네티스 환경이 아닌 전통적인 환경에서는 앱을 구성할 때 3 tier 구조(Web - WAS - DB)를 사용하는 경우가 많다. 만약 Web과 DB 계층만 있는 앱을 쿠버네티스에 배포한다고 생각해보자. 이를 하나의 파드에 배포할 수 있을까?
 
기술적으로는 가능하지만 좋은 방법은 아니라고볼 수 있다. 이는 쿠버네티스 환경이 아니라도 마찬가지다. 만약 하나의 파드에 배포하면 Web과 DB가 언제나 같은 워커 노드에서 실행된다. 클러스터내의 노드가 여러 대라도 언제나 1대의 노드에만 배포되는것이다. (여유 분의 워커노드를 활용할 수 없다.)
 
각각 파드로 분리하면 개별적으로 확장(scaling) 할 수 있는 이점이 있다. 특정 파드에 부하가 더 생긴다면 특정 파드만 확장할 수 있다. 만약 하나의 파드에 이 둘은 모두 배포하면 특정 파드만 확장하고 싶어도 의도하지 않은 파드도 같이 확장해야 한다.
 
그렇다고 해서 파드에 여러 컨테이너를 사용하는 경우가 아예 없는 것은 아니다. 보통 이를 활용하는 경우는 주요 프로세스에 보완 프로세스가 붙는 경우이다.
 
예를 들어 파일을 제공는 웹서버의 경우 아래와 같이 구성할 수 있다.
 
  • 주 컨테이너: 파일을 제공하는 웹 서버
  • 추가 컨테이너(사이드카 컨테이너): 외부소스에서 주기적으로 컨텐츠를 받아 웹서버 디렉터리에 저장
 
사이드카 컨테이너 같은 경우 서비스에 필수적인 기능 말고도 로그의 데이터를 수집하는것과 같이 운영 관련된 기능을 구성하는데에도 응용이 가능하다.
 
그렇다면 이를 어떻게 판단하는가?
 
  • 함께 실행이 되야 하는지 여부
  • 서로 다른 호스트에서 실행 가능한지 여부
  • 확장이 함께 되어야하는지 개별적으로 되어야하는지 여부
 
위의 나열한점에 대해서 생각해봐도 잘 모르겠다면 일단 분리하여 구성하는것이 좋다.
 

- YAML or JSON 디스크립터로 파드 생성

이전까지는 kubectl create 명령어로 디플로이먼트 리소스를 생성하는 방식으로 파드를 생성했다. 하지만 이는 제한적이며 일반적으로는 yaml이나 json 형식의 매니페스트에 기술한다. 그러면 Control Panel(마스터 노드)의 API 서버가 이 파일을 받아서 적절한 처리를 한다. 매니페스트 파일은 제한사항이 적다는것 이외에도 설정 관련한 버전관리가 되는 측면에서도 도움이 된다.
 
이미 생성된 파드의 yaml 디스크립터를 살펴보자.
 
 
 
매우 긴 항목들이 나올것이다. 만약 yaml을 통해 파드를 생성하려면 이 정보들을 다 집어넣어야 하나? 라는 생각이 들수도 있지만 조회한 모든 항목을 모두 기술해야 하는건 아니다.
 
당장은 yaml 속성 모두를 자세히 알 필요는 없다. 파드를 구성하는 주요한 부분만 살펴보자. 거의 모든 쿠버네티스 리소스는 3 가지 주요한 항목을 갖는다.
 
  • Metadata: 이름, 네임스페이스, 레이블 및 파드에 관한 기타 정보
  • Spec: 파드 컨테이너, Volume, 기타 데이터 등 파드 자체에 관한 실제 명세
  • Status: 파드 상태(현재 실행중인 파드에 관한 정보)
 
조회한 파드의 yaml은 위와 같이 복잡하지만 파드를 생성하기 위해 작성할때에는 모든 정보를 기술할 필요가 없다고 했다. 파드를 생성하는 yaml 파일을 작성해보자.
 
apiVersion: v1
kind: Pod # Object type
metadata:
  name: kubia-manual # Pod name
spec:
  containers:
  - image: ocwokocw/kubia # container image source
    name: kubia # container name
    ports:
    - containerPort: 8080 # app port
      protocol: TCP
 
파드를 생성할때는 조회했을 때 보다 훨씬 간단한 항목만 기술한다. 각 항목이 의미하는 바는 주석을 참조한다.
 
다만 한 가지 언급할 점이 있는데 ports 정의안에서 지정한 포트는 단지 정보성에 불과하다. 다른 client가 포트를 통해 접속하는데 영향을 미치지 않는다. 그럼에도 기술하는 이유는 클러스터를 사용하는 다른 사람이 편리하게 파악할 수 있기 때문이다.
 
"kubectl create" 명령어를 이용하면 yaml 파일을 기반으로 파드를 생성할 수 있다.
 
 
 
파드에 관한 정보를 조회하면 "kubectl create" 명령어를 통해 디플로이먼트를 생성한것과 비슷한 정보를 담고 있는걸 확인할 수 있다. "kubectl get pod"를 통해 파드가 올바르게 동작하고 있는지 확인한다.
 
 

- 앱 로그

컨테이너화된 앱은 로그를 기록할 때 파일보다 표준 출력이나 표준 에러에 남기는게 일반적이다. 컨테이너 런타임(예제의 경우 docker)가 이 스트림을 파일로 전달하면 명령어를 통해 로그를 조회할 수 있게 된다.
 
docker의 경우 "docker logs [컨테이너 ID]"를 통해 로그를 조회할 수 있다. 이렇게 조회하려고 할 경우 ssh를 이용해 파드에 접속한 후에 해당 명령어를 수행해야하지만 쿠버네티스는 별도의 명령어를 제공한다.
 
만약 파드의 로그를 보고 싶다면 "kubectl logs [파드 이름]"으로 조회한다.
 
 
 
또한 파드 내의 컨테이너가 여러 개인 경우를 위해 파드 내 특정 컨테이너 로그만 조회하는 명령어도 제공한다. "kubectl logs [파드이름] -c [컨테이너 이름]" 명령어를 실행한다.
 
 
 

- 파드로 요청 보내기

tutorial 에서 앱의 동작을 확인하기 위해 쿠버네티스의 서비스 오브젝트를 통해 앱을 노출했었다. 이렇게 하면 파드에 요청을 보낼 수 있지만 쿠버네티스는 포트 포워딩을 통해 테스트와 디버깅 목적으로 연결할 수 있는 방법도 제공한다.
 
포트 포워딩을 통해 파드에 연결하고 싶다면 "kubectl port-forward" 명령어를 통해 로컬 포트를 특정 파드로 포워딩 하도록 설정해야 한다.
 
 
 
다른 터미널을 켜고 "curl localhost:8888" 명령어를 실행한다.
 
 
 
curl 요청을 보내면 kubectl port-forward 프로세스가 8888포트 수신을 대기하고 있다가 이 요청을 쿠버네티스 클러스터내의 파드로 넘겨준다. kubectl port-forward 프로세스는 파드의 응답을 받아서 다시 curl에 넘겨준다.
 
 

'Framework and Tool > Kubernetes' 카테고리의 다른 글

Kubernetes - Namespace  (0) 2022.10.09
Kubernetes - Label 및 Annotation  (0) 2022.10.09
Kubernetes - deploy app tutorial  (0) 2022.10.06
Kubernetes - cluster 생성  (0) 2022.10.06
Kubernetes - Docker basic  (0) 2022.10.06

댓글