본문 바로가기
네트워크/k8s

[k8s] 23. Pod - Node Scheduling - 실습

by Lauren X Ming 2021. 2. 17.

Pod - Node Scheduling 실습

  • 노드가 여러 개 있어야 좋은데, 여건상 2개의 노드로 실습 ㅠㅠ

1. Node Affinity

image

  • 노드에 두 라벨을 만들고, 파드에 Node Affinity를 사용하여 노드1에 할당되도록 할 것

Pod - MatchExpressions

apiVersion: v1
kind: Pod
metadata:
 name: pod-match-expressions1
spec:
 affinity:
  nodeAffinity:
   requiredDuringSchedulingIgnoredDuringExecution:   
    nodeSelectorTerms:
    - matchExpressions:
      -  {key: kr, operator: Exists}
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0

Pod - Required

apiVersion: v1
kind: Pod
metadata:
 name: pod-required
spec:
 affinity:
  nodeAffinity:
   requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchExpressions:
      - {key: ch, operator: Exists}
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0
  • Pod - MatchExpressions랑 구조가 완전 같은데 matchExpressions의 key만 다르네

Pod - Preferred

apiVersion: v1
kind: Pod
metadata:
 name: pod-preferred
spec:
 affinity:
  nodeAffinity:
   preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
       matchExpressions:
       - {key: ch, operator: Exists}
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0

실습 과정

  1. 마스터 노드에서 다음 명령어로 노드에 라벨 달기

    kubectl label nodes k8s-node1 kr=az-1
    kubectl label nodes k8s-node2 us=az-1
  2. Pod - MatchExpressions 만들기 --> 노드1에 할당됨
    이름만 바꿔서 몇 개를 만들어봐도 노드1에 할당됨

  3. Pod - required, Pod - preferred 생성
    required는 Pending, preferred는 노드2에 할당
    image

2. Pod Affinity

image

  • Pod Affinity: 이 키를 가진 파드와 같은 노드에 할당되고 싶어!

Web1 Pod

apiVersion: v1
kind: Pod
metadata:
 name: web1
 labels:
  type: web1
spec:
 nodeSelector:
  a-team: '1'
 containers:
 - name: container
   image: kubetm/app
 terminationGracePeriodSeconds: 0
  • a-time: '1'로 할당되도록 nodeSelector를 줌

Web1 Affinity Pod

apiVersion: v1
kind: Pod
metadata:
 name: server1
spec:
 affinity:
  podAffinity:
   requiredDuringSchedulingIgnoredDuringExecution:   
   - topologyKey: a-team
     labelSelector:
      matchExpressions:
      -  {key: type, operator: In, values: [web1]}
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0
  • spec에 affinity 속성에 podAffinity가 있음
  • requiredDuringSchedulingIgnoredDuringExecution 속성아래 topologyKey로 a-team 키를 가진 노드 지정
  • labelSelector안의 matchExpressions로 key가 type이고 values가 web1인 파드를 가진 노드를 찾음

Web2 Affinity Pod

apiVersion: v1
kind: Pod
metadata:
 name: server2
spec:
 affinity:
  podAffinity:
   requiredDuringSchedulingIgnoredDuringExecution:   
   - topologyKey: a-team
     labelSelector:
      matchExpressions:
      -  {key: type, operator: In, values: [web2]}
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0

Web2 Pod

apiVersion: v1
kind: Pod
metadata:
  name: web2
  labels:
     type: web2
spec:
  nodeSelector:
    a-team: '2'
  containers:
  - name: container
    image: kubetm/app
  terminationGracePeriodSeconds: 0

실습 과정

  1. 마스터 노드에 다음 명령어로 노드에 라벨 달기

    kubectl label nodes k8s-node1 a-team=1
    kubectl label nodes k8s-node2 a-team=2
  2. Web1 Pod 생성

  3. We1 Affinity Pod 생성 --> Web1 Pod이 할당된 노드에 할당

  4. Web2 Affinity Pod 생성 --> web2 밸류를 가진 파드가 없어서 Pending
    image

  5. Web2 Pod 생성 --> Web2 Pod, Web2 Affinity Pod 둘 다 할당됨
    image

3. Pod Anti-Affinity

image

  • Pod Anti-Affinity: 이 키를 가진 파드와 다른 노드에 할당되고 싶어!

Master Pod

apiVersion: v1
kind: Pod
metadata:
  name: master
  labels:
     type: master
