본문 바로가기
INFRA/DevOps

[k8s] Pod Scheduling

by BTC_비웃는사나이 2023. 2. 6.

Node selector란?

  • Worker node에 할당된 label을 이용해 node를 선택
  • node label 설정
    • kubectl label nodes <NODE_NAME> <LABEL_KEY>=<LABEL_VALUE>
    • kubectl label node1.example.com gpu=true
    • kubectl get nodes -L <LABEL_KEY>
  • definition
apiVersion: v1
kind: Pod
metadata:
  name: tensorflow-gpu
spec:
  containers:
  - name: tensorflow
    image: tensorflow/tensorflow:nightly-jupyter
    ports:
    - containerPort: 8888
      protocol: TCP
  nodeSelector:
    gpu: "true"

 

[ Hands - on ]

  • node2에 gpu=true이라는 key, value 값 label
kubectl label node node2.example.com gpu=true

 

  • label 확인
kubectl get nodes -L gpu
NAME                 STATUS   ROLES           AGE   VERSION   GPU
master.example.com   Ready    control-plane   17h   v1.24.1
node1.example.com    Ready    <none>          17h   v1.24.1
node2.example.com    Ready    <none>          17h   v1.24.1   true

 

  • gpu=true이라는 key, value 값 label 되어 있는 node에서 pod 실행
vi tensorflow-gpu.yaml
apiVersion: v1
kind: Pod
metadata:
  name: tensorflow-gpu
spec:
  containers:
  - name: tensorflow
    image: tensorflow/tensorflow:nightly-jupyter
    ports:
    - containerPort: 8888
      protocol: TCP
  nodeSelector:
    gpu: "true"

 

  • pod 실행 결과 확인
kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
tensorflow-gpu   1/1     Running   0          79s   10.44.0.1   node2.example.com   <none>           <none>

 

Affinity & antiAffinity

nodeAffinity

  • node의 특정 집합에만 pod를 스케줄 하도록 지시
  • nodeSelector : selector field에 명시된 모든 label이 포함되어야 배치됨
  • nodeAffinity : 특정 node에만 pod가 실행되도록 유도
  • nodeAffinity 요구 조건
    • 엄격한 요구(필수 충족 조건) : requiredDuringSchedulingIgnoredDuringExecution
    • 선호도 요구(가중치) : preferredDuringSchedulingIgnoredDuringExecution
  • definition
apiVersion: v1
kind: Pod
metadata:
  name: redis-ssd
spec:
  containers:
  - name: redis
    image: redis
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: disktype, operator: In, values: ["ssd"]}

 

[ Hands - on ]

  • node2에 disktype=ssd이라는 key, value 값 label
kubectl label node node2.example.com disktype=ssd

 

  • label 확인
kubectl get nodes -L gpu,disktype
NAME                 STATUS   ROLES           AGE   VERSION   GPU    DISKTYPE
master.example.com   Ready    control-plane   18h   v1.24.1
node1.example.com    Ready    <none>          18h   v1.24.1
node2.example.com    Ready    <none>          18h   v1.24.1   true   ssd

 

  • nodeAffinity가 지정된 pod 생성
vi tensorflow-gpu-ssd.yaml
apiVersion: v1
kind: Pod
metadata:
  name: tensorflow-gpu-ssd
spec:
  containers:
  - name: tensorflow
    image: tensorflow/tensorflow:nightly-jupyter
    ports:
    - containerPort: 8888
      protocol: TCP
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: disktype, operator: Exists}
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 10
        preference:
          matchExpressions:
          - {key: gpu, operator: In, values: ["true"]}
          - {key: disktype, operator: In, values: ["ssd"]}
kubectl create -f tensorflow-gpu-ssd.yaml
kubectl get pods -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
tensorflow-gpu-ssd   1/1     Running   0          4s    10.44.0.1   node2.example.com   <none>           <none>

 

