[K8s in Action] 3. 파드: 쿠버네티스에서 컨테이너 실행

Sangmin Yoon·2021년 6월 28일
1

Kubernetes in Action

목록 보기
3/8
post-custom-banner

1. Pod 소개

일반적으로 파드는 하나의 컨테이너를 포함한다. 중요한 점은, 여러 컨테이너를 가진 파드는 항상 하나의 worker node에서 실행된다는 점이다.

1) 파드가 필요한 이유

  • 왜 컨테이너를 직접 사용할 수 없는가? 왜 여러 컨테이너를 같이 실행해야 하는가? 모든 프로세스를 단일 컨테이너에 넣을 수는 없는가?
  • 여러 프로세스를 실행하는 단일 컨테이너보다 다중 컨테이너가 나은 이유
    - 컨테이너는 단일 프로세스를 실행하는 것을 목적으로 설계됐다.
    - 단일 컨테이너에서 관련없는 다른 프로세스를 실행하는 경우, 모든 프로세스를 실행하고 관리하는 것은 모두 사용자 책임이다. 그리고 이 로그들은 모두 동일 표준 출력이므로 어떤 프로세스가 남긴 로그인지 구별이 안 된다.

2) 파드 이해하기

  • 여러 프로세스를 단일 컨테이너로 묶지 않기 때문에, 컨테이너를 함께 묶고 하나의 단위로 관리할 수 있는 상위 구조가 필요한데, 그것이 파드가 필요한 이유다.
  • K8s는 파드 내 모든 컨테이너가 자체 네임스페이스가 아닌 동일한 리눅스 네임스페이스를 공유하도록 도커를 설정한다. 따라서 모든 컨테이너는 같은 호스트 이름과 네트워크 인터페이스를 공유한다. 마찬가지로 모든 컨테이너는 동일한 IPC 네임스페이스 아래에서 실행되기 때문에 IPC를 통해 서로 통신할 수 있다.
  • 단, 대부분의 컨테이너 파일시스템은 컨테이너 이미지에서 나오기 때문에 다른 컨테이너와 완전히 분리된다. 그러나 볼륨을 사용하면 파일 디렉터리 공유하게 만들 수 있다.
  • 파드 내 컨테이너는 동일한 IP 주소와 포트 공간을 공유하므로, 포트가 충돌되면 안 된다. 파드 내 모든 컨테이너는 동일한 loopback network interface를 갖기 때문에 localhost를 통해 통신할 수 있다.
  • 클러스터 내의 모든 파드는 하나의 NAT 없는 flat한 공유 네트워크 주소 공간에 있으므로, 모든 파드는 다른 파드의 IP 주소를 사용해 접근할 수 있다.

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

  • 파드는 기본적으로 개별 스케일링이 가능하도록 여러 파드로 분할하는 것이 맞다.
  • 그럼에도 여러 컨테이너를 단일 파드에 넣는 주된 이유는, 앱이 하나의 주요 프로세스와 하나 이상의 보완 프로세스(사이드카 프로세스)로 구성된 경우이다.

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

YAML 파일에 모든 쿠버네티스 오브젝트를 정의하면 VCS에 올리는 것이 가능해져서 관리하기 편하다.

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

  • 파드 정의는 몇 부분으로 구성된다. 먼저 YAML에서 사용하는 K8s API 버전과 YAML이 설명하는 리소스 유형이 있다. 그리고 세 가지 중요한 부분(Metadata / Spec / Status)이 있다.
  • Metadata : 이름, 네임스페이스, 레이블 및 파드에 관한 기타 정보를 포함
  • Spec : 파드 컨테이너, 볼륨, 기타 데이터 등 파드 자체의 실제 명세
  • Status : 파드 상태, 각 컨테이너 설명과 상태, 파드 내부 IP 등

2) 파드를 정의하는 간단한 YAML 정의 작성하기

  • kubectl create -f kubia-manaul.yaml

