데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      Kubernetes Scheduler 설명

      seungkyua 22.05.25
      5,119 6 0

      Pod 가 새롭게 생성되면 Scheduler 를 통해서 Pod 가 실행될 노드를 결정된다. 즉 모든 Pod 는 Scheduler 에 의해서 최적의 노드가 결정되고 실행된다.


      kube-scheduler 는 Control Plane 에 속하는 컴포넌트 중에 하나이며, 디폴트 scheduler 이다. 만약 특별한 스케줄링을 원한다며 커스텀 스케줄러를 만들어서 대체할 수 도 있다.


      Pod 가 스케줄링 되기 위해서는 노드가 스케줄링 요구 사항에 맞아야 하는데 이 때, 요구사항에 맞는 노드를 피저블 노드(feasible node) 라고 한다.


      스케줄러는 피저블 노드를 찾고 적절한 로직을 통해 노드에 점수를 부여한다. 가장 최고 점수를 갖는 노드에 Pod 가 실행된다.


      스케줄링을 결정하는 데에는 하드웨어, 소프트웨어, policy contraints, affinity 와 anti-affinity spec, local data 등 여러 요구 사항들이 있다.



      kube-scheduler 가 결정하는 2-step operation

      1. Filtering

      2. Scoring

      Filtering 단계에서는 피저블 노드를 찾는 단계이다. 예를 들면, PodFitsResources 필터는 Pod 의 request 리소스를 만족하는 리소스를 갖는 후보 노드를 추려낸다. 이 단계 이후에는 적합한 노드 리스트가 도출되는데 만약 노드 리스트의 값이 비었다면 Pod 는 스케줄링 되지 않는다.


      Scoring 단계에서는 필터링된 노드 리스트 중에서 Pod 가 실행될 최적의 노드를 찾는다. 스케줄러는 노드 리스트에 있는 각 노드들에 점수를 부여한다.


      마지막으로 kube-scheduler 는 최고 점수의 노드에 Pod 를 배치한다.


      Filtering 과 Scoring 을 설정할 수 있는 방법은 2가지가 있다.

      1. Scheduling Policies (kubernetes 1.22 버전까지만 사용)

        • Predicates : filtering 을 조절할 수 있음

        • Priorities: scoring 을 조절할 수 있음

      2. Scheduling Profiles (https://kubernetes.io/docs/reference/scheduling/config/#profiles)

        • KubeSchedulerConfiguration 리소스 타입으로 조절할 수 있음

        • plugins 를 통해 Filter 와 Score 를 조절 가능

      NodeSelector

      Node 에 label 을 설정하고 Pod 에서 nodeSelector 로 Node 지정하는 방식이다.

      $ kubectl get nodes -L nginx
      NAME          STATUS   ROLES                  AGE   VERSION   NGINX
      k1-master01   Ready    control-plane,master   92d   v1.21.6
      k1-node01     Ready    ingress                92d   v1.21.6
      k1-node02     Ready    <none>                 92d   v1.21.6   enabled
      k1-node03     Ready    <none>                 92d   v1.21.6   enabled
      k1-node04     Ready    <none>                 92d   v1.21.6
      k1-node05     Ready    <none>                 92d   v1.21.6


      k1-node02 와 k1-node03 에 nginx=enabled 로 label 이 지정되어 있다.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-nodeselector
        namespace: kube-sample
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx:1.21.0
              ports:
              - containerPort: 80
            nodeSelector:
              nginx: enabled


      nodeSelector 를 활용하여 deployment 를 배포하면 아래와 같이 k1-node02 혹은 k1-node03 에 배포된다.

      $ kubectl get pods -n kube-sample -o wide
      NAME                                  READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
      nginx-nodeselector-68977d7759-sf48l   1/1     Running   0          9s    10.233.113.7   k1-node02   <none>           <none>

      Node affinity

      nodeSelector 와 동작 방식이 유사하지만 다음과 같은 차이가 있다.


      requiredDuringSchedulingIgnoredDuringExecution: 스케줄링에서 만족하는 노드가 없으면 스케줄링 되지 않는다.


      preferredDuringSchedulingIgnoredDuringExecution: 스케줄링에서 만족하는 노드를 찾고 노드가 없더라도 스케줄링은 된다. weight 필드의 값을 scoring 에 포함시킨다.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-node-affinity
        namespace: kube-sample
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: nginx
                      operator: In
                      values:
                      - enabled
                  - matchExpressions:
                    - key: kubernetes.io/os
                      operator: In
                      values:
                      - windows
                preferredDuringSchedulingIgnoredDuringExecution:
                - weight: 1
                  preference:
                    matchExpressions:
                    - key: another-node-label-key
                      operator: In
                      values:
                      - another-node-label-value
            containers:
            - name: nginx
              image: nginx:1.21.0
              ports:
              - containerPort: 80

      위와 같이 nodeSelectorTerms 에 여러 개의 matchExpressions 가 있으면 이 중 하나만 만족해도 스케줄링은 된다. nodeSelectorTerms 에 하나의 matchExpressions 가 있고, key value 가 여러 개가 있으면 matchExpressions 내의 모든 조건을 만족해야 스케줄링이 된다.


      operator 로 쓸 수 있는 값은 In, NotIn, Exists, DoesNotExist, Gt, Lt 이다.


      NotIn 과 DoesNotExist 는 node anti-affinity 로 사용 가능하다.

      $ kubectl get pods -n kube-sample -o wide
      NAME                                   READY   STATUS        RESTARTS   AGE    IP              NODE        NOMINATED NODE   READINESS GATES
      nginx-node-affinity-755cf7f85d-ss9q5   1/1     Running       0          5s     10.233.113.10   k1-node02   <none>           <none>

      Pod affinity and anti-affinity

      Pod 를 서로 다른 노드에 배치시키는 방법은 pod anti-affinity 를 통해서 구현할 수 있다.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-pod-anti-affinity
        namespace: kube-sample
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: nginx-pod-anti-affinity
        template:
          metadata:
            labels:
              app: nginx-pod-anti-affinity
          spec:
            affinity:
              podAntiAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - nginx-pod-anti-affinity
                  topologyKey: kubernetes.io/hostname
            containers:
            - name: nginx
              image: nginx:1.21.0
              ports:
              - containerPort: 80

      위와 같이 pod label 에 pod anti affinity 를 설정하면 replicas 값 2 에 의해서 생성되는 2개의 pod 는 서로 다른 노드에 배치된다. topologyKey 는 kubernetes.io/hostname 값으로 세팅하고 특정 node lable 로 하고 싶으면 node affinity 를 추가하면 된다.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-pod-anti-affinity
        namespace: kube-sample
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: nginx-pod-anti-affinity
        template:
          metadata:
            labels:
              app: nginx-pod-anti-affinity
          spec:
            affinity:
              podAntiAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - nginx-pod-anti-affinity
                  topologyKey: kubernetes.io/hostname
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: nginx
                      operator: In
                      values:
                      - enabled
            containers:
            - name: nginx
              image: nginx:1.21.0
              ports:
              - containerPort: 80
      $ kubectl get pods -n kube-sample -o wide
      NAME                                       READY   STATUS    RESTARTS   AGE   IP              NODE        NOMINATED NODE   READINESS GATES
      nginx-pod-anti-affinity-7cfcbcff8f-c2429   1/1     Running   0          14s   10.233.96.3     k1-node03   <none>           <none>
      nginx-pod-anti-affinity-7cfcbcff8f-dmqqm   1/1     Running   0          14s   10.233.113.12   k1-node02   <none>           <none>

      Taint 와 Toleration

      노드에 taint 를 지정하면 해당 노드에 taint effect 를 줄 수 있다. 예를 들어 taint effect 에 NoSchedule 을 준다면 해당 노드에는 pod 가 스케줄링 되지 않는다.


      taint effect 를 제거할 수 있는 방법은 Pod 에 toleration 을 세팅하는 것이다.


      마스터에는 기본적으로 taint 를 지정해서 스케줄링 안되게 세팅해 놓는 것을 알 수 있다.

      $ kubectl describe node k1-master01
      
      Name:               k1-master01
      Roles:              control-plane,master
      Labels:             beta.kubernetes.io/arch=amd64
                          beta.kubernetes.io/os=linux
                          kubernetes.io/arch=amd64
                          kubernetes.io/hostname=k1-master01
                          kubernetes.io/os=linux
                          node-role.kubernetes.io/control-plane=
                          node-role.kubernetes.io/master=
                          node.kubernetes.io/exclude-from-external-load-balancers=
      Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/containerd/containerd.sock
                          node.alpha.kubernetes.io/ttl: 0
                          projectcalico.org/IPv4Address: 192.168.30.13/24
                          volumes.kubernetes.io/controller-managed-attach-detach: true
      CreationTimestamp:  Tue, 08 Feb 2022 21:27:12 +0900
      Taints:             node-role.kubernetes.io/master:NoSchedule


      마지막의 Taints 값은 kubectl 로 세팅할 수 있다.

      $ kubectl taint nodes k1-master01 node-role.kubernetes.io/master=:NoSchedule


      그럼 master 노드에 toleration 을 활용하여 pod 를 배치해 보자.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-toleration
        namespace: kube-sample
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nginx-toleration
        template:
          metadata:
            labels:
              app: nginx-toleration
          spec:
            tolerations:
            - key: node-role.kubernetes.io/master
              operator: Exists
              effect: NoSchedule
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: node-role.kubernetes.io/control-plane
                      operator: Exists
            containers:
            - name: nginx
              image: nginx:1.21.0
              ports:
              - containerPort: 80


      toleration 으로 taint 효과를 없애고 node affinity 를 활용하여 control-plane, 즉 master 노드에 pod 를 배치 시켰다. 물론 master 노드에 node-role.kubernetes.io/control-plane 이라는 label 이 존재해야 한다.


      taint effect 는 NoSchedule, NoExecute, PreferNoSchedule 이 있다.


      NoSchedule 은 스케줄링을 막는 것이고, NoExecute 는 실행중인 pod 를 eviction 시킨다. PreferNoSchedule 은 가능하면 스케줄링 하지 않는다는 의미이다.


      operator 에는 Exists 와 Equal 이 있다. Exists 는 key 값이 존재하는 지를 판단하기 때문에 value 값이 필요 없으며, Equal 은 key 와 value 값이 지정된 값과 일치해야 한다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      seungkyua 님의 최신 블로그

      더보기
      동영상 기고하기