kok202
쿠버네티스 입문 - 07 - 파드 스케줄링

2020. 4. 5. 03:44[정리] 기능별 개념 정리/Kubernetes

파드 스케줄링 기법

  • 노드 셀렉터 : 특정 노드에 스케줄링 되도록 하는 가장 간단한 설정
  • 노드 어피니티 : 파드를 노드의 레이블 기반으로 스케줄링한다.
  • 파드 어피니티 : 파드를 지정한 레이블을 가진 파드들이 있는 노드로 스케줄링한다.
  • 테인트와 톨러레이션 : 테인트가 걸린 노드에 요구하는 톨러레이션이 설정되있지 않은 파드라면 생성하지 못하도록한다.

 

 

 

어피니티가 적용된 파드 샘플

apiVersion: v1
kind: Pod
metadata:
  name: kubernetes-nodeaffinity-pod
spec:
  containers:
  - name: kubernetes-nodeaffinity-pod
    image: arisu1000/simple-container-app:latest
    ports:
    - containerPort: 8080
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: beta.kubernetes.io/os
            operator: In
            values:
            - linux
            - window
          - key: disktype
            operator: Exists
          - key: core
            operator: Gt  
            values: 
            - "4"
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 10
        preference:
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - worker-node01

.spec.affinity.nodeAffinity : 파드를 노드의 레이블 기반으로 스케줄링한다.

.spec.affinity.podAffinity : 파드를 지정한 레이블을 가진 파드들이 있는 노드로 스케줄링한다.

.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution : 스케줄링 하는 동안 꼭 필요한 조건

.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[] : 스케줄링 하는 동안 가능하면 필요한 조건

.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[] : 지켜야하는 조건의 나열

 

.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].weight : 노드를 보고 해당 조건이 맞을 때마다 얻게될 가중치 점수

 

 

 

어피니티와 안티 어피니티

컨테이너로 서비스를 운영하다보면 클러스터 내부의 서비스들끼리 자주 통신하는 경우가 많다.

이런 경우 어피니티를 활용하여 통신이 많은 파드들은 같은 노드에 배치시키는 것이 네트워크 비용을 줄이는 방법일 것이다.

대표적으로 데이터베이스와 캐시 같이 서비스와 통긴하는 앱 컨테이너를 같은 노드에 두면 성능이 좋아진다.

안티 어피니티는 CPU 나 네트워크 같은 하드웨어 자원을 많이 잡아먹는 컨테이너가 있을 때, 이를 여러개의 노드에 분산하는 방법이다.

 

 

 

topologyKey

파드 어피니티을 적용 할 때 추가로 노드의 정보도 확인할 수 있다.

topologyKey 를 이용하면 파드의 레이블 기준으로 대상 노드를 찾고, 이후 찾은 노드가 원하는 노드인지 확인까지한다.

topologyKey 는 다음과 같은 제약 사항이 있다.

  1. .spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[] 에는 반드시 명시해야한다.
  2. .spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].topologyKey 는 kubernetes.io/hostname 만 설정 가능하다.
  3. 어드미션 컨트롤러의 .limitPodHardAntiAffinityTopology.topologyKey 는 kubernetes.io/hostname 만 설정 가능하다.

 

 

테인트와 톨러레이션

테인트를 설정한 노드에는 파드를 스케줄링하지 않는다.

테인트를 설정한 노드에 파드를 스케줄링 하려면 톨러레이션이 설정되있어야한다.

kubectl taint nodes docker-desktop key01=value01:NoSchedule
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubernetes-simple-app
  labels:
    app: kubernetes-simple-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kubernetes-simple-app
  template:
    metadata:
      labels:
        app: kubernetes-simple-app
    spec:
      containers:
      - name: kubernetes-simple-app
        image: arisu1000/simple-container-app:latest
        ports:
        - containerPort: 8080
      tolerations:
      - key: "key01"
        operator: "Equal"
        value: "value01"
        effect: "NoSchedule"

.spec.tolerations[] : 파드가 가지는 톨러레이션을 명시한다.

 

 

 

톨러레이션의 이펙트

  • NoSchedule : 톨러레이션이 없으면 파드를 스케줄링하지 않는다.
  • PreferNoSchedule : 톨러레이션이 없으면 파드를 스케줄링하지 않지만 자원이 테인트가 걸려있어도 스케줄링 한다.
  • NoExecute : 톨러레이션이 없으면 파드를 스케줄링 하지 않는다. 테인트가 걸리기전 생성된 파드가 있고 해당 파드가 톨러레이션이 없다면 종료시킨다.

 

 

 

커든과 드레인

클러스터 관리중 특정 노드에 파드를 더 이상 추가 생산하지 않도록 제한해야하거나 특정 노드안의 파드를 다른 노드로 옮겨야할 수도 있다.

커든 : 지정한 노드에 파드가 추가 생성되지 않도록 한다.

드레인 : 지정한 노드안의 파드들을 다른 노드로 이동시킨다.

kubectl cordon docker-desktop
kubectl uncordon docker-desktop
kubectl drain docker-desktop

 

 

 

드레인의 특징

  • 데몬셋으로 생성한 파드들이 있다면 해당 파드들은 옮겨지지 않는다. (--ignore-daemonset=true 로 무시가능)
  • 컨트롤러가 생성한 파드들이 있다면 해당 하드들은 옮겨지지 않는다. 해당 파드들은 삭제되면 복구되지 않기 때문이다. (삭제만을 원한다면 --force 로 가능)
  • 드레인 설정은 그레이스풀하게 파드들이 종료되기를 기다린다.

 

 

 

기타 영어 뜻

affinity : 인접한

taint : 오염시키다.

cordon : 비상경계

drain : 액체를 빼내다.