Pod

유웅조·2020년 9월 8일
0

kubernetes

목록 보기
1/4

파드: 쿠버네티스에서 컨테이서 실행

파드 소개

파드는 노드 안에 배치된 컨테이너의 그룹이며, 쿠버네티스의 기본 빌딩 블록이다.

컨테이너를 개별적으로 배포하기보다는 컨테이너를 가진 파드를 배포하고 운영한다.

이론적으로 파드는 여러 개의 컨테이너를 포함할 수 있지만, 일반적으로 파드는 하나의 컨테이너만 포함한다.

파드의 핵심 사항은 파드가 여러 컨테이너를 가지고 있을 경우에, 각각의 컨테이너가 다른 워커 노드에서 실행되는 것이 아니라 하나의 워커 노드에서 실행된다는 것이다.

파드가 필요한 이유?

컨테이너를 직접 사용해도 되는데 굳이 파드를 사용하는 이유는 무엇일까?

여러 프로세스를 실행하는 단일 컨테이너보다 다중 컨테이너가 낫다

같은 노드에서 IPC 혹은 로컬 파일을 통해 통신하는 여러 프로세스로 구성된 애플리케이션을 예로 들어본다.

쿠버네티스에서는 프로세스를 항상 컨테이너에서 실행시킨다. 그리고 각 컨테이너는 일종의 VM과 비슷하기에 여러 프로세스를 단일 컨테이너 안에서 실행하는 것이 타당하다고 생각할 수 있지만, 실제로는 그렇지 않다.

컨테이너는 단일 프로세스를 실행하는 것을 목적으로 설계했다(자식 프로세스를 생성하는 것을 제외하고). 단일 컨테이너에서 다른 프로세스를 실행시키는 경우, 모든 프로세스의 실행, 로그 관리는 모두 사용자 책임이다. 프로세스가 죽을 경우의 자동 재시작을 직접 설정해야 하고, 로그 출력을 구분할 수 없다.

파드 이해해보기

여러 프로세스를 단일 컨테이너로 묶지 않는다면, 각각의 컨테이너를 관리할 수 있는 또 다른 상위 구조가 필요하다. 이게 바로 파드가 필요한 이유이다.

파드를 사용해서 서로 연관된 프로세스를 함께 실행하고, 마치 단일 컨테이너 안에서 실행되는 것처럼 거의 동일한 환경을 제공할 수 있으면서도 이들을 격리된 상태로 유지할 수 있는 장점이 있다.

같은 파드에서 컨테이너 간 부분 격리

쿠버네티스에서는 파드 안에 있는 모든 컨테이너가 자체 네임스페이스가 아닌 동일한 리눅스 네임스페이스를 공유하도록 도커를 설정한다.

파드의 모든 컨테이너는 동일한 네트워크 네임스페이스와 UTS 네임스페이스 안에서 실행되기 때문에 모든 컨테이너는 같은 호스트 이름과 네트워크 인터페이스를 공유한다.

비슷하게 파드의 모든 컨테이너는 동일한 IPC 네임스페이스 아래에서 실행되 IPC를 통해 서로 통신할 수 있다.

하지만 파일 시스템에서는 조금 다르다. 대부분의 컨테이너 파일 시스템은 컨테이너 이미지에서 나오기 때문에 기본적으로 파일 시스템은 다른 컨테이너와 완전히 분리된다. 그러나 쿠버네티스의 불륨을 이용해 컨테이너가 파일 디렉토리를 공유하는 것이 가능하다.

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

여기서 중요한 점은 파드 안의 컨테이너가 동일한 네트워크 네임스페이스에서 실행되기 때문에 동일한 IP 주소와 포트 공간을 공유한다는 것이다.

그렇기 때문에 동일한 파드 안 컨테이너에서 실행 중인 프로세스가 같은 포트 번호를 사용하지 않도록 주의해야 한다는 것을 유의해야 한다. 그렇지 않으면 포트 충돌이 발생할 수 있다.

또한 파드 안에 있는 모든 컨테이너는 동일한 루프백 네트워크 인터페이스를 갖기 때문에 컨테이너들이 로컬호스트를 통해 서로 통신할 수 있다.