3) 애플리케이션 로그 보기

  • kubectl logs kubia-manual
  • 여러 컨테이너 포함한 파드인 경우는 -c <컨테이너 이름> 옵션을 명시해준다.

4) 파드에 요청 보내기

  • 파드의 실제 동작 보려면 kubectl expose 이용해서 외부에서 접속할 수 있는 서비스를 만들었지만, 그렇게 안 하고 테스트/디버깅 목적의 포트 포워딩을 쓸 수 있다.
  • kubectl port-forward kubia-manual 8888:8080
  • 이렇게 하면 머신의 로컬 포트 8888을 kubia-manual 파드의 8080으로 향하게 한다.

3. 레이블을 이용한 파드 구성

파드 수가 늘어나면 파드를 부분 집합으로 분류할 필요가 있다.
1) 레이블 소개

  • 레이블은 파드와 모든 다른 쿠버네티스 리소스를 조직화할 수 있는 기능이다. 레이블은 리소스에 첨부하는 Key-Value 쌍이다. 아래 그림은 2개의 레이블(app, rel)로 파드를 분류한 모습이다.
  • metadata - labels 에서 레이블 두 개를 파드에 붙였다.

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

레이블은 레이블 셀렉터와 함께 사용된다. 레이블 셀렉터는 특정 레이블로 태그된 파드의 부분 집합을 선택해 원하는 작업을 수행한다.

  • kubectl get po -l creation_method=manual
  • kubectl get po -l '!env'

5. 레이블과 셀렉터를 이용해 파드 스케쥴링 제한

보통은 파드가 어느 노드에 스케쥴링됐느냐는 중요하지 않다. 그런데 특정 상황에서는 파드를 특정 노드에 스케쥴링할 필요가 있다. (ex. GPU 계산이 필요한 파드, SSD 필요한 파드)
1) 워커 노드 분류에 레이블 사용

  • 노드를 포함한 모든 쿠버네티스 오브젝트에 레이블을 부착할 수 있다.
  • 특정 노드에 gpu=true 레이블을 추가한 뒤 파드를 생성할 때 nodeSelector를 사용하면 특정 노드에 스케쥴링된다.

6. 파드에 어노테이션 달기

  • 파드 및 다른 오브젝트는 레이블 외에 어노테이션을 가질 수 있다. 어노테이션은 Key-Value 쌍으로 레이블과 거의 비슷하지만 식별 정보가 없다. 어노테이션 셀렉터 같은 것은 없다.
  • 그럼 왜 쓰냐? 더 많은 정보를 보유할 수 있다. 파드나 다른 API 오브젝트에 설명을 추가할 때 유용하다. 레이블에는 안 넣고 싶은데 주석 처리 하고 싶은 데이터를 metadata - annotaions에 넣는다.

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

여기서 말하는 네임스페이스는 프로세스를 격리하는 리눅스 네임스페이스가 아니다. 쿠버네티스 네임스페이스는 오브젝트 이름의 범위를 제공한다. 같은 리소스 이름을 다른 쿠버네티스 네임스페이스에 걸쳐 사용할 수 있게 해준다.

1) 네임스페이스의 필요성

  • 네임스페이스를 사용해 서로 관계없는 리소스를 겹치지 않는 그룹으로 분리할 수 있다.

2) 네임스페이스 생성

  • 아래와 같은 YAML 파일을 작성하거나 kubectl create namespace 명령 사용.

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

  • 네임스페이스가 다르다고 해서 실행 중인 오브젝트가 격리되는 것은 아니다. 네트워크 솔루션이 격리를 제공하지 않는 경우 A 파드가 B 파드의 IP를 알고 있다면 트래픽 보낼 수 있다.

8. 파드 중지와 제거

1) 이름으로 파드 삭제

  • kubectl delete po kubia-gpu

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

  • kubectl delete po -l creation_method=manual

3) 네임스페이스를 삭제한 파드 제거

  • 파드는 네임스페이스와 함께 자동으로 삭제된다.
  • kubectl delete ns custom-namespace
post-custom-banner

0개의 댓글