Scheduler

Kubernetes cluster의 default scheduler는 nodes들 전반에 걸쳐서 어떻게 Pod를 배치할지 결정하는 역할을 한다. 각 node들의 상태와 affinity, tolerations, taints, selector등의 조건들을 기준으로 Pod의 배치를 결정한다.

하지만 kubernetes가 제공하는 조건들 외에 추가적인 조건을 확인해야 한다면? 사용자가 원하는 스케쥴러를 사용할 수 있다.

Multiple scheduler

사용자는 기본 스케쥴러 대신에 새로운 스케쥴러를 만들어 기본 스케쥴러를 대체하거나 사용자가 만든 스케쥴러를 추가로 배치할 수 있다.

사용자는 Pod가 배치될 때 스케쥴러를 지정할 수 있다.

  • kubernetes의 기본 스케쥴러는 kube-scheduler이며, 사용자가 생성한 스케쥴러는 이름이 고유해야한다.

default-scheduler 대체

kube-scheduler를 배치할 때 defaut-scheduler의 바이너리를 이용할 수 있다. 다음은 기본 바이너리를 이용해서 추가적인 작업을 하도록 스케쥴러를 배포하는 예시다.

ExecStart=/usr/local/bin/kube-scheduler \\
  --config=/etc/kubernetes/config/my-scheduler-2-config.yaml

my-scheduler-2-config.yaml

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: my-scheduler-2
leaderElection:
  leaderElect: true
  resourceNmaspace: kube-system
  resourceNmae: lock-object-my-shed
  • leaderElection: muilti master 상황에서 HA 제공을 위해 leader를 선출하는 옵션. 동시에 여러 kube-scheduler가 실행되지만 하나의 kube-scheduler만이 leader가 되어 명령을 처리한다.

커스텀 scheduler 배포

커스텀 scheduler 배포 테스트를 위해 다음과 같이 yaml파일을 생성한다.

apiVersion: v1
kind: Pod
metadata:
  name: my-custo-schjeduler
  naespace: kube-system
spec:
  containers:
  - command:
    - kube-scheduler
    - --address=127.0.0.1
    - --kubeconfig=/etc/kubernetes/scheduler.conf #1
    - --config=/etc/kubernetes/my-scheduler-config.yaml #2
    image: k8s.gcr.io/kube-scheduler-amd64:v1.11.3
    name: kube-scheduler
  • 1은 kubernetes scheduer의 default config파일로 인증정보가 명시되있다.
  • 2는 사용자가 정의한(앞서 우리가 정의한) scheduler를 명기한다.

config에 명시한 config 파일을 전달하려며면 다양한 방법이 있지만 여기서는 kubernetes document에서 설명하는 Deployment 예시를 보도록 하자.

spec:
  selector:
    matchLabels:
      component: scheduler
      tier: control-plane
  replicas: 1
  template:
    metadata:
      labels:
        component: scheduler
        tier: control-plane
        version: second
    spec:
      serviceAccountName: my-scheduler
      containers:
      - command:
        - /usr/local/bin/kube-scheduler
        - --config=/etc/kubernetes/my-scheduler/my-scheduler-config.yaml #3
        image: gcr.io/my-gcp-project/my-kube-scheduler:1.0
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10259
            scheme: HTTPS
          initialDelaySeconds: 15
        name: kube-second-scheduler
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10259
            scheme: HTTPS
        resources:
          requests:
            cpu: '0.1'
        securityContext:
          privileged: false
        volumeMounts:
          - name: config-volume #2
            mountPath: /etc/kubernetes/my-scheduler
      hostNetwork: false
      hostPID: false
      volumes:
        - name: config-volume #1
          configMap:
            name: my-scheduler-config

다음의 과정을 따라 한다.

  1. ConfigMap에 선언
  2. ConfigMap을 Volume으로 mount
  3. config 명기

위 과정을 진행하면 Pod는 ConfigMap 타입으로 선언된 값을 Pod내에서 매핑할 수 있다.

커스텀 scheduler 사용

사용자가 임의로 추가한 scheduler가 다음 처럼 배치되어 있다고 가정해 보자.

hugh@master:~/yaml $ kubectl get po -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-7ddc4f45bc-9pnx2   1/1     Running   0          14d
calico-node-47qww                          1/1     Running   0          13d
calico-node-7jhns                          1/1     Running   0          14d
calico-node-bcc6k                          1/1     Running   0          13d
calico-node-ktb4h                          1/1     Running   0          13d
coredns-5dd5756b68-2v7jg                   1/1     Running   0          14d
coredns-5dd5756b68-5mzgx                   1/1     Running   0          14d
etcd-master                                1/1     Running   5          14d
kube-apiserver-master                      1/1     Running   7          14d
kube-controller-manager-master             1/1     Running   0          14d
kube-proxy-4frxk                           1/1     Running   0          13d
kube-proxy-bsxdb                           1/1     Running   0          13d
kube-proxy-pc8ld                           1/1     Running   0          13d
kube-proxy-scnbt                           1/1     Running   0          14d
kube-scheduler-master                      1/1     Running   9          14d
my-scheduler                               1/1     Running   0          10m

그리고 사용자가 Pod하나를 배치할 때, 사용자가 추가한 스케쥴러를 사용하고 싶다면 schedulerName에 해당 scheduler를 명기하면 된다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
  schedulerName: my-scheduler # <--

my-scheduler를 사용해 배치된 Pod는 k8s events를 통해 확인할 수 있다.

hugh@master:~/yaml $ kubectl get event -o wide
LAST SEEN   TYPE     REASON      OBJECT                       SUBOBJECT                SOURCE                                    MESSAGE                                                                    FIRST SEEN   COUNT   NAME
63s         Normal   Scheduled   pod/nginx                                             my-scheduler, my-scheduler-my-scheduler   Successfully assigned default/nginx to worker2                             63s          1       nginx.17b71994464b2560

사용된 custom scheduler의 yaml파일은 여기서 다운받을 수 있다.