파드 간 플랫 네트워크 소개

쿠버네티스 클러스터의 모든 파드는 하나의 플랫한 공유 네트워크 주소 공간에 상주하므로 모든 파드는 다른 파드의 IP 주소를 사용해 접근하는 것이 가능하다.

둘 사이에는 어떠한 NAT도 존재하지 않고, 두 파드가 서로 네트워크 패킷을 보내면, 상대방의 실제 IP 주소를 패킷 안에 있는 출발지 IP 주소에서 찾을 수 있다.

결과적으로 파드 사이에서 통신은 항상 단순하다. 두 파드가 동일한 혹은 다른 워커 노드에 있는지는 중요하지 않고, 두 경우 모두 파드 안에 있는 컨테이너는 NAT 없는 플랫 네트워크를 통해 서로 통신하는 것이 가능하다.

이는 마치 LAN에 있는 컴퓨터 간의 통신과 비슷하다. LAN 상에 있는 컴퓨터처럼 각 파드는 고유 IP를 가지며 모든 다른 파드에서 이 네트워크를 통해 접속할 수 있다.

요약하자면, 파드는 논리적인 호스트로서 환경에서의 물리적 호스트 혹은 VM과 매우 유사하게 동작한다는 것이다. 동일한 파드 안에서 실행한 프로세스는 각 프로세스가 컨테이너 안에 캡슐화돼 있다는 점을 제외하면, 앞선 예와 유사하다.

파드에서 컨테이너의 적절한 구성

파드는 특정한 애플리케이션만을 호스팅한다.

파드는 상대적으로 가볍기 때문에 오버헤드 없이 필요한 만큼 파드를 가질 수 있다.

모든 것을 파드 하나에 넣는 대신에 애플리케이션을 여러 파드로 구성하고, 각 파드에는 밀접하게 관련 있는 구성 요소나 프로세스만 포함해야 한다.

다계층 애플리케이션을 여러 파드로 분할

프론트엔드 서버와 데이터베이스 컨테이너 두 개로 구성된 단일 파드를 실행하지 못할 것은 없지만 적절한 방법은 아니다.

이는 프론트엔드 서버와 데이터베이스가 같은 머신에서 실행되어야만 하는가에 대한 답을 찾아보면 조금 더 쉽게 알 수 있다.

만약 하나의 클러스터에 두개의 워커 노드가 있다면 위의 서버를 각각 하나의 노드에 다른 파드로 분리해서 스케줄링하면 인프라스트럭쳐의 활용도를 향상시킬 수 있다.

개별 확장이 가능하도록 여러 파드로 분할

파드는 스케일링의 기본 단위다. 쿠버네티스는 개별 컨테이너가 아닌 전체 파드를 수평으로 확장한다.

일반적으로 프론트엔드 구성 요소는 백엔드와 완전히 다른 스케일링 요구 사항을 갖고 있어 개별적으로 확장하는 경향이 있다. 데이터베이스, 백앤드는 프론트엔드 웹 서버에 비해 활장하기가 어렵다.

이처럼 컨테이너를 개별적으로 스케일링하는 것이 필요하다면, 별도 파드에 배포해야 한다.

파드에서 여러 컨테이너를 사용하는 경우

여러 컨테이너를 단일 파드에 넣는 주된 이유는 애플리케이션이 하나의 주요 프로세스와 하나 이상의 보완 프로세스로 구성된 경우다.

예를 들어, 파드 안에 주 컨테이너는 특정 디렉토리에서 파일을 제공하는 웹 서버일 수 있고, 추가 컨테이너는 로그 로데이터와 수집기, 데이터 프로세서, 통신 어뎁터, 외부에서 소스를 주기적으로 받아 저장한느 등으로 활용될 수 있다.

파드에서 여러 컨테이너를 사용하는 경우 결정

파드를 만들 때, 두 개의 컨테이너를 단일 파드로 넣을지, 두 개의 별도 파드에 넣을지를 결정해야 한다. 그러기 위해서 다음과 같은 질문이 도움이 된다.

  • 컨테이너를 함께 실행해야 하는가, 혹은 서로 다른 호스트에서 실행할 수 있는가?
  • 여러 컨테이너가 모여 하나의 구성 요소를 나타내는가, 혹은 개별적인 구성 요소인가?
  • 컨테이너가 함께, 혹은 개별적으로 스케일링돼야 하는가?