spec:
  nodeSelector:
    a-team: '1'
  containers:
  - name: container
    image: kubetm/app
  terminationGracePeriodSeconds: 0
  • nodeSeoector로 a-team: '1'에 할당

Master Anti-Affinity Pod

apiVersion: v1
kind: Pod
metadata:
 name: slave
spec:
 affinity:
  podAntiAffinity:
   requiredDuringSchedulingIgnoredDuringExecution:   
   - topologyKey: a-team
     labelSelector:
      matchExpressions:
      -  {key: type, operator: In, values: [master]}
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0
  • podAntiAffinity로 master 밸류를 피함

실습 과정

  1. Master Pod 생성 --> 노드1에 할당
  2. Master Anti-Affinity Pod --> 노드2에 할당
    image

4. Taint / Toleration

image

Pod With Toleration

apiVersion: v1
kind: Pod
metadata:
 name: pod-with-toleration
spec:
 nodeSelector:
  gpu: no1
 tolerations:
 - effect: NoSchedule
   key: hw
   operator: Equal
   value: gpu
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0
  • Toleration이 있고, nodeSelector로 노드를 지정하고 있으니 해당 노드에 할당

Pod Without Toleration

apiVersion: v1
kind: Pod
metadata:
 name: pod-without-toleration
spec:
 nodeSelector:
  gpu: no1
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0
  • nodeSelector로 노드를 지정하고 있지만, Toleration이 없으니 Taint가 있는 노드에는 할당 안 됨

Pod1 With NoExecute

apiVersion: v1
kind: Pod
metadata:
 name: pod1-with-no-execute
spec:
 tolerations:
 - effect: NoExecute
   key: out-of-disk
   operator: Exists
   tolerationSeconds: 30
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0
  • effect가 NoExecute --> Toleration이 없으면 노드에 있는 파드는 삭제
  • TolerationSeconds --> Toleration이 있는 노드에 있는 파드는 30초뒤에 삭제
  • 원래 Toleration이 있으면 삭제가 안 되는데 tolerationSeconds가 있으면 정해진 시간뒤에 삭제
  • 노드를 따로 지정하지 않았지만, 실습 과정상 노드1에 Taint가 붙을 예정이니 노드2에 할당될 것

Pod2 With NoExecute2

apiVersion: v1
kind: Pod
metadata:
 name: pod1-with-no-execute2
spec:
 tolerations:
 - effect: NoExecute
   key: out-of-disk
   operator: Exists
 containers:
 - name: container
   image: tmkube/app
 terminationGracePeriodSeconds: 0

실습 과정

  1. 마스터 노드에 다음 명령어로 노드에 라벨 달기

    kubectl label nodes k8s-node1 gpu=no1
  2. 마스터 노드에 다음 명령어로 노드에 Taint 달기

    kubectl taint nodes k8s-node1 hw=gpu:NoSchedule

    key는 hw, value는 gpu, effect는 NoSchedule

  3. Pod without toleration 생성 --> 할당 안 됨

  4. Pod with toleration 생성 --> 노드1에 할당됨
    image
    노드에 NoSchedule effect를 달면, 기존에 할당된 파드는 Toleration이 없어도 삭제가 안 됨

  5. Pod1 With NoExecute 생성 --> 노드2에 할당됨

  6. Pod2 With NoExecute2 생성 --> 노드2에 할당되고 tolerationSeconds가 없음

  7. 마스터 노드에서 다음 명령어로 노드1의 Taint 삭제
    노드1의 Taint를 삭제하지 않으면, 노드2에 NoExecute로 Taint 생성 시 Toleration이 없는 모든 파드가 죽음
    파드가 그냥 죽지 않고 노드1에 재생성되어야 하기 때문에 노드1의 Taint를 없애는 작업을 하는 것
    노드2에 중요한 파드가 있을 수도 있으니까

    kubectl taint nodes k8s-node1 hw=gpu:NoSchedule-
  8. 마스터 노드에서 다음 명령어로 노드2의 Taint 생성

    kubectl taint nodes k8s-node2 out-of-disk=True:NoExecute

    pod1-with-no-execute2만 삭제되지 않고 나머지는 다 삭제
    pod1-with-no-execute는 30초뒤에 삭제됨 --> tolerationSeconds:30
    image

출처

인프런 - 대세는 쿠버네티스

이렇게 무난하게 넘어가고 싶었지만

image

얘네는 노드2에 Taint 있고, Toleration도 없는 파드들인데 왜 안 쫓겨나나 너무 궁금한데
공식문서에는 없는데 여기엔 나와서 이걸로 납득하려고 함

image