본문 바로가기
Infra/Kubernetes

[Kubernetes] Namespace, ResourceQuota, LimitRange

by 진꿈청 2024. 9. 4.

Kubernetes

 

 

이번 포스팅에서는 `Namespace`, `ResourceQuota`, `LimitRange`에 관해 알아보려 한다.

 

우선, 해당 오브젝트들을 왜 사용해야 되는지 먼저 알아보자.

 

 

`Kubernetes` 클러스터 안에는 사용할 수 있는 자원들이 존재한다.

 

일반적으로는 메모리CPU가 있을 것이다.

 

클러스터 안에는 여러 `Namespace`들이 존재하며 `Namespace` 안에는 여러 `Pod`가 생성이 가능하다.

 

각 `Pod`는 필요한 자원을 클러스터 자원을 공유해서 사용하는데,

만약 한 `Namepsace` 안에 있는 `Pod`가 이 클러스터에 남은 자원을 모두 사용해 버리면 다른 `Pod` 입장에서는

더 이상 쓸 자원이 없어서 자원이 필요할 때 문제가 발생한다.

 

이런 문제를 해결하기 위해 `ResourceQuota`라는 것이 존재하는데 이걸 `Namespace`에 달면

`Namespace` 마다 최대 한계를 설정할 수 있게 된다.

 

따라서, `Pod` 자원이 `ResourceQuota`의 한계를 넘을 수 없게 된다.

 

즉, 자원을 많이 필요로 하는 `Pod`가 자원이 부족해서 문제가 될지언정

다른 `Namespace`에 있는 `Pod`에는 영향을 끼치지 않게 해준다. 

 


 

다음으로, 만약 한 `Pod`가 자원 사용량을 너무 크게 해버리면 어떻게 될까?

 

그렇게 되면 다른 `Pod`들이 더 이상 `Namespace`에 들어오지 못할 것이다.

 

이런 경우에 사용하는 것이 `LimitRange`이다.

 

`LimitRange`를 두게 되면 `Namespace`에 들어오는 `Pod`의 크기를 제한할 수 있다.

 

한 `Pod`의 자원 사용량이 `LimitRange`에 설정된 값보다 낮아야 이 `Namespace`에 들어오는 것이 가능하다.

만약, `LimitRange`에 설정된 값보다 클 경우에는 `Pod`가 `Namespace`안에 들어올 수 없다.

 

 

참고로, `LimitRange`와 `ResourceQuota`는 `Namespace`에만 달 수 있는게 아니라,

클러스터에도 달아 전체 자원에 대한 제한을 걸 수도 있다.

 


Namespace

 

 

`Namespace`에 관해 좀 더 알아보자.

 

한 `Namespace` 안에 있는 같은 타입의 오브젝트들은 이름이 중복될 수 없다.

오브젝트들마다 별도의 UUID가 존재하기는 하지만, 한 `Namespace` 안에서는 같은 종류의 오브젝트라면

이름 또한 UUID 같이 유일한 키 역할을 할 수가 있는 셈이다.

 

그리고 `Namespace`의 대표적인 특징은 타 `Namespace`에 있는 자원과 분리가 되어 관리가 된다는 것이다.

 

위의 그림처럼 `nm-1`이라는 `Namespace`가 있고 그 안에 서비스가 존재한다고 했을 때,

다른 `Namespace`에 있는 `Pod`의 `Label`을 서비스셀렉터로 지정을 하여도

`Pod`에는 연결되지 않는다.

 

이뿐만 아니라, 지금까지 배웠던 대부분의 자원들은 그 자원 안에서 만든 `Namespace` 안에서만 사용 가능하다.

 

물론, `Node`나 `PV`과 같이 모든 `Namespace`에서 공용으로 사용되는 오브젝트도 있긴 하다.

 

그리고 `Namespace`에 관한 특징을 하나 더 설명하자면, `Namespace`를 지우게 되면 그 안에 있는

모든 자원들도 지워지기 때문에 `Namespace`를 지울 때는 유의해야 한다.

 

 

만약, 한 `Pod`가 다른 `Namespace`에 있는 `Pod`의 IP로 접근을 하게 된다면 어떻게 될까?

 

기본적으로는 연결이 된다. 하지만, 추후 배워볼 네트워크 폴리시라는 오브젝트를 통해 제한을 할 수가 있다.

 

 

`Namespace` 생성 YAML 파일을 확인해보자.

apiVersion: v1
kind: Namespace
metadata:
  name: nm-1

 

YAML 파일의 내용을 보면 이렇게 `Namespace`를 만들 때는 이름 외에 특별하게 들어가는 것이 없다.

 

Pod

apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  namespace: nm-1
  labels:
    app: pod
