1.10.4 Custom Scheduler 사용하기
OKE에서는 default-scheduler를 사용자에게 열어주고 있지 않습니다. 이런 상황에서 스케줄러를 확장하기 위해 쿠버네티스에서 제공하는 multiple schedulers 기능이 잘 동작하는 지 쿠버네티스 문서상의 내용을 따라 확인해 봅니다.
스케줄러 패키징
여기서는 default-scheduler 원 소스 Kubernetes source code from GitHub를 이용하여 두 번째 스케줄러를 배포합니다. 여기서는 이후 옵션, 설정값만으로 커스터마이징하겠습니다. 필요에 따라 스케줄러 소스를 자체를 변경할 수도 있겠습니다.
복제한 kube-scheduler 소소를 패키징합니다.
git clone --depth 1 --single-branch --branch release-1.26 https://github.com/kubernetes/kubernetes.git cd kubernetes make all WHAT=cmd/kube-scheduler GOFLAGS=-v
- 빌드후 생성된 바이너리를 확인할 수 있습니다.
thekoguryo@cloudshell:kubernetes (ap-chuncheon-1)$ ls -la ./_output/local/bin/linux/amd64/kube-scheduler -rwxr-xr-x. 1 thekoguryo oci 53497856 Aug 1 04:46 ./_output/local/bin/linux/amd64/kube-scheduler
컨테이너 이미지를 생성하기 위해 Dockerfile을 만듭니다.
FROM busybox ADD ./_output/local/bin/linux/amd64/kube-scheduler /usr/local/bin/kube-scheduler
이미지를 빌드해서 OCIR에 등록합니다.
- 1.5 OCIR 이미지 사용하기 참조하여 등록합니다.
# 로그인 docker login -u '<tenancy-namespace>/<username>' yny.ocir.io # 이미지 빌드후 등록: 예, 춘천 리전 docker build -t yny.ocir.io/<tenancy-namespace>/my-kube-scheduler:1.0 . docker push yny.ocir.io/<tenancy-namespace>/my-kube-scheduler:1.0
- 편의상 OCIR Repository는 Public으로 전환하였습니다.
스케줄러 배포 파일 수정
배포 파일을 다운로드 받습니다.
wget https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/admin/sched/my-scheduler.yaml
배포 파일에서 이미지 주소를 변경합니다.
- image 주소를 본인이 등록한 OCIR 주소로 변경합니다.
- 스케줄러 실행 옵션
- kube-scheduler
- 옵션 값을 변경할 수 있습니다. 여기서는 예시로 command에
- --v=4
을 추가하여 로그 레벨을 변경합니다.
... containers: - command: - /usr/local/bin/kube-scheduler - --config=/etc/kubernetes/my-scheduler/my-scheduler-config.yaml - --v=4 image: yny.ocir.io/<tenancy-namespace>/my-kube-scheduler:1.0 ...
OKE 클러스터 버전인 1.25 이상에 배포하는 경우, 배포 파일에서 apiVersion의 /v1으로 변경합니다.
- 스케줄러 설정
- default-scheduler와 소스코드 동일하더라도, 여기 있는 KubeSchedulerConfiguration 설정을 통해 스케줄러 설정을 커스터마이징할 수 있습니다.
- 예시는 NodeResourcesFit 플러그인의 스코어링 정책을 일부 변경적용한 예입니다.
- 추가 설정은 KubeSchedulerConfiguration 을 참고합니다.
... --- apiVersion: v1 kind: ConfigMap metadata: name: my-scheduler-config namespace: kube-system data: my-scheduler-config.yaml: | apiVersion: kubescheduler.config.k8s.io/v1 kind: KubeSchedulerConfiguration profiles: - schedulerName: my-scheduler pluginConfig: - name: NodeResourcesFit args: scoringStrategy: resources: - name: cpu weight: 1 type: MostAllocated leaderElection: leaderElect: false ...
- 스케줄러 설정
클러스터에 두번째 스케줄러 배포
작성한 배포 파일로 배포합니다.
kubectl apply -f my-scheduler.yaml
배포된 스케줄러를 확인합니다.
kubectl get pods --namespace=kube-system
- 결과
$ kubectl get pods --namespace=kube-system NAME READY STATUS RESTARTS AGE ... my-scheduler-5fb44c4fb9-kqwqc 1/1 Running 0 4m17s ...
스케줄러 테스트
스케줄러 이름 지정없이 Pod를 배포합니다.
kind: Pod metadata: name: no-annotation labels: name: multischeduler-example spec: containers: - name: pod-with-no-annotation-container image: registry.k8s.io/pause:2.0
- 실행
wget https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/admin/sched/pod1.yaml kubectl apply -f pod1.yaml
default-scheduler로 지정 배포합니다.
apiVersion: v1 kind: Pod metadata: name: annotation-default-scheduler labels: name: multischeduler-example spec: schedulerName: default-scheduler containers: - name: pod-with-default-annotation-container image: registry.k8s.io/pause:2.0
- 실행
wget https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/admin/sched/pod2.yaml kubectl apply -f pod2.yaml
my-scheduler로 지정 배포합니다.
apiVersion: v1 kind: Pod metadata: name: annotation-second-scheduler labels: name: multischeduler-example spec: schedulerName: my-scheduler containers: - name: pod-with-second-annotation-container image: registry.k8s.io/pause:2.0
- 실행
wget https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/admin/sched/pod3.yaml kubectl apply -f pod3.yaml
결과 확인
첫번째 배포한 pod1은 스케줄러를 지정하지 않은 경우, default-scheduler가 스케줄링한 것을 볼 수 있습니다.
$ kubectl describe pod no-annotation Name: no-annotation ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 4s default-scheduler Successfully assigned default/no-annotation to 10.0.10.112 ...
default-scheduler를 지정한 두번째 pod2는, default-scheduler가 스케줄링한 것을 볼 수 있습니다.
$ kubectl describe pod annotation-default-scheduler Name: annotation-default-scheduler ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 16s default-scheduler Successfully assigned default/annotation-default-scheduler to 10.0.10.112
두번째 스케줄러인 my-scheduler로 지정한 세번째 pod3는, my-scheduler가 스케줄링한 것을 볼 수 있습니다.
$ kubectl describe pod annotation-second-scheduler Name: annotation-second-scheduler ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 15s my-scheduler Successfully assigned default/annotation-second-scheduler to 10.0.10.112
배포한 스케줄러의 로그를 확인합니다.
FLAG: --v="4"
에서 변경한 로그레벨이 적용된 것을 볼 수 있습니다. 두 번째 pod2(annotation-default-scheduler)에 대해서는 직접 스케줄하지 않았고, 세 번째 pod3(annotation-second-scheduler)는 “Attempting to schedule pod” 로그에서 보듯이 배포한 두 번째 스케줄러가 스케줄링한 것을 확인할 수 있습니다.$ kubectl logs -n kube-system -f my-scheduler-587dd655fb-sf9w5 ... I0801 07:12:36.759716 1 flags.go:64] FLAG: --v="4" ... I0801 07:13:56.973413 1 eventhandlers.go:197] "Add event for scheduled pod" pod="default/annotation-default-scheduler" I0801 07:13:56.991814 1 eventhandlers.go:218] "Update event for scheduled pod" pod="default/annotation-default-scheduler" I0801 07:13:58.711914 1 eventhandlers.go:218] "Update event for scheduled pod" pod="default/annotation-default-scheduler" ... I0801 07:14:26.843405 1 eventhandlers.go:126] "Add event for unscheduled pod" pod="default/annotation-second-scheduler" I0801 07:14:26.843517 1 schedule_one.go:80] "About to try and schedule pod" pod="default/annotation-second-scheduler" I0801 07:14:26.843527 1 schedule_one.go:93] "Attempting to schedule pod" pod="default/annotation-second-scheduler" I0801 07:14:26.843792 1 default_binder.go:53] "Attempting to bind pod to node" pod="default/annotation-second-scheduler" node="10.0.10.112" I0801 07:14:26.854440 1 eventhandlers.go:171] "Delete event for unscheduled pod" pod="default/annotation-second-scheduler" I0801 07:14:26.854457 1 eventhandlers.go:197] "Add event for scheduled pod" pod="default/annotation-second-scheduler" I0801 07:14:26.856109 1 schedule_one.go:285] "Successfully bound pod to node" pod="default/annotation-second-scheduler" node="10.0.10.112" evaluatedNodes=1 feasibleNodes=1 I0801 07:14:26.878836 1 eventhandlers.go:218] "Update event for scheduled pod" pod="default/annotation-second-scheduler"
참고
이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.