본문 바로가기
Kubernetes

Kubernetes Scheduling

by 손영진 2023. 8. 15.
728x90

#1 Pod Scheduling

   1. 개념

  • 쿠버네티스에서 Pod 생성 요청 시, Pod를 적정 node에 배치
  • Pod를 어느 node에 적절하게 배치할 것인지에 대한 여러 고려 사항 필요
  • 충분한 리소스 ( CPU와 메모리)등 필요

 

   2. 종류

  • NodeSelector
    • 가장 간단하고 권장되는 node선택 제약 조건 형태
    • Pod가 클러스터 안에서 어떤 노드에서 실행될 지 키-값 쌍으로 설정
    • Pod가 노드에서 동작하려면, 노드는 키-값 쌍으로 표시되는 레이블이 필요

  • Affinity & Anti-affinity
    • Affinity : Pod가 지정한 레이블을 가진 Pod들이 있는 node로 Scheduling
    • Anti : 같은 조건을 가진 Pod를 피해 다른 노드로 Scheduling

  • Taint & Toleration
    • 각 node에  taint 설정 감염으로부터 용인(Toleration)된 Pod만 해당 node에 Scheduling
    • Pod1 : red와 blue taint에 대해 용인된 것이 있으므로 node1, node2에 Scheduling
    • Pod2 : 허용된 toleraiton이 없으므로 어디에도 Scheduling 되지 안흠
    • Pod3 : node3에 Scheduling

  • Cordon & Drain
    • Cordon : 특정 노드를 선택하여 Scheduling 대상에서 제외
    • Drain : Cordon과 동일하나, 남아있는 Pod를 제거하고 그 수만큼 다른 node에 재생성

 

#2 각 종류별 실습

   1. NodeSelector

  • nodeselector.yaml
  • 더보기
    apiVersion: v1
    kind: Pod
    metadata:
      name: nodeselector-pod
    spec:
      containers:
      - name: nodeselector-pod
        image: arisu1000/simple-container-app:latest
        ports:
        - containerPort: 8080
      nodeSelector:
        disktype: ssd
<< Label 생성 >>
kubectl create ns scheduling
kubectl scheduling
kubectl get nodes --show-labels

kubectl label node worker2.example.com disktype=ssd		//node2에 disktype으로 조건을 걸어 lable 생성
kubectl get nodes --show-labels | grep disktype

<< Nodeselector 사용 >>
vim nodeselector.yaml	<더보기 참조>
			// 조건을 label에 맞게 생성
kubectl apply -f nodeselector.yaml
kubectl get pods -o wide		// yaml에 의해 생성된 pod가 worker2에 생성되었는지 확인
kubectl describe pod nodeselector-pod

<< Label 삭제 >>
kubectl label node worker2.example.com disktype-
kubectl get nodes --show-labels | grep disktype		// 삭제되었는지 확인

 

   2. Affinity & Anti-affinity

  • Anffinity : 통신이 많은 Pod들은 같은 node에 배치
    • 컨테이너로 서비스 운용 시 클러스터 내부의 서비스끼리 통신하는 경우가 많기 때문에
  • Anti-affinity : CPU나 네트워크 같은 하드웨어 자원을 많이 소모하는 컨테이너를 여러 노드에 분산
  • node-affinity.yaml
    • required : 강제라는 의미로 반드시 규칙을 만족해야 한다는 의미
    • prefer : 반강제의 의미로 가급적 규칙을 만족하는 것이 좋지만 반드시 그래야 하는 것은 아니다
    • require 구문의 Gt : Greater than의 의미로 value의 6보다는 커야한다는 의미이다
      • Lt: Less than
    • 더보기
      apiVersion: v1
      kind: Pod
      metadata:
        name: nodeaffinity-pod
      spec:
        containers:
        - name: nodeaffinity-pod
          image: arisu1000/simple-container-app:latest
          ports:
          - containerPort: 8080
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
              - matchExpressions:
                - key: kubernetes.io/os
                  operator: In
                  values:
                  - linux
                - key: disktype
                  operator: Exists
                - key: core
                  operator: Gt
                  values:
                  - "6"
            preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 10
              preference:
                matchExpressions:
                - key: kubernetes.io/hostname
                  operator: In
                  values:
                  - node1.example.com
  • pod-antiaffinity.yaml
    • podAntiAffinity 구문 안의 내용과 반대되는 곳에 배포 되어야 한다.
    • 더보기
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: redis-cache
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: store
        template:
          metadata:
            labels:
              app: store
          spec:
            affinity:
              podAntiAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - store
                  topologyKey: "kubernetes.io/hostname"
            containers:
            - name: redis-server
              image: redis:3.2-alpine
  • pod-affinity.yaml
    • podAntiAffinity와 podAffinity 둘다 만족하는 node에 실행
    • 더보기
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: web-server
      spec:
        selector:
          matchLabels:
            app: web-store
        replicas: 2
        template:
          metadata:
            labels:
              app: web-store
          spec:
            affinity:
              podAntiAffinity: ①
                requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - web-store
                  topologyKey: "kubernetes.io/hostname"
            podAffinity: ②
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - store
                topologyKey: "kubernetes.io/hostname"
            containers:
            - name: web-app
              image: nginx:1.12-alpine