spec:
  containers:
  - name: container
    image: kubetm/app
    ports:
    - containerPort: 8080

 

 

Service

apiVersion: v1
kind: Service
metadata:
  name: svc-1
  namespace: nm-1
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080

 

위의 YAML 파일처럼 `Pod`나 `Service`를 만들 때 자기가 속한 `Namespace`를 지정할 수가 있다.

 

만약, 아래와 같은 `Service`를 생성하면 `Namespace`가 서로 틀리기 때문에 셀렉터, 라벨 값이 일치해도 연결되지 않는다.

apiVersion: v1
kind: Service
metadata:
  name: svc-1
  namespace: nm-2
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080

 


ResourceQuota

 

`ResourceQuota`는 자원 한계를 설정하는 오브젝트이다.

 

위의 그림처럼 `Namespace`에 제한하고 싶은 자원을 명시해서 `Namespace`에 달 수가 있다.

 

위의 그림 예시로는 `Namespace`에 들어갈 `Pod`들의 전체 리퀘스트 자원을 최대 1기가로 설정하겠다는 것이며,

메모리의 리밋도 1기가로 설정하겠다는 것을 말한다.

 

근데 여기서 한가지 중요한 것이 있는데 이렇게 `ResourceQuota`가 지정되어 있는 `Namespace`에 `Pod`를 생성하려면

해당 `Pod`는 무조건 자원과 관련된 스펙을 명시해야 한다.

 

만약, 스펙 자체가 없으면 해당 `Namespace`에 만들어지지 않는다.

 

그리고 위의 그림처럼 현재 총 1기가의 requests 중에 0.5기가를 사용하는 `Pod`가 있는데

2기가를 더 사용 하겠다는 `Pod`가 들어오면 만들어지지 않는다.

 

 

ResourceQuota YAML 파일 

apiVersion: v1
kind: ResourceQuota
metadata:
  name: rq-1
  namespace: nm-1
spec:
  hard:
    requests.memory: 1Gi
    limits.memory: 1Gi

 

YAML 파일의 내용을 보면 `ResourceQuota`를 만들 때 할당할 `Namespace` 설정을 한다.

이때 `hard`라는 속성에 제한할 종류와 자원, 그리고 그 한계치가 들어가게 된다.

 

메모리 뿐만 아니라 제한할 수 있는 건 CPU스토리지가 있다.

그리고 오브젝트들의 숫자도 제한할 수 있는데 많은 오브젝트들이 있지만

모든 오브젝트들을 다 제한할 수 있는 건 아니고 `Kubernetes` 버전이 업데이트 되며 제한할 수 있는 수가 늘고 있다.

 

 

Compute Resource : cpu, memory, storage

Objects Count : Pod, Service, ConfigMap, PVC, ... 


LimitRange

 

그 다음은 `LimitRange`에 관한 설명이다.

 

먼저, `LimitRange`의 기능은 각각의 `Pod`마다 `Namespace`에 들어올 수 있는지 자원을 체크를 해준다.

 

체크되는 항목에 관해 알아보자면 위의 그림을 예시로 `min`은 `Pod`에 설정되는

메모리의 리미트 값이 0.1기가를 넘어야 한다는 것이다.

 

그리고 `max`는 0.4기가를 초과할 수 없다는 뜻이다.

 

`maxLimitRequestRatio`는 리퀘스트 값과 리미트 값의 비율이 최대 3배를 넘으면 안된다는 뜻이다.

 

위의 정보를 토대로 그림을 보면 `3-3 Pod`의 경우 리밋의 값이 0.5기가로 `max` 값을 초과하여 해당 `Pod`는 들어갈 수 없다.

 

또한, `defaultRequest`와 `default` 항목이 있는데 해당 항목은 `Pod`에 아무런 스펙 설정을 하지 않았을 때

자동으로 해당 리퀘스트 값과 리미트 값이 위에 명시된 값으로 할당이 된다.

 

 

`LimitRange`의 YAML 파일을 살펴보자.

apiVersion: v1
kind: LimitRange
metadata:
  name: lr-1
spec:
  limits:
  - type: Container
    min:
      memory: 0.1Gi
    max:
      memory: 0.3Gi
    maxLimitRequestRatio:
      memory: 1
    defaultRequest:
      memory: 0.3Gi
    default:
      memory: 0.3Gi

 

`limits` 아래에 여러 옵션을 설정을 할 수가 있는데,

`type`에는 컨테이너 뿐만 아니라 `Pod`단위의 설정과 `PVC` 설정을 진행할 수가 있다.

 

각각의 타입마다 지원되는 옵션의 종류가 다르므로 해당 부분들도 별도의 확인이 필요하다.