쿠버네티스 상에서의 자원 할당

쿠버네티스에서 Pod가 구동되기 위해서는 스케줄링 된 노드 내 가용할 수 있는 리소스를 사용한다.

  • kube-schduler 는 Pod가 필요로 하는 자원을 어느 노드에서 구동시킬 지 결정함.
  • 만일 모든 노드에서 Pod를 구동시킬 수 있는 자원이 충분히 남아있지 않을 경우
    • 스케줄러는 Pod를 할당하지 않고 스케줄링을 멈춤.
    • Pod를 Pending State 이 됨.
      • STATUS=pending 표기가 되며, Event 에도 Insufficient resource로 표기됨

Resource Requirements

  • Resource Requirements 는 Pod를 구동시키기 위해 필요한 최소 자원을 명시하는 것.
  • CPU 수, 메모리의 크기를 명시함.
  • CPU는 경우에 따라 의미가 달라질 수 있음
    • Core
    • 1 AWS vCPU
    • 1 GCP Core
    • 1 Azure Core
    • 1 Hyperthread
    • 코어
  • 메모리의 경우, 크기를 나타냄
    • Mi 메가바이트
    • Gi 기가바이트
      • 1G = 1000MB
      • 1Gi = 1024MB

리소스 리퀘스트 request 명시하기

# pod-definition

apiVersion: v1
kind: Pod
metadata:
	name: ubuntu-sleeper
	labels:
		name: ubuntu-sleeper
		
spec:
	containers:
	- name: ubuntu
		image: ubuntu
		command: 
			- "sleep"
			- "3600"
		
		resources:
			requests:
				memory: "2Gi"
				cpu: 1

리소스 한도 limit 지정하기

# pod-definition

apiVersion: v1
kind: Pod
metadata:
	name: ubuntu-sleeper
	labels:
		name: ubuntu-sleeper
		
spec:
	containers:
	- name: ubuntu
		image: ubuntu
		command: 
			- "sleep"
			- "3600"
		
		resources:
			requests:
				memory: "2Gi"
				cpu: 1
		
			limits:
				memory: "4Gi"
				cpu: 2
  • Pod 애플리케이션이 한도를 초과하게 될 경우
    • 메모리 한도 초과
      • Pod 종료됨
      • OOM (Out Of Memory) 발생
    • CPU 한도 초과
      • CPU는 시스템이 쓰로틀로 제한함

request & limit 설정 조합에 따른 차이

  • CPU 설정

    • requests X - limit X
      • 있는대로 다 사용함
    • requests X - limit O
      • 리퀘스트는 리밋만큼 설정됨
    • requests O - limit O
      • 리퀘스트와 리밋이 모두 요구한대로 설정됨
      • PodA는 자원이 더 요구되는데 리밋 때문에 제한이 되고, PodB의 자원은 그냥 놀고 있다면 , 자원이 묶이는 경우가 발생함
      • 불필요하게 자원을 제한하는 경우도 생김
    • requests O - limit X
      • 최소한의 자원은 보장 받고, 경우에 따라 놀고 있는 자원도 유연하게 쓸 수 있는 설정.
      • 보편적으로는 가장 권장됨.
  • 메모리 설정

    • requests X - limit X
      • 있는대로 다 사용함
    • requests X - limit O
      • 리퀘스트는 리밋만큼 설정됨
    • requests O - limit O
      • 리퀘스트와 리밋이 모두 요구한대로 설정됨
      • Pod A와 B가 있다고 가정할 때, Pod A는 자원이 더 요구되는데 리밋 때문에 제한이 되고, Pod B의 자원은 그냥 놀고 있다면 , 자원이 묶이는 경우가 발생함
      • 불필요하게 자원을 제한하는 경우도 생김
    • requests O - limit X
      • 최소한의 자원은 보장 받음
      • 허용된 자원 이상으로 사용되는 경우 OOM과 함께 종료됨

Resource Quota - Namespace에 리소스 제한 걸기

  • ResourceQuota는 클러스터 레벨에서 Namespace의 총 리소스 사용을 제한하는 오브젝트
  • 적용하고자 하는 Namespace에서 해당 오브젝트를 생성하면 됨.
# ex) resource-quota.yaml

apiVersion: V1
kind: ResourceQuota
metadata:
	name: my-resource-quota
	
spec:
	hard:
		requests.cpu: 4
		requests.memory: 4Gi
		limits.cpu: 10
		limits.memory: 10Gi

LimitRange - Namespace 리소스 설정하기

  • LimitRange 는 Namespace 레벨에서 Pod가 사용할 리소스에 대한 설정을 할 수 있는 오브젝트
  • 디폴트 request와 limit, 상한, 하한선 설정 가능
  • CPU와 메모리에 대한 설정을 개별로 하는 것이 권장됨.
# ex) limit-range-cpu.yaml

apiVersion: v1
kind: LimitRange
metadata:
	name: cpu-resource-constraint
	
spec:
	limits:
		- default:          # default limit on pod
				cpu: 500m
			defaultRequest:   # default request on pod
				cpu: 500m
			max:              # max limit on a container in a pod
				cpu: "1"
			min:              # min request on a container in a pod
				cpu: 100m
			type: Container
# ex) limit-range-memory.yaml

apiVersion: v1
kind: LimitRange
metadata:
	name: cpu-resource-constraint
	
spec:
	limits:
		- default:          # default limit on pod
				memory: 1Gi
			defaultRequest:   # default request on pod
				memory: 1Gi
			max:              # max limit on a container in a pod
				memory: 1Gi
			min:              # min request on a container in a pod
				memory: 500Mi
			type: Container

Reference