본문 바로가기

메가존 클라우드 2기 교육/실무 특화

Kubernetes - 스케줄링(taint & toleration, cordon , drain),

스케줄링

스케줄링 사전 작업

# 템플릿으로 만든 모든 것들 삭제 (템플릿으로 생성되지 않은 네임 스페이스는 남아있다)
kubectl delete -f .

# 네임 스페이스 삭제
kubectl delete ns kyounggu
kubectl delete ns test-namespace
kubectl delete ns metallb-system

# 현재 네임 스페이스 변경
kubectl config set-context kubernetes-admin@kubernetes --namespace=default

# deployment 삭제
kubectl delete deployments.apps mysql-deploy
kubectl delete deployments.apps wordpress-deploy

# 루트 경로로 이동
cd

# 폴더 생성 후 이동
mkdir schedule && cd $_

파드 스케줄(자동 배치)

# 파드 스케쥴 템플릿 생성
vi pod-schedule.yaml
//
apiVersion: v1
kind: Pod
metadata:
  name: pod-schedule-metadata
  labels:
    app: pod-schedule-labels
spec:
  containers:
  - name: pod-schedule-containers
    image: 192.168.1.158:5000/nginx:latest
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: pod-schedule-service
spec:
  type: NodePort
  selector:
    app: pod-schedule-labels
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
//
# kubectl apply -f pod-schedule.yaml
# kubectl get po -o wide

워커1에 자동 배치.

# 복사해서 이름을 수정하여 파드 하나 더 생성
cp pod-schedule.yaml pod-schedule2.yaml
vi pod-schedule2.yaml
//
밑의 사진처럼 이름 부분에 '2' 붙여주기
//

# kubectl apply -f pod-schedule2.yaml
# kubectl get po -o wide
워커2에 자동 배치.

파드 노드네임(수동 배치)

# 파드 노드네임 템플릿 생성
vi pod-nodename.yaml
//
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename-metadata
  labels:
    app: pod-nodename-labels
spec:
  containers:
  - name: pod-nodename-containers
    image: 192.168.1.158:5000/nginx:latest
    ports:
    - containerPort: 80
  nodeName: worker2    # 배치하고 싶은 노드 선택
---
apiVersion: v1
kind: Service
metadata:
  name: pod-nodename-service
spec:
  type: NodePort
  selector:
    app: pod-nodename-labels
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
//

# kubectl apply -f pod-nodename.yaml
# kubectl get po -o wide

지정한 워커2 노드에 생성됨.

노드 셀렉터(수동 배치)

# 노드에도 라벨이 존재
kubectl get nodes --show-labels

# 노드한테 원하는 라벨 부여
kubectl label nodes worker1 tier=dev

워커1의 라벨 부여

# 노드 셀렉터 템플릿 생성 
vi pod-nodeselector.yaml
//
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector-metadata
  labels:
    app: pod-nodeselector-labels
spec:
  containers:
  - name: pod-nodeselector-containers
    image: 192.168.1.158:5000/nginx:latest
    ports:
    - containerPort: 80
  nodeSelector:
    tier: dev    # 라벨이 tier: dev인 노드에 생성됨
---
apiVersion: v1
kind: Service
metadata:
  name: pod-nodeselector-service
spec:
  type: NodePort
  selector:
    app: pod-nodeselector-labels
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
//

라벨이 tier=dev인 워커1에 배치됨.

# 라벨 제거
kubectl label nodes worker1 tier-

# kubectl get nodes --show-labels
라벨 제거.

taint와 toleration

노드에 taint를 설정할 수 있으며, 해당 노드에 파드를 생성할 때, taint에 맞는 toleration이 있어야 생성이 된다.

# worker1,2에 테인트 세팅
kubectl taint node worker1 tier=dev:NoSchedule
kubectl taint node worker2 tier=gpu:NoSchedule

# kubectl describe nodes worker1

# 위에서 사용한 템플릿 복사 후 수정
cp pod-schedule2.yaml pod-schedule3.yaml
vi pod-schedule3.yaml
//
사진처럼 이름에 3 붙이기
//

테인트가 없으면 배치될 곳이 없어서 Pending상태에서 머무른다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deployment2

  template:
    metadata:
      name: nginx-deployment2
      labels:
        app: nginx-deployment2
    spec:
      containers:
      - name: nginx-deployment-container2
        image: 192.168.1.158:5000/nginx:latest
        ports:
        - containerPort: 80
      tolerations:
      - key: "tier"
        operator: "Equal"
        value: "gpu"
        effect: "NoSchedule"
테인트를 지정해줘야 지정된 노드에 배치된다.

# 테인트 테스트용 템플릿 생성
vi pod-taint.yaml
//
apiVersion: v1
kind: Pod
metadata:
  name: pod-taint-metadata
  labels:
    app: pod-taint-labels
spec:
  containers:
  - name: pod-taint-containers
    image: 192.168.1.158:5000/nginx:latest
    ports:
    - containerPort: 80
  tolerations:      # 노드 taint에 맞는 toleration
  - key: "tier"
    operator: "Equal"
    value: "dev"
    effect: "NoSchedule"
---
apiVersion: v1
kind: Service
metadata:
  name: pod-taint-service
spec:
  type: NodePort
  selector:
    app: pod-taint-labels
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
//

# kubectl apply -f pod-taint.yaml
# kubectl get pod -o wide

 


toleration과 짝인 taint를 가진 worker1에 생성된다.

 


# 테인트 제거
kubectl taint node worker1 tier=dev:NoSchedule-
테인트가 없는 노드가 생기자, Pending이었던 파드가 배치됐다.

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename-metadata
  labels:
    app: pod-nodename-labels
spec:
  containers:
  - name: pod-nodename-containers
    image: nginx
    ports:
    - containerPort: 80
  nodeName: worker1
---
apiVersion: v1
kind: Service
metadata:
  name: pod-nodename-service
spec:
  type: NodePort
  selector:
    app: pod-nodename-labels
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

이러한 테인트는 수동 배치로 노드를 직접 지정해주면 테인트가 안맞아도 배치가 가능하다.


cordon

커든 명령은 지정된 노드에 추가로 파드를 자동 스케줄하지 않는다.

# 노드의 상태를 확인
kubectl top node
kubectl get nodes

# worker1에 cordon을 사용하여 더 이상 스케줄링이 안되게 설정
kubectl cordon worker1

# worker1에 cordon 해제
kubectl uncordon worker1

 


cordon된 worker1에는 스케줄링되지 않는다.

수동 스케줄링 같은 경우는 테인트와 마찬가지로 cordon도 무시하고 배치시킨다.


drain

드레인 명령은 지정된 노드에 모든 파드를 다른 노드로 이동시킨다.

# drain 사용
kubectl drain worker2 --ignore-daemonsets --force --delete-local-data

# uncordon을 이용하여 drain으로 인한 스케줄링 불가 상태 해제
kubectl uncordon worker2
drain이 된 노드는 자동 스케줄링 불가로 변한다.
기존에 워커2에 있던 파드들이 워커1로 이동(사실 삭제 후 재생성)

uncordon