kubernetes

Pod Scheduling

Control Plane은 사용자의 요청을 받아 Node와 container를 관리합니다. ( Control Plane의 구조적 설명은 하단 설명을 참고해 주세요. ) Pod가 어느 Node에 배치가 될지는 Scheduler가 관리해 줍니다. 하지만 상황에 따라 물리적 Node와 Pod 사이에는 복잡한 제약조건이 존제할 수도 있습니다.

Scheduler는 filtering/scoring 과정을 통해 Node 배치를 결정합니다. 당연한 이야기지만 이러한 과정에는 개발자는 개입하지 않고 쿠버네티스가 선택하여 배치합니다. filtering은 배드를 배치 할 수 없는 Node를 filtering하는 역할을합니다. scoring은 필터링 되지 않는 Node에서 어느 노드가 파드의 배치가 적합한지를 종합적으로 고려하여 선택하는 역할을 합니다. 하지만 개발자의 개입을 통해 특정 Node에만 배치를 하거나 하지 말아야하는 경우도 발생하게 됩니다. 관련 설정하는 방법에 대해 하나씩 알아보도록 합시다.

특정 Node에 Pod 배치하기

특정 Node를 선택하여 파드는 넣는 경우는 보통 GPU가 포함된 Node에 인공지능과 관련된 pod를 올리는 경우라고 할 수 있습니다. 이러한 경우 우리는 보통 Selector/Label를 사용하게 됩니다.

  • label : 식별을 위한 태그를 넣어줄 수 있습니다.
  • selector : label을 식별하는 값이 selector입니다.
Selector/Label 확인하기 (클릭)

정리하면, label이 데이터 값이라면, selector가 쿼리라고 할 수 있습니다.

nodeSelector

Node Selector는 파드가 배치될 노드를 Selector를 이용하여 선택하는 방법입니다. 우선 아래와 같이 node-2에 label을 명령어로 넣어봅시다.

scheduling
$ kubectl label node node-2 hw-type=gpu

그리고 yaml 에서 Pod 생성 시 nodeSelector를 넣어줍니다.

scheduling
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  nodeSelector:
    hw-type: gpu
  containers:
    - name: ml-server
      image: ai-server:latest

기본적으로 nodeSelector는 AND 조건으로 모든 label 된 값들이 동일해서 node에 배치가 완료 됩니다. 만약 label이 없는 경우에는 Pod 자체는 pending 상태가 되고 Node에 바인딩 되지 못하게 됩니다. 여기서 조금 더 조건을 추가해서 생각해 볼 수 있습니다. gpu와 관련된 pod를 특정 Node에서 실행되도록 등록을 하였습니다. 이제는 gpu와 관련되지 않는 pod를 gpu Node에 실행되지 않도록 하는 방법을 알아봅시다.

Taint and Tolerations

taint를 활용하여 아래와 같이 배치할 수 없는 Node를 지정하는 것이 가능합니다.

scheduling
$ kubectl taint node node-2 hw-type=gpu:NoSchedule

위에서 taint의 NoSchedule 옵션을 적용하였습니다. 관련 사용할 수 있는 사항들은 아래와 같습니다.

  • NoSchedule : 강력한 제약으로 Node에 pod가 스케줄 되지 못하는 설정입니다.
  • PreferNoSchedule : 소프트한 제약으로 다른 Node가 다 차서 가용할 수 있는 Node가 없는 경우 배치합니다. 일반적으로 배치하지 않습니다. - NoExecute : 이미 존재하는 pod도 모두 제거하는 옵션입니다.

Tolerations란 Taint옵션을 무시하여 배치할 수 있는 옵션으로 Taint옵션을 오버라이딩합니다. 기본적으로 Taint옵션을 걸어두고, Taint옵션을 무시하는 방식으로 pod를 배치할 수 있습니다.

scheduling
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  tolerations:
    - key: 'hw-type'
      operator: 'Equal'
      value: 'gpu'
      effect: 'NoSchedule'
  containers:
    - name: ml-server
      image: ai-server:latest

위의 내용에서 key, value, effect 옵션이 모두 일치해야한 Taint 무시가 가능합니다. 보통 Taint와 Tolerations를 복합적으로 사용해야 원하는 동작을 수행시킬 수 있습니다.

Node에서 pod를 선택하는 간단한 방법을 알아보았습니다. 좀 더 구체적으로 pod를 지정하는 방법으로는 Node Affinity를 활용해서 가능합니다. 관련 내용은 다음 블로그에서 확인해 보도록 하겠습니다.


Word

Node / Control Plane 구성요소 정리

앞에서 배운 클릭 부분에 대한 간단히 정리를 해보려합니다.

image

API Server

  • 사용자의 입력에 따라 상태를 저장하고 Node들과 통신하여 Node와 Container의 변화를 인지하고 동작을 수행합니다.(ex. kubectl은 API server를 활용하여 만들어진 cli tool 입니다.)

etcd(엣시디, 이티시디)

  • 쿠버네티스에 관한 정보를 저장하는 곳으로, 분산 환경에서 가용성이 크고 안전합니다.

Scheduler

  • 여러 Node 중에 어느 Node에 컨테이너를 생성할지를 정합니다.

Controller Manager

  • 쿠버네티스의 다양한 컨트롤러를 관리하며 API Server가 해야할 일들을 알려주는 역할을 합니다.

Cloud Controller Manager

  • 클라우드 서비스에 따른 저장소나 트래픽 연동을 담당합니다.

Node 구성요소

  • 기본적으로 Node는 컨테이너가 실행되는 공간으로 필수적으로 필요한 최소한의 프로세스들만 존재합니다.

Kubelet (큐블랫)

  • API Server의 명령을 받아 Container를 실행하거나 종료하는 역할을 합니다.

Kube-proxy (큐브 프록시)

  • 독립적인 공한인 Container 내부에서 외부 통신을 관리합니다.