파드

blackdog·2021년 10월 4일
0

book-k8s-in-action

목록 보기
2/3

3.1 파드 소개

  • 파드는 함께 배치된 컨테이너 그룹이며 쿠버네티스의 기본 빌딩 블록이다.
  • 쿠버네티스는 컨테이너를 개별적으로 배포하기보다는 컨테이너를 가진 파드를 배포하고 운영한다.
  • 일반적으로 파드는 하나의 컨테이너만 포함한다.
  • 파드가 여러 컨테이너를 가지고 있을 경우에 모든 컨테이너는 항상 하나의 워커 노드에서 실행되며, 여러 워커 노드에 걸쳐 실행하지 않는다.

3.1.1 파드가 필요한 이유

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

  • 컨테이너는 단일 프로세스를 실행하는 것을 목적으로 설계
  • 컨테이너의 프로세스는 동일한 표준 출력으로 로그를 기록하게 되는데, 컨테이너 안에 여러 프로세스가 섞이면 어떤 프로세스의 로그인지 구분이 힘들다.
  • 개별 프로세스가 실패하면 재시작하는 매커니즘이 필요한데, 단일 프로세스로 구분하는게 구현이 쉽다.

3.1.2 파드 이해하기

요약 : 파드는 논리적인 호스트이다. 동일한 파드에서 실행한 프로세스는 각 프로세스가 컨테이너 안에 캡슐화되어 있는 점을 제외하면, 같은 물리적 머신에서 동작하는 것과 동일하다.

  • 여러 프로세스를 단일 컨테이너로 묶지 않기 때문에, 컨테이너를 함께 묶고 하나의 단위로 관리할 수 있는 구조가 필요
  • 컨테이너 모음(파드)를 통해 연관된 프로세스를 함께 실행하면서, 각 프로세스는 단일 컨테이너 안에서 실행되는 것처럼 환경을 제공한다.
  • 하지만 각 컨테이너는 격리되어 있기 때문에, 격리되어 있지만 논리적으로 하나의 서비스처럼 묶어서 구분하게 된다.

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

  • 그룹 안에 있는 컨테이너는 특정한 리소스를 공유하기 위해서 완벽하게 격리되지 않도록 한다.
  • 쿠버네티스는 카드 안에 있는 모든 컨테이너가 동일한 리눅스 네임스페이스를 공유하도록 도커를 설정한다.
  • 동일한 네트워크 네임스페이스와 UTS 네임스페이스 안에서 실행되기 때문에 같은 호스트 이름과 네트워크 인터페이스를 공유한다.
  • 파일 시스템은 조금 다른데, 대부분의 컨테이너 파일 시스템은 다른 컨테이너와 분리된다. 그래서 쿠버네티스 볼륨을 이용한다.

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

  • 파드 내의 컨테이너들은 동일한 네트워크 네임스페이스에서 실행되기 때문에 프로세스 간 포트가 겹치지 않도록 주의해야 한다.
  • 파드 안의 컨테이너들은 동일한 루프백 네트워크 인터페이스를 갖기 때문에 컨테이너들이 로컬호스트를 통해 서로 통신 가능하다.

파드 간 플랫 네트워크 소개

  • 쿠버네티스 클러스터의 모든 파드는 하나의 플랫한 공유 네트워크 주고 공간에 상주한다.
  • 모든 파드는 다른 파드의 IP 주소를 사용해 접근하는 것이 중요하다.
  • 어떠한 NAT도 존재하지 않는다.
  • 두 파드가 동일 혹은 다른 워커에 있는지 여부에 상관 없이 통신이 가능하다.

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

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

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

프론트엔드 서버와 데이터베이스 컨테이너를 한 파드에 넣고 실행하면 어떤 단점이 있을까? 둘은 항상 같은 노드에서 실행된다. 만약에 두 노드가 있으면 한 노드에만 배포가 되게 된다. 만약에 여러 파드로 나눴다면 각 노드에서 따로 동작하며 모든 노드의 리소스를 사용할 수 있었을 것이다.

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

  • 파드는 스케일링의 기본 단위
  • 개별 컨테이너는 수평으로 확장할 수 없다.
  • 여러 컨테이너가 들어간 파드를 수평 확장하게 되면 파드에 있는 모든 컨테이너들이 같이 확장될 것이다.
  • 컨테이너를 개별적으로 확장하는 것이 필용하면, 별도 파드에 배포해야 한다.

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

  • 애플리케이션이 하나의 주요 프로세스와 하나 이상의 보완 프로세스로 구성된 경우에만 파드에 여러 컨테이너를 넣는다.
  • 보완 프로세스를 사이드카 컨테이너라고 하는데, 로그 로테이터, 로그 수집, 데이터 프로세서, 통신 어댑터 등이 있다.

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