Pod Affinity

  • Pod 스케줄링
    • pod affinity : pod를 더 가깝게 배치
    • pod antiAffinity : pod를 더 멀리 배치
  • Pod Affinity 요구조건
    • 엄격한 요구 : requiredDuringSchedulingIgnoredDuringExecution
    • 선호도 요구 : preferredDuringSchedulingIgnoredDuringExecution
  • topologyKey
    • node label을 이용해 pod의 affinity를 설정할 수 있는 또 하나의 기준
    • K8s는 pod를 스케줄링 할 때 먼저 pod의 label을 기준으로 대상 노드를 찾고, 이후 topologyKey 필드를 확인해 해당 node가 원하는 node인지 확인

 

[ Hands - on ]

1. Affinity

  • 임의의 pod 실행 및 확인
    • app=backend labeling
kubectl run backend --labels app=backend --image=busybox -- sleep 9999999
kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP          NODE                NOMINATED NODE   READINESS GATES
backend   1/1     Running   0          2m44s   10.36.0.1   node1.example.com   <none>           <none>
kubectl get pods --show-labels
NAME      READY   STATUS    RESTARTS   AGE   LABELS
backend   1/1     Running   0          18s   app=backend

 

  • app=backend로 label 된 pod가 실행되어 있는 node에 배치되는 pod 생성 및 확인
vi pod-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: backend
            topologyKey: kubernetes.io/hostname
      containers:
      - name: main
        image: busybox
        args:
        - sleep
        - "99999"
kubectl apply -f pod-affinity.yaml
kubectl get pods -o wide
NAME                       READY   STATUS    RESTARTS   AGE    IP          NODE                NOMINATED NODE   READINESS GATES
backend                    1/1     Running   0          4m2s   10.36.0.1   node1.example.com   <none>           <none>
frontend-7c4546cff-6gmdz   1/1     Running   0          16s    10.36.0.2   node1.example.com   <none>           <none>
frontend-7c4546cff-m9ltp   1/1     Running   0          16s    10.36.0.5   node1.example.com   <none>           <none>
frontend-7c4546cff-tvs4r   1/1     Running   0          16s    10.36.0.4   node1.example.com   <none>           <none>
frontend-7c4546cff-z9g4k   1/1     Running   0          16s    10.36.0.6   node1.example.com   <none>           <none>
frontend-7c4546cff-zht2v   1/1     Running   0          16s    10.36.0.3   node1.example.com   <none>           <none>

 

2. antiaffinity

  • app=backend로 label 된 pod가 실행되어 있지 않은 node에 배치되는 pod 생성 및 확인
vi pod-antiaffinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: backend
            topologyKey: kubernetes.io/hostname
      containers:
      - name: main
        image: busybox
        args:
        - sleep
        - "99999"
kubectl apply -f pod-antiaffinity.yaml
kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP          NODE                NOMINATED NODE   READINESS GATES
backend                     1/1     Running   0          7m55s   10.36.0.1   node1.example.com   <none>           <none>
frontend-5ddc8895bc-7tgrq   1/1     Running   0          16s     10.44.0.3   node2.example.com   <none>           <none>
frontend-5ddc8895bc-fk8rl   1/1     Running   0          16s     10.44.0.2   node2.example.com   <none>           <none>
frontend-5ddc8895bc-m7ktc   1/1     Running   0          16s     10.44.0.4   node2.example.com   <none>           <none>
frontend-5ddc8895bc-q25kn   1/1     Running   0          16s     10.44.0.1   node2.example.com   <none>           <none>
frontend-5ddc8895bc-x577z   1/1     Running   0          16s     10.44.0.5   node2.example.com   <none>           <none>

 

참고 : [따배쿠/멤버십] 12-1. Pod Scheduling

'INFRA > DevOps' 카테고리의 다른 글

[K8s] Cordon& Drain  (1) 2023.02.20
[K8s] Taint & Toleration,Cordon& Drain  (0) 2023.02.13
[K8s] Multi-master - HA Kuberenetes cluster 운영  (0) 2023.01.30
[k8s] Secret  (1) 2023.01.25
[K8s] ConfigMap  (0) 2023.01.16

댓글