반응형

파드 스케줄링

파드를 만들때 어떤 노드에서 실행할지 다양한 옵션으로 선택할 수 있다.

NodeSelector(노드 셀렉터)

  • 설정
    spec:
      containers:
      nodeSelector:
        key: value

Node Affinity

  • 노드 레이블을 기반으로 파드를 스케줄링 한다.
  • 노드 셀렉터를 함께 설정할 경우 둘다 만족하는 노드에 스케줄링된다.
  • requiredDuringSchedulingIgnoredDuringExecution : 스케줄링 하는동안 꼭 필요한 조건
  • preferredDuringSchedulingIgnoredDuringExecution : 만족하면 좋은 조건. (필수아님)
  • 스케줄링 하는 동안 조건이 변경되더라도 무시한다.
  • 설정
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: beta.kubernetes.io/os
                operator: In
                values:
                - linux
                - window
              - key: disktype
                operator: Exists
          preferredDuringSchedulingIgnoredDuringExecution  
          - weight: 10
            preference:
              matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - worker-node01
    • operators : In, NotIn, Exists, DoesNotExist, Gt(Greater than), Lt(Lower than)

Pod affinity, antiAffinity

  • affinity: 서로 연관성이 있는 Pod 를 같은 노드에 배치
  • antiAffinity: 자원을 많이 차지 하는 Pod 를 서로 다른 노드에 배치
  • 설정
    spec:
        affinity:
          podAntiAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - store
              topologyKey: "kubernetes.io/hostname"
    • app 필드 값이 store 인 노드는 피해서 스케줄링 한다.
    • topologyKey : affinity 를 만족하면 topologyKey 기준으로 같은 노드에 pod 를 실행하고 anitiAffinity를 만족하면 topologyKey 기준으로 다른 노드에 pod 를 실행한다.

taint, toleration

  • 테인트를 설정한 노드는 스케줄링 하지 않는다.
  • 테인트를 설정한 노드에 스케줄링 하려면 톨러레이션을 설정해야 한다.
  • kubectl taint nodes 노드명 key01=value01:NoSchedule (key=value:효과)
  • kubectl taint nodes 노드명 key01=value01:NoSchedule- (테인트 제거)
  • 톨러레이션
    spec:
      tolerations:
      - key: "key01"
        operator: "Equal"
        value: "value01"
        effect: "NoSchedule"
    • effect
      • NoSchedule : 톨러레이션 설정 없으면 스케줄링 안함.
      • PreferNoSchedule : 스케줄링 안하지만 자원 부족하면 할수도 있음
      • NoExecute : 스케줄링 안하며 기존 파드도 설정이 없는경우 종료시킴

cordon, drain

  • cordon
    • 지정한 노드에 추가로 파드를 스케줄링 하지 않는다.
    • kubectl cordon 노드명
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS     ROLES    AGE   VERSION
      master01-virtualbox   Ready      master   79d   v1.19.2
      worker01-virtualbox   Ready      <none>   79d   v1.19.2
      worker02-virtualbox   NotReady   <none>   79d   v1.19.2
      master01@master01-VirtualBox:~$ kubectl cordon worker01-virtualbox
      node/worker01-virtualbox cordoned
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS                     ROLES    AGE   VERSION
      master01-virtualbox   Ready                      master   79d   v1.19.2
      worker01-virtualbox   Ready,SchedulingDisabled   <none>   79d   v1.19.2
      worker02-virtualbox   NotReady                   <none>   79d   v1.19.2
      master01@master01-VirtualBox:~$ kubectl uncordon worker01-virtualbox
      node/worker01-virtualbox uncordoned
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS     ROLES    AGE   VERSION
      master01-virtualbox   Ready      master   79d   v1.19.2
      worker01-virtualbox   Ready      <none>   79d   v1.19.2
      worker02-virtualbox   NotReady   <none>   79d   v1.19.2
  • drain
    • 지정된 노드에 있는 파드를 다른 노드로 옮긴다.
    • 노드에 데몬셋이 존재할 경우 적용 불가능
    • 데몬셋 무시하고 적용할 경우 --ignore-daemonsets=true 옵션 추가
    • 컨트롤러를 이용하지 않은 파드들도 drain 불가능

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

현재 시스템의 구성은 다음과 같다

 

MasterNode, Worker1, Worker2

 

여기에 테스트를 위해서 mysql 을 열려놨다. 해당 yaml 은 다음과 같다. 

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: spring
  name: deploy-mysql
  labels:
    app: mysql
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: MYSQL_ROOT_PASSWORD
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: MYSQL_DATABASE
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: MYSQL_USER
        ports:
        - containerPort: 3306
          name: mysql
          protocol: TCP
        volumeMounts:
        - mountPath: "/var/lib/mysql"
          name: mysql-volume
          subPath: dbdata
      volumes:
      - name: mysql-volume
        persistentVolumeClaim:
          claimName: mysql-pvc

그런데 한가지 문제가 생겼다. 

나는 K8S 를 사용하기 위해 virtual box 에서 master, worker1, worker2 이렇게 순서대로 헤드리스로 기동을 시킨다.

그런데 가끔 worker2 가 Ready 가 되기 전에 deployment 의 replicaset 이 같은 노드에 할당 되는 상황이 발생했다.

그러다 보니 pod 가 정상적으로 뜨지 않게 되었다. 

 

그냥 Pod 를 실행시키는 거라면 nodeselector 를 설정하면 될텐데 Deployment는 어떻게 하는지 몰라서 찾아보니 다음과 같이 spec 에 affinity 를 추가하는 방법을 찾을 수 있었다. 

      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - mysql
            topologyKey: "kubernetes.io/hostname"

 

위 설정에는 affinity 설정중 podAntiAffinity 설정을 추가하였다. 설정을 차례대로 해석하면 다음과 같다.

 

podAntiAffinity : 이 pod 가 실행될때 다음 값이 참이면 안된다.

requiredDuringSchedulingIgnoredDuringExecution : 반드시 만족해야 한다. (또다른 설정으로는 preffered 가 있다.)

matchExpressions: label 이 key 는 app 이고 값은 mysql 인 label을 찾는다.

 

결과적으로 label 이 app 이고 값이 mysql 인 pod 가 존재하는 node 에서는 pod 가 실행되지 않는다.

그래서 replicas 가 2로 설정되어있기 때문에 각각의 pod 는 각각의 node 에 위치하게 된다. 

 

master01@master01-VirtualBox:~/k8s/mysql$ kubectl get po -n spring -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE                  NOMINATED NODE   READINESS GATES
deploy-mysql-84f7bb885-rn9tz   1/1     Running   1          27h   10.244.1.80   worker01-virtualbox   <none>           <none>
deploy-mysql-84f7bb885-zqlmw   1/1     Running   1          26h   10.244.2.64   worker02-virtualbox   <none>           <none>

 

이거 이외에도 다양한 표현식으로 컨트롤이 가능하다. 

더 자세한 것은 아래 도큐먼트 참고하길 바란다.

 

v1-18.docs.kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/

728x90
반응형

+ Recent posts