다음 질문을 할 필요가 있다.

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

3.2 YAML 또는 JSON 디스크립터로 파드 생성

  • 파드를 포함한 다른 쿠버네티스 리소스는 일반적으로 쿠버네티스 REST API에 매니페스트를 전송해 생성한다.
  • 매니페스트는 YAML 또는 JSON 형식으로 작성할 수 있다.
  • 매니페스트를 파일로 관리하게 되면 버전 관리 시스템에 넣어 버전 관리가 가능해지는 이점이 있다.

3.2.1 기존 파드의 YAML 디스크립터 살펴보기

파드를 정의하는 주요 부분 소개

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

3.2.2 파드를 정의하는 간단한 YAML 정의 작성

컨테이너 포트 지정

  • YAML 파일에서 포트 지정을 생략해도 다른 클라이언트에서 포트를 통해 파드에 연결할 수 있다.
  • 포트를 명시적으로 정의하면 포트에 이름을 지정해서 편하게 사용할 수 있다.

3.2.3 kubectl create 명령으로 파드 만들기

3.2.4 애플리케이션 로그 보기

  • 컨테이너화된 애플리케이션은 로그를 파일에 쓰기 보다는 표준 출력과 표준 에러에 로그를 남기는게 일반적
  • 도커는 이 로그를 컨테이너에서 docker logs <container id> 커맨드를 사용하여 가져옴
  • 쿠버네티스에서는 kubectl logs <pod name> 을 이용하여 가져옴
  • 다중 컨테이너로 이루어진 파드에서는 컨테이너 이름을 지정하여 특정 컨테이너의 로그를 가져올 수 있다.
  • 파드가 삭제되면 해당 로그도 같이 삭제되기 때문에, 파드가 삭제된 후에도 파도의 로그를 보기 위해서는 모든 로그를 중앙 저장소에 저장하는 클러스터 전체의 중앙집중식 로깅을 설정해야 한다.

3.2.5 파드에 요청 보내기

  • 포트 포워딩을 사용하여 일시적으로 파드를 외부에 노출시킬 수 있다. (테스트 및 디버깅)

3.3 레이블을 이용한 파드 구성

  • 파드 수가 증가함에 따라서 파드를 부분 집합으로 분류할 필요가 있다.
  • 집합을 나누기 위해 레이블을 사용

3.3.1 레이블 소개

  • 레이블은 리소스에 첨부하는 K-V이다.
  • 레이블 셀렉터를 사용해 리소스를 선택할 때 활용한다.
  • OS 버전, 배포 방식, 앱의 기능 등 분류에 따라서 동일 리소스에 중첩 설정이 가능하다.

3.3.2 파드를 생서할 때 레이블 지정

3.3.3 기존 파드 레이블 수정

3.4 레이블 셀렉터를 이용한 파드 부분 집합 나열

레이블 셀렉터는 특정 레이블로 태그된 파드의 부분 집합을 선택해 원하는 작업을 수행한다. 레이블 셀렉터는 리소스 중에서 다음 기준에 따라서 리소스를 선택한다.

  • 특정한 키를 포함하거나, 포함하지 않는 레이블
  • 특정한 키와 값을 가진 레이블
  • 특정한 키를 갖고 있지만, 다른 값을 가진 레이블

3.4.1 레이블 셀렉터를 사용해 파드 나열

여러 조건을 거는 것도 가능하다.

$ kubectl get po -l key=value
$ kubectl get po -l key!=value
$ kubectl get po -l key in (value1, value2)
$ kubectl get po -l key notin (value1, value2)

3.5 레이블과 셀렉터를 이용해 파드 스케줄링 제한

  • 파드를 스케줄링할 노드(머신)을 지정하고 싶을 때 레이블과 셀렉터를 이용할 수 있다.
  • 쿠버네티스의 아이디어는 인프라를 숨기는 것이기 때문에 노드를 특정하는 방식보다는, 원하는 노드 요구사항을 기술하여 그 요구사항에 맞는 노드에 파드가 스케줄링 될 수 있도록 관리하는 방식이 좋다.

3.5.1 워커 노드 분류에 레이블 사용

  • 노드에도 레이블을 사용할 수 있다.

