본문 바로가기

DevOps/쿠버네티스

쿠버네티스에서 POD, Node의 리스소 관리(CPU, memory, 등)

쿠버네티스에서의 리소스

## 아래 예제는 unmanaged pod라고 보면됨.(실제로 이렇게 쓰지 않음)

apiVersion: v1
kind: Pod
metadata:
  name: requests-pod
spec:
  containers:
  - image: busybox
    command: ["dd", "if=/dev/zero", "of=/dev/null"]
    name: main
    resources:
      requests: #미니멈 개념, 최소 X가 필요하다.
        cpu: 200m #200밀리코어
        memory: 10Mi #10메가



## pod A가 request설정, pod B도 request설정 pod C도 request설정 그러나 실제 usage는 너무 작다

## 즉, 실제 CPU사용량은 request와는 무관하다.(작을수도, 클수도)

## 하지만! Scheduler가 pod를 배포할 수있을까 말까는 request값에 따라 pod 배포여부를 결정한다. 넘어가버리면 배포를 안함


## request 합은 100을 넘지 못한다. - request sum can not over 100


POD 리소스 전략

## LeastRequestedPriority : 최대한 node에 분산배포한다.

## MostRequestedPriority : request가 한 node로 몰아버린다. aws와 같이 node당 과금이 일어날때 node 최소화할때 사용하면됨. 그러나 병목이 일어날 가능성이 있다!!



## request에 대비하여 실제 usage가 넘어버리면 request의 비율로 몰아버린다.


POD 리소스 limit 설정


## 말그대로 최대값을 제한

## vm vs container에서의 memory : vm에서 memory를 제한걸면 아에 커널에서부터 제한됨, 그러나 컨테이너에서는 실제 node의 memory가 보임. 그래서 process가 수시로 제한된 memory를 넘기려고함. -> 해결방법 : kill

## 그래서, limit을 지나버리면 pod을 restart(kill and start)시켜버린다.
(너무 작게 하면 안됨, 그렇다고 너무 크게 해도 문제, cpu는 상관없음. hz조절 알아서 잘함)


## request를 안주고 limit만 해버리면? limit의 값을 request라고 판단함. 반드시 두개다 설정하는게 가장 좋다.


POD 리소스가 딸릴때 우선순위?

## pod에 대한 QOS classes : BestEffort, Burstable, Guaranteed

## 리소스가 딸려서 위급한 상황에서 죽이는 놈들을 판단하여 죽인다. 즉, process kill 순서임



## BestEffort(가장 우선적으로 죽음) : request나 limit을 둘다 설정하지 않은 애들

## Burstable : best effort, guaranteed 둘다 아닌 경우

## Guaranteed(가장 마지막으로 죽음) : request, limit을 둘다 명시적으로 설정하고, 둘다 같은 값으로 구성한 경우


ABCD 누가 누가 먼저 죽을까?


## 스케쥴러가 볼때는 request 값 기준으로 본다.

## 스케쥴러가 죽일때 request대비 used의 %에 따라 죽이는 여부를 판단한다.

## 즉 B(90% used)가 C(70% used)보다 먼저죽는다.



POD의 Limit Range

apiVersion: v1
kind: LimitRange
metadata:
  name: example
spec:
  limits:
  - type: Pod ##pod들은 cpu나 메모리를 아래 값에 셋팅됨
    min:
      cpu: 50m
      memory: 5Mi
    max:
      cpu: 1
      memory: 1Gi
  - type: Container
    defaultRequest: ##requeset
      cpu: 100m
      memory: 10Mi
    default: ##limit
      cpu: 200m
      memory: 100Mi
    min:
      cpu: 50m
      memory: 5Mi
    max:
      cpu: 1
      memory: 1Gi
    maxLimitRequestRatio:
      cpu: 4
      memory: 10
  - type: PersistentVolumeClaim
    min:
      storage: 1Gi
    max:
      storage: 10Gi


$ k create -f limit.yml

$ k get limitrange

$ k describe limitrange example



## 앞으로 배포될 값들은 상기 limitrange를 따르게 된다.


POD가 limit에 대비해 더 큰 pod를 배포하려고하면?

apiVersion: v1
kind: Pod
metadata:
  name: too-big
spec:
  containers:
  - image: busybox
    args: ["sleep", "9999999"]
    name: main
    resources:
      requests:
        cpu: 2


$ k create -f limits-pod-too-big.yaml ##오류가 나면서 배포되지 않는다.

$ k delete limitrange example ## limit 지우기

$ k create -f limits-pod-too-big.yaml ## limit지우니깐 배포 잘됨




POD quota 설정하기

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cpu-and-mem
spec:
  hard:
    requests.cpu: 400m
    requests.memory: 200Mi
    limits.cpu: 600m
    limits.memory: 500Mi ##해당 네임스페이스의 토탈이 넘어가지 못하도록 설정


$ k create -f quota-cpu-memory.yaml

$ k get quota

$ k describe quota cpu-and-mem


생성 가능한 POD수 제한

apiVersion: v1
kind: ResourceQuota
metadata:
  name: objects
spec:
  hard:
    pods: 10
    replicationcontrollers: 5
    secrets: 10
    configmaps: 10
    persistentvolumeclaims: 5
    services: 5
    services.loadbalancers: 1
    services.nodeports: 2
    ssd.storageclass.storage.k8s.io/persistentvolumeclaims: 2


## 각 팀별로 namespace로 배포해주고, 그 안에서 양을 제한해주는 방법이 있음

## cloud에서는 이것을 빌링시스템으로 붙여버림.




그림 퍼온 사이트 : https://livebook.manning.com/#!/book/kubernetes-in-action/chapter-14/92