파드를 정의하는 주요 부분

파드 정의는 몇 부분으로 구성된다. 먼저 YAML에서 사용하는 쿠버네티스 API 버전과 YAML이 설명하는 리소스 유형이 있다. 이어서 거의 모든 쿠버네티스 리소스가 갖고 있는 세 가지 중요한 부분이 있다.

- Metadata: 이름, 네임스페이스, 레이블 및 파드에 관한 기타 정보를 포함한다. 
- Spec: 파드 컴테이너, 볼륨, 기타 데이터 등 파드 자체에 관한 실제 명세를 가진다. 
- Status: 파드 상태, 각 컨테이너 설명과 상태, 파드 내부 IP, 기타 기본 정보 등 현재 실행 중인 파드에 관한 현재 정보를 포함한다. 

레이블을 이용한 파드 구성

마이크로 서비스 아키텍처의 경우 배포된 마이크로서비스의 수는 매우 쉽게 20개를 초과한다. 이로 인해 시스템에 수백 개 파드가 생길 수 있다. 파드를 정리하는 메커니즘이 없다면, 크고 이해하기 어려운 구조가 되기가 쉽다. 따라서 파드를 부분 집합으로 분류할 필요가 있다.

레이블은 파드와 모든 다른 쿠버네티스 리소스를 조직화할 수 있는 단순하면서 강력한 쿠버네티스 기능이다.

리소스에 첨부하는 키-값 쌍으로 레이블 셀렉터를 사용해 리소스를 선택할 때 활용된다.

파드뿐만 아니라, 노드에도 레이블을 부착할 수 있는데, 노드가 제공하는 하드웨어나 파드를 스케줄링할 때 유용하게 사용할 수 있는 기타 사항을 레이블로 지정해 노드를 분류한다.

예를 들어 클러스터에 범용 GPU 컴퓨팅에 사용할 수 있는 GPU를 가지고 있는 노드가 있다고 가정했을 때, gpu=true와 같은 레이블을 노드에 추가할 수 있다.

네임스페이스를 사용한 리소스 그룹화

레이블을 이용해 파드와 다른 오브젝트를 그룹으로 묶을 수 있다. 그렇기 때문에 오브젝트 그룹은 서로 겹쳐질 수 있다.

또한 클러스터에서 작업을 수행할 때 레이블 셀렉터를 명시적으로 지정하지 않으면 항상 모든 오브젝트를 보게 된다.

그렇다면 오브젝트를 겹치지 않는 그룹으로 분할하고자 할 때는 어떻게 해야 할까?

한번에 하나의 그룹 안에서만 작업하고 싶을 것이다.

그럴 땐 오브젝트를 네임스페이스로 그룹화한다. 여기서의 네임스페이스는 프로세스를 격리하는데 사용하는 리눅스 네임스페이스는 아니다.

쿠버네티스 네임스페이스는 오브젝트 이름의 범위를 제공한다.

네임스페이스를 이용하면 리소스를 프로덕션, 개발, QA 환경 혹은 원하는 다른 방법으로 나누어 구분할 수 있다.

네임스페이스를 통해 오브젝트를 별도 그룹으로 분리해 특정한 네임스페이스 안에 속한 리소스를 대상으로 작업할 수 있게 해주지만, 실행 중인 오브젝트에 대한 격리는 제공하지 않는다.

예를 들어, 다른 사용자들이 서로 다른 네임스페이스에 파드를 배포할 때 해당 파드가 서로 격리돼 통신할 수 없다고 생각할 수 있지만, 반드시 그런 것은 아니다. 만약 쿠버네티스와 함께 배포하는 네트워킹 솔루션이 네임스페이 간의 격리를 제공하지 않는 경우, 만약 서로 다른 네임스페이스 하의 파드가 서로의 IP 주소를 알고 있다면 네트워크 통신을 할 수 있다.

0개의 댓글