3.5.2 특정 노드에 파드 스케줄링

  • 파드의 YAML 파일에 스케줄링을 원하는 노드의 레이블을 지정한다.

3.5.3 하나의 특정 노드로 스케줄링

  • 노드 이름 정보를 갖고 있는 레이블도 있기 때문에 파드를 특정한 노드로 스케줄링 하는 것도 가능은 하다.
  • 하지만 노드 역시 파드처럼 언제든 사라질 수 있기 때문에, 좋은 방법은 아니다.
  • 레이블 셀렉터를 통해서 지정한 특정 기준을 만족하는 노드의 논리적인 그룹을 생각해야 한다. (조건을 많이 걸면 되겠네)

3.6 파드에 어노테이션 달기

  • 어노테이션은 레이블처럼 K-V 쌍으로 비슷하지만, 식별 정보를 갖지 않는다.
  • 그래서 셀렉터도 없다.
  • 파드나 다른 개별 리소스에 설명을 추가해두는 용도로 사용한다. (만든 사람 이름 등)

3.6.1 오브젝트의 어노테이션 조회

3.6.2 어노테이션 추가 및 수정

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

  • 쿠버네티스 클러스터에 있는 오브젝트를 개념적으로 그룹화 할 필요가 있다.
  • 레이블 셀렉터로 필터링 해도 조건에 맞는 모든 오브젝트가 검색이 될 것이다.
  • 그래서 쿠버네티스의 오브젝트를 위한 네임스페이스 기능을 제공한다.
  • 분리된 네임스페이스에서는 같은 리소스 이름을 사용할 수 있다.

3.7.1 네임스페이스의 필요성

  • 복잡한 시스템을 좀 더 작은 개별 그룹을 분리할 수 있다.
  • 멀티테넌트 환경처럼 리소스를 분리하는 데 사용할 수 있다. (권한 부여도 네임스페이스 기준으로 하면 되겠지?)
  • 리소스를 프로덕션, 개발, QA 환경 혹은 원하는 다른 방법으로 나누어 사용할 수 있다.
  • 리소스 이름은 네임스페이스 안에서만 고유하면 된다.

3.7.2 다른 네임스페이스와 파드 살펴보기

  • 여러 사용자 또는 그룹이 동일한 클러스터를 사용하고 있더라도, 각자 리소스를 관리한다면 각자 다른 네임스페이스를 사용해야 한다.
  • 네임스페이스를 기준으로 접근 권한과, 컴퓨팅 리소스 제한을 할 수 있다.

3.7.3 네임스페이스 생성

  • yaml 파일에서 지정 가능

3.7.4 다른 네임스페이스의 오브젝트 관리

  • --namespace 또는 -n 플래그를 kubectl에 전달하여 설정 가능
  • 네임스페이스를 지정하지 않으면 kubectl 컨텍스트에 설정되어 있는 기본 네임스페이스를 기준으로 작업하게 된다.

3.7.5 네임스페이스가 제공하는 격리 이해

  • 네임스페이스는 실행 중인 오브젝트에 대한 격리는 제공하지 않는다.
  • 다른 네임스페이스의 파드끼리도 네트워크 통신이 가능하다. (쿠버네티스의 네트워킹 솔루션에 따라 다르지만)
  • 사용자의 리소스에 대한 작업 권한을 격리한다고 생각하면 된다. (별도 클러스터를 사용하는 것처럼)

3.8 파드 중지와 제거

3.8.1 이름으로 파드 삭제

  • 파드를 삭제하면 쿠버네티스는 파드 안에 있는 모든 컨테이너를 종료하도록 지시
  • SIGTERM 신호를 프로세스에 보내고 지정 시간(기본값 30초) 동안 기다린다.
  • 시간 내에 종료되지 않으면 SIGKILL 신호를 통해 종료
  • 프로세스가 정상 종료되게 하기 위해서는 SIGTERM 신호를 올바르게 처리하도록 개발해야 한다.

3.8.2 레이블 셀렉터를 이용한 파드 삭제

3.8.3 네임스페이스를 삭제하여 파드 제거

3.8.4 네임스페이스를 유지하면서 네임스페이스 안에 있는 모든 파드 삭제

kubectl delete po --all

  • 설정된 replication 수가 있다면 모든 파드를 삭제하더라도, 다시 replication 수에 맞게 파드가 생성된다.

3.8.5 네임스페이스에서 (거의) 모든 리소스 삭제

profile
검둥검둥 검둥개

0개의 댓글