k8s scheduling (2)

iwin1203·2022년 12월 12일
0

백엔드&DevOps

목록 보기
9/9

Resource Requirements and Limits

  • pod는 cpu / mem / disk를 사용한다.
  • pod definition file에서 specify한대로 node에 배정된다.
// pod.yaml

spec:
	containers:
    - name: testcont
      image: testcont
      ports:
      	- containerPort: 8080
      resources:
      	requests:
        	memory: "1Gi"
            cpu: 1
  • 1cpu == 1 AWS vCPU == 1 GCP Core == 1 Azure Core == 1 Hyperthread
  • 기존 도커는 default 설정에서는 리소스에 제한이 없다. 하나가 커지면 다른 컨테이너 자리 잡아먹어서 suffocate한다.
  • 반면, k8s는 default로 "1 vcpu, 512 mb"의 리소스 제한이 있다.
    • cpu는 기준치 넘어가면 바로 차단하지만, mry는 기준치 넘어가도 사용 가능하다. 한 pod의 mry 제한을 다 쓰면 그때 터진다.
  • 주의! 이 limit은 전부 node 내 pod 내 컨테이너 각각에 적용되는 것이다!

https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/

pod와 deployments의 수정 팁

  • 다음 네 가지 외에 이미 돌아가는 pod의 내용을 바꿀 수 없다.
    • spec.containers[*].image
    • spec.initContainers[*].image
    • spec.activeDeadlineSeconds
    • spec.tolerations
  • 가령, 환경 변수나 resource limit을 바꾸려면,
    • kubectl edit pod <pod name> 하고 내용을 수정한 뒤, deni됨을 확인하고, 기존 Pod를 삭제하고, 생성된 tmp 파일로 새로 create한다.
      -kubectl get pod webapp -o yaml > my-new-pod.yaml 로 현재 pod definition을 뽑고, 얘를 수정한 뒤, 기존 pod를 삭제하고, 새로운 my-new-pod.yaml로 create한다.
  • 반면 deployments는 자유로이 수정 가능하다.

Daemon Sets

  • Daemon Sets은 rs와 비슷하다. 클러스터 내 모든 node 내에 pod이 무조건 하나는 떠 있게 해준다.
  • 가령, 클러스터를 모니터링하는 pod가 무조건 떠 있어야 할 때 사용할 수 있다. / kube proxy / networking
  • 생성 방법은 kind 제외하면 rs와 동일하다.
    kubectl get daemonsets
    kubectl describe daemonsets <ds name>
  • v1.12까지는 내부적으로 nodeName을 creation time에 명시해서 곧바로 해당 노드에 꽂히게 한다.
  • v1.12부터는 default scheduler와 node affinity를 사용해서 꽂는다.

Static Pods

  • k8s cluster나 master node, api server,, 등 어떠한 오브젝트의 개입 없이, 노드 내에서 직접 kubelet에 의해 생성되는 pod를 static pods라 한다.
  • 이건 pod만 된다. rs나 deployment는 불가. 애초에 kubelet은 pod 레벨이다.
  • /etc/kubernetes/manifests 에 yaml file을 올린다.
  • 위 경로를 kubelet.service file에 cmdline option으로 직접 주거나, kubeconfig.yaml을 새로 만들어서 여기에 넣어줘도 된다.
  • Q) 그럼 kube api server가 있고, 얘가 Pod 생성 요청하는데, 동시에 Static Pods 생성용 파일도 있으면?
  • A) kubelet은 동시에 둘 다 만들 수 있다. kube api server도 static pod의 존재를 인지하긴 한다. (kube api server가 볼 수 있는 read-only mirror pod가 생성되기 때문이다.)
  • 근데, 이걸 대체 왜 써? -> Master Node에서 중요한 pod (controller, etcd, apiserver 등)를 생성하고, 꺼지지 않게 유지하기 위해서 static pod로 둔다. 이게 k8s cluster를 처음 생성할 때 진행되는 것이다.

daemon sets vs static pods

  • daemon sets는 모든 노드에 최소 하나의 인스턴스는 보장하기 위해 사용된다.
  • ds는 kube api server (ds controller)에 의해 생성된다. 모니터링, 로깅 agent를 심는데 주로 사용된다.
  • static pods는 kube api server 간섭 없이, kubelet이 직접 생성한다. control plane의 요소들을 생성하는 데 사용된다.
  • kube scheduler는 둘 다 무시한다.

Multiple Schedulers

  • k8s에서는 여러 scheduler를 사용할 수 있다. 나만의 커스텀 scheduler도.
  • 각 sch는 이름이 달라야하고, 당연히 각각 다른 conf 파일로 생성해야 한다.
  • 가장 간단한 방법은 scheduler를 하나의 pod로 생성하는 것이다.
// my-custom-scheduler.yaml

kind: Pod
metadata:
	name: my-custom-scheduler
    namespace: kube-system
spec:
	containers:
    - command: 
      - kube-scheduler
      - --address=127.0.0.1
      - --kubeconfig=/etc/kubernetes/scheduler.conf // auth to connect to kube api server
      - --config=/etc/kubernetes/my-scheduler-config.yaml
      image: k8s.gcr.io/kube-scheduler-amd64:v1.11.3
      name: kube-scheduler
// my-scheduler-config.yaml

kind: KubeSchedulerConfiguration
profiles:
- schedulerName: my-scheduler
leaderElection: // multiple이 떠있을 때, 누가 리딩할꺼냐. (하나만 active 할 수 있다. HA 섹션에서 다시 다룰 것)
	leaderElect: true
    resourceNamespace: kube-system
    resourceName: lock-object-my-scheduler
// pod.yaml

...
spec:
	schedulerName: my-custom-scheduler

Configuring Scheduler Profiles

  • scheduler는 pod의 조건을 충족하는 node에 호스팅시켜주는 역할이었다.
  • 과정 1) Scheduling Queue에 pod들이 담긴다. 이때 priority에 의해 queue에서 순서가 생성된다.
  • 과정 2) highest priority pod에 대해, 호스팅 시킬 수 없는 node들을 filter out한다. (Filtering Phase)
  • 과정 3) 2까지 통과한 노드들에 대해 점수를 매긴다. 더 높은 점수 == pod을 호스팅할 자격! (Scoring Phase)
  • 과정 4) 가장 높은 노드에 pod이 binding 된다. (Binding Phase)
  • 위 과정은 모두 plugin으로 진행된다. 가령, 1에는 PrioritySort, 2에는 NodeResourcesFit, NodeName, NodeUnschedulable, 3에는 NodeResoucesFit, ImageLocality, 4에는 DefaultBinder
  • 위는 default일 뿐이고, 우리의 plugin은 'extension point'를 사용하여 꽂을 수 있다. queueSort plugin, preFilter, filter, postFilter, preScore, score ... 다양한 플러그인
  • 위와 같은 scheduler 내부 내용을 정리, 명문화해놓은게 profile이다.
  • Multiple Schedule을 사용하는 가장 기본적인 방법은 각자 다 yaml 파일 만들어서 create하는 것이다. 그러나 이 방법은 귀찮고, 불필요한 자원이 투입된다. 무엇보다, scheduler간 race condition 발생 가능성이 있다.
  • 1.18부터는 한 scheduler 내에 여러 profile을 둘 수 있게 되었다.
my-scheduler.yaml
apiVersion: ~
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: sch1
  plugins: // 이 아래가 extension point이다.
    score:
      disabled:
      - name: ~
      enabled:
      - name: ~
- schedulerName: sch2

- schedulerName: sch3

0개의 댓글