<< Label 생성 >>
kubectl label nodes worker1.example.com core=4
kubectl label nodes worker2.example.com core=8
kubectl label nodes worker2.example.com disktype=ssd
kubectl label nodes worker1.example.com disktype=ssd
kubectl get nodes --show-label		//생성한 Label 확인

<< Node-affinity 생성 및 확인>>
vim node-affinity.yaml	<더보기 참조>
kubectl apply -f node-affinity.yaml
kubectl get pods -o wide
kubectl describe pods nodeaffinity-pod
			//생성한 yaml 파일에 넣은 조건에 부합되는 worker2에 생성된 것을 확인
            
<< Pod anti-affinity 생성 및 확인 >>
vim pod-antiaffinity.yaml	<더보기 참조>
kubectl apply -f pod-antiaffinity.yaml
kubectl get deploy -o wide
kubectl get pods -o wide

<< Pod Affinity >>
vim pod-affinity.yaml	<더보기 참조>
kubectl apply -f pod-affinity.yaml
kubectl get deploy -o wide

 

   3. Taint & Toleration

  • Taint는 node, Toleration은 Pod에 정의
  • pod-taint.yaml
    • 더보기
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: taint-app
        labels:
          app: taint-app
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: taint-app
        template:
          metadata:
            labels:
              app: taint-app
          spec:
            containers:
            - name: taint-app
              image: arisu1000/simple-container-app:latest
              ports:
              - containerPort: 8080
            resources:
              requests:
                cpu: 50m
  • pod-toleration.yaml
    • 더보기
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: taint-app
        labels:
          app: taint-app
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: taint-app
        template:
          metadata:
            labels:
              app: taint-app
          spec:
            containers:
            - name: taint-app
              image: arisu1000/simple-container-app:latest
              ports:
              - containerPort: 8080
            resources:
              requests:
                cpu: 50m
            tolerations:
            - key: "key01"
              operator: "Equal"
              value: "value01"
              effect: "NoSchedule"
kubectl taint node worker1.example.com key01=value01:NoSchedule
kubectl describe node worker1.example.com | grep Taints

vim pod-taint.yaml	<더보기 참조>
kubectl apply -f pod-taint.yaml
kubectl get deploy -o wide
kubectl get pods -o wide		// node에 잘 배포 되었는지 확인

<< Toleration 설정 및 사용 >>
vim pod-toleration.yaml	<더보기 참조>
kubectl apply -f pod-toleration.yaml
kubectl get delply -o wide
kubectl get pods -o wide		// node에 잘 배포 되었는지 확인

<< Taint 삭제 >>
kubectl taint node worker1.example.com key01:NoSchedule-
kubectl describe node worker1.example.com | grep Taint
			// 삭제된 상태 확인

 

   4. Cordon & Drain

  • Cordon : 지정된 노드에 더이상 pod들이 scheduling되자 않음
  • Drain : 설정 후 pod 확인 이름이 바뀌는 것을 볼 수 있음
    • 이는 기존 pod가 삭제되고 새로 생기는 것으로 위험하기 때문에 Cordon을 선호
<< cordon 설정 >>
kubectl get pods -o wide
kubectl cordon worker1.example.com		//worker1 노드에 cordon 설정
kubectl get nodes		// node 상태 확인시 disabled라는 문구 확인

kubectl get deploy
kubectl scale deploy taint-app --replicas=4
			// deploy를 갯수를 더 늘려 해당 node로 scheduling 되지 않는 것을 확인
kkubectl get pods -o wide

<< cordon 제거 >>
kubectl uncordon worker1.example.com
kubectl get nodes		// node 상태 확인시 disabled라는 문구가 사라진 것을 확인

<< Drain 사용 >>
kubectl get pods -o wide		// 현재 pods들의 이름과 node확인
kubectl drain worker2.example.com		//worekr2에 drain 설정
kubectl drain worekr2.example.com --ignore-daemonsets=true
			// 실행 중인 daemonset이 있기에 무시하고 현재의 pod에게만 적용하라는 명령어
kubectl get nodes		// node 상태 확인시 disabled라는 문구 확인
kubectl get pods -o wide		// pods들의 node확인과 바뀐 이름들을 확인
kubectl uncordon worker2.example.com
			//drain 상태 해제

'Kubernetes' 카테고리의 다른 글

Kubernetes ConfigMap & volume  (0) 2023.08.09
Kubernetes Deploy & Service & Ingress  (0) 2023.08.08
Kubernetes 기본  (1) 2023.08.07