Kubernetes를 배워보자 7일차 - namespace와 pod의 자원 제한, ResourceQuota, LimitRange

1

kubernetes

목록 보기
7/13
post-custom-banner

kubernetes에서 namespace 관리하기

이번에는 namespace에 대해서 알아보자. namespace는 application 또는 environment에 따라 우리의 cluster resource들을 그룹화하여 잘 관리해주도록 도와준다.

kubernetes cluster에 application이 많아지면 많아질 수록 조직화의 필요성이 커진다. label과 annotation을 사용해서 이를 해결할 수 있지만, namespace를 사용하여 cluster내에 virtual한 cluster를 만들 수 있다.

즉, namespace를 사용함으로서 kubernetes cluster를 logical하게 잘게 나누고 고립시킬 수 있다. namespace은 kubernetes object에 할당할 수 있는데, namespace를 할당받은 kubernetes cluster는 개별 namespace scope안에서 실행된다. 따라서 kubectl 명령어로 실행할 때 namespace scope를 적어주지 않으면 해당 kubernetes object를 다룰 수 없게 된다. 이는 특정 resource를 삭제하는 여파가 다른 namespace에 미치지 않도록 해주기도 한다.

또한, namespace는 resource limit과 quota를 pod에 정의해줄 수 있다.

사실 application입장에서는 namespace의 존재를 모른다. 즉, namespace는 cluster 관리자를 위한 object로 생각할 수 있다는 것이다. 따라서, namespace를 추가하고 삭제한다고 해서 application의 동작에 영향을 미치지 않는다.

namespace가 관리자에게 도와주는 부분들은 다음과 같다.

  1. resource 조직화를 용이하게 하기위해서 cluster를 파티셔닝한다.
  2. resource 이름을 scope로 감싼다.
  3. 하드웨어를 고유하고 자원 소비를 제한한다.
  4. permission access

그러나, 오해하면 안되는 것은 namespace로 분리된 kubernetes object들이 서로 다른 스코프(영역)을 갖는다고 해도, 이들이 서로 통신을 못하는 것은 아니다. 즉, pod들이 서로 다른 namespace를 갖는다해도 이들 각각이 서로 다른 service와 연결되어 있으면 clusterIP를 통해서 언제든지 interact할 수 있다. 또한, fully qualified domain name(FQDN)을 통해서 전체 cluster에서 어디서든 접근할 수 있다. 따라서, A namespace에서 동작 중인 pod가 B namespace에서 동작 중인 pod와 통신하려고 할 때, B namespace를 가진 pod가 service로 노출되어있다면 FQDN을 통해서 통신할 수 있다. cross-namespace communication이 가능하다는 것이다.

default namespace의 이해

kubectl get ns를 통해서 모든 namespace를 가져올 수 있다.

kubectl get ns        
NAME                   STATUS   AGE
default                Active   325d
kube-public            Active   325d
kube-system            Active   325d

다음의 namespace는 기본적으로 설치되는 namespace이다.

default가 매우 중요한데, 지금까지 생성한 모든 kubernetes resource들은 모두 default 네임스페이스를 갖는다. 즉, 따로 네임스페이스를 등록하지 않으면 모두 default 네임스페이스인 것이다.

kube-system은 kubernetes cluster가 동작하기 위해 필요한 object들을 배포할 때 부여하는 네임스페이스이다. 가령, kube-scheduler와 같이 kubernetes cluster가 동작하기 위해 필요한 object는 kube-system이다. 따라서, 건드리지 말도록 하자.

kube-public은 기본적으로 생성되지만, 현재는 따로 부여된 곳이 없다. public object가 접근 가능할 때 부여되는 네임스페이스인데, 잘 쓰이지 않으니 그대로 두도록 하자.

Namespace 리스트

네임스페이스는 pod와 같이 하나의 kubernetes object로 namespace라는 Kind가 있는 것이다. 따라서, 이전에 배웠던 kubectl 명령어가 거의 모두 적용된다.

네임스페이스 리스트를 불러내는 방법은 다음과 같다.

kubectl get ns   
NAME                   STATUS   AGE
default                Active   325d
kube-public            Active   325d
kube-system            Active   325d

특정 namespace만 가져올 수 있다.

ubectl get ns default
NAME      STATUS   AGE
default   Active   325d

또한, 자세한 정보를 보기위해서 describe도 사용할 수 있다.

STATUS는 두 가지 종류로 되어있다.

  1. Active: 해당 네임스페이스가 active면 새로운 object를 해당 네임스페이스에 둘 수 있다.
  2. Terminating: 네임 스페이스가 삭제되는 중이며, 관련된 모든 object들도 삭제된다. 삭제중이기 때문에 해당 네임스페이스에 어떠한 object도 둘 수 없다.

imperative 문법으로 Namespace 만들기

imperative, declarative 문법을 통해서 namespace를 만들 수 있다. imperative문법을 사용한다면 아주 간단하게 kubectl create ns <ns-name>을 사용하면 된다.

가령, custom-ns라는 네임스페이스를 만드는 방법은 다음과 같다.

kubectl create ns custom-ns
namespace/custom-ns created

잘 만들어졌는 지 확인해보도록 하자.

kubectl get ns custom-ns
NAME        STATUS   AGE
custom-ns   Active   22s

Active상태로 네임스페이스가 잘 배포되었다.

참고로, 네임스페이스를 만들 때 kube-라는 접두사를 쓰지 않도록 하자. 해당 용어는 kubernetes상의 object와 시스템 네임스페이스를 위한 접두사이다.

declarative 문법으로 Namespace 만들기

yaml파일을 통해서도 만들 수 있다. KindNamespace이고, pod를 만들 때와 동일하다.

  • custom-ns-2.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: custom-ns-2

잘 만들어졌는 지 확인해보도록 하자.

kubectl get ns custom-ns-2        
NAME          STATUS   AGE
custom-ns-2   Active   6s

Active상태로 잘 만들어졌다.

다음으로 만들어낸 두 네임스페이스를 삭제해보도록 하자.

namespace 삭제하기

kubectl delete ns <ns-name>을 사용하여 삭제할 수 있다.

kubectl delete ns custom-ns 
namespace "custom-ns" deleted

또한, yaml파일을 통해서 삭제할 수 있다.

kubectl delete -f custom-ns-2.yaml 
namespace "custom-ns-2" deleted

namespace를 삭제하게 되면 Active상태에서 Terminating상태로 변경된다. 이 상태로 들어서면 해당 namespace로 object들을 할당하지 못한다.

그러나, namespace를 삭제하는 일은 가장 마지막에 cluster를 내릴 때를 제외하고는 추천하지 않는다. 네임스페이스를 삭제하면 관련된 모든 resource들이 삭제되기 때문이다. 즉, 다시는 해당 resource를 사용하지 않겠다는 보장이 있지 않는 한 쓰지말아야 한다는 것이다.

다음으로, 네임스페이스에 kubernetes object를 할당해보도록 하자.

-n 옵션으로 resource에 namespace 할당하기

네임스페이스에 resource를 할당하는 방법은 매우 쉽다. nginx pod에 custom-ns라는 네임스페이스를 할당해주도록 하자.

먼저 custom-ns라는 네임스페이스를 만들어주도록 하자.

kubectl create ns custom-ns
namespace/custom-ns created

다음으로 -n옵션으로 pod를 만들 때 네임스페이스를 할당해주도록 하자.

ubectl run nginx --image nginx:latest -n custom-ns
pod/nginx created

-n옵션은 --namespace옵션의 단축버전으로 네임스페이스 이름을 적으면 해당 resource에 할당된다.

다음으로, pod가 아니라 configmapcustom-ns 네임스페이스를 할당해 만들어보도록 하자.

kubectl create configmap configmap-custom-ns --from-literal=Lorem=Ipsum -n custom-ns
configmap/configmap-custom-ns created

위는 모두 imperative문법이지만, declarative문법으로도 namespace를 할당해줄 수 있다.

  • pod-in-namespace.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx2
  namespace: custom-ns
spec:
  containers:
  - name: nginx
    image: nginx:latest

metadataname과 함께 namespace를 두면 된다. 위의 pod를 만들어보도록 하자.

kubectl create -f pod-in-namespace.yaml 
pod/nginx2 created

성공적으로 배포된 것을 볼 수 있다.

이제 네임스페이스를 할당한 resource에 대해서는 kubectl로 명령어를 사용하든 뭐든 간에 -n옵션으로 네임스페이스를 붙여서 스코프를 할당해주어야 한다. 왜냐하면 기본적으로 네임스페이스가 default로 맞춰져 있기 때문에 -n으로 네임스페이스를 붙이지 않으면 default 네임스페이스에 있는 object들만 제어되기 때문이다.

kubect get pods로 모든 파드들을 불러와보자. 우리가 만든 파드들이 안나올 것이다. 왜냐하면 kubectl명령어의 스코프가 default 네임스페이스로 한정되었기 때문이다. 따라서, -n옵션으로 네임스페이스를 주어 스코프를 알려주어야 object들을 제어할 수 있따.

가령, custom-ns라는 네임스페이스를 가진 pod를 불러오려면 다음과 같이 해야한다.

ubectl get pods -n custom-ns 
NAME     READY   STATUS    RESTARTS   AGE
nginx    1/1     Running   0          11m
nginx2   1/1     Running   0          4m3s

pod뿐만 아니라 object들이면 모두 해당이다. configmapkubectl get cm만으로 호출시에 우리가 만들 configmap이 안나올 것이다. 이는 default 네임스페이스의 스코프이기 때문이다.

따라서, -n옵션으로 네임스페이스를 붙여주도록 하자.

kubectl get cm -n custom-ns 
NAME                  DATA   AGE
configmap-custom-ns   1      10m

kubectl 커맨드 이외에도 네임스페이스 스코프 한정은 매우 많이 사용되고 중요하므로 꼭꼭 챙기도록 하자.

만약, 네임스페이스와 상관엾이 해당 object의 모든 인스턴스를 보고 싶다면 -A옵션을 사용하면 된다. 가령, 네임스페이스와 상관없이 모든 pod를 보고싶다면 다음과 같이하면 된다.

kubectl get po -A

pod에 할당된 namespace도 같이 나오기 때문에 이를 참고하여 해당 object에 어떤 네임스페이스가 할당되었는 지 볼 수 있다.

또는 네임스페이스와 상관없이 모든 cluster내의 모든 object들의 인스턴스를 보고 싶다면 kubectl get all -A을 사용하면 된다.

kubectl get all -A

그렇다고 모든 리소스가 보이는 것은 아니긴하다. 가령 ingress와 같은 것들은 안나온다. 어디까지나 기본적으로 kubernetes에서 제공하는 object들을 보여주는 것이다.

만약, 특정 네임스페이스에 해당하는 모든 object들의 인스턴스를 보고싶다면 -A옵션 대신에 -n옵션을 추가하면 된다.

kubectl get all -n custom-ns

왠만한 명령어면 namespace를 한정하는 -n옵션이 있는 것을 알 수 있다. 이를 잘 활용하길 바란다.

네임스페이스에 한정된 리소스 이름

namespace는 아주 재미난 특징을 갖는데, 이는 scope를 제공하여 resource의 이름을 한정짓게 할 수 있다는 것이다.

kubernetes cluster상에서는 동일한 이름을 가진 object가 있을 수 없다. 가령, pod의 이름이 nginx라면, 또 nginx이름을 가진 pod를 만들 수 없다는 것이다. 이는 이름을 식별자로 삼는 kubernetes cluster의 정책 때문이다.

그런데, 만약 두 pod의 이름은 같지만 서로 다른 네임스페이스를 갖고 있다면 어떻게 될까?? 네임스페이스는 object에게 격리된 상태를 제공한다. 즉, cluster안의 virtual한 cluster인 것이다. 따라서, 네임스페이스가 다르면 이름이 같은 object라도 상관없이 배포된다. 해당 object들은 이름과 namespace로 식별되기 때문이다. 가령 default 네임스페이스를 가진 nginx를 만들어보도록 하자.

kubectl run nginx --image nginx:latest

네임스페이스를 제공하지 않았기 때문에 default이다.

우리는 이전에 custom-ns라는 네임스페이스를 가진 nginx pod를 만들었었다.

kubectl get po nginx -n custom-ns
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          24m

kubectl get po nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          11s

nginx 동일한 이름을 가진 pod는 서로 다른 네임스페이스를 갖고 있기 때문에 배포가 가능한 것이다.

이처럼 네임스페이스를 달리하여 object들을 격리할 수 있고 다른 cluster에 배포한 것처럼 사용할 수 있다. 또한, yaml파일에 있는 namespacekubectl create 명령어로 override할 수 있는데, 이는 매우매우 강력한 무기이다. 만약 test환경이라면 test 네임스페이스를 할당해주면 되고, 배포버전이면 production 네임스페이스를 줄 수 있기 때문이다.

모든 object들이 namespace를 갖고 있는 것은 아니다.

모든 kubernetes의 object들이 namespace에 속한 것은 아니다. 가장 대표적인 것이 Node이다. Node는 cluster level로 어떠한 네임스페이스에도 속하지 않는다.

다음의 명령어로 namespace에 속하지 않는 resource들을 불러올 수 있다.

kubectl api-resources --namespaced=false

true로 바꾸면 namespace에 영향을 받은 resource들이 나온다.

Service DNS와 Namespace

Service는 DNS record로 할당되어 cluster내의 pod들이 해당 서비스에 DNS로 접근이 가능하다.

그러나, Service의 DNS에 네임스페이스를 따로주지 않으면 pod가 DNS을 통해 Service에 접근할 때 오직 Service가 해당 pod와 같은 namespace에 있을 때만 가능하다. 때무에 DNS에 namespace를 추가하여 특정 네임스페이스의 Service를 지정할 수 있어, pod와 Service의 네임스페이스가 달라도 접근이 가능하다.

<service_name>.<namespace_name>.svc.cluster.local

해당 도메인 이름을 쿼리함으로서 kubernetes cluster 내의 어떠한 namespace이든 간에 Service에 접근할 수 있다. 즉, 같은 네임스페이스에 있지 않아도 접근할 수 있다는 것이다.

namespace level에서 ResourceQuota와 Limit 설정하기

namespace는 resource들을 정리하는 것에만 사용되는 것이 아니라, pod들이 접근할 수 있는 자원들의 컴퓨팅 자원들을 제한하는 역할도 한다.

ResourceQuotaLimits를 namespace와 함께쓰면서 pod에서 접근할 수 있는 resource 컴퓨팅 자원에 대해 제한을 걸 수 있다.

kubernetes pod는 application들과 마찬가지로 특정한 양의 컴퓨팅 자원을 요구하며, 이 자원들은 다음과 같이 정리할 수 있다.

  • CPU
  • Memory

모든 worker node들은 CPU와 memory를 제공한다. 즉, CPU와 Memory를 추가로 kubernetes cluster에 추가하는 방법은 worker node를 추가하는 것이다.

kubernetes cluster에 pod가 시작되면 control plane의 kube-scheduler가 worker node를 선정하고 해당 노드에 pod를 할당한다. 이 다음 worker node의 kubelet이 pod에 정의된 container를 시작시킨다.

worker node를 찾아 pod에 할당하는 과정을 kubernetes에서 pod scheduling이라고 한다.

일단, pod가 worker node에 할당되면 해당 worker node의 모든 자원들에 접근할 수 있다. 따라서, 원래 application이 필요한 그 이상의 자원을 요구할 수도 있는 것이다.

하나의 worker node에 여러 개의 pod가 올라가는 multiple pod(application) 상황에서 이는 굉장히 큰 문제를 야기한다. 가령, 10개의 pod가 배포되어야 할 worker node에서 하나의 pod가 노드의 모든 자원들을 요구한다면 9개의 pod들은 정상적으로 동작하지 못할 것이다.

따라서, 우리는 다음의 두 가지를 고민해야한다.
1. 각 pod가 동작해야할 최소한의 자원에 대해서 요구할 수 있어야 한다.
2. cluster는 pod의 자원 독점을 막아야하며 제한을 두어야 한다.

이러한 문제를 해결할 수 있는 방법으로 두 가지 옵션을 설정하면 된다. 하나는 pod가 자신이 필요한 자원의 양을 요구할 수 있도록 하는 resources가 있고, 하나는 limit으로 pod가 접근할 수 있는 자원의 한계를 의미한다.

pod에 resources 설정하여 최소한의 자원 확보하기

pod resource를 정의하는 yaml파일에 requestlimit 옵션을 설정할 수 있다.

request는 kubernetes pod가 cluster 내에서 적절하게 동작할 수 있는 컴퓨팅 자원의 최소한의 양을 의미한다. 그리고 이는 꼭 정의하여 production에 배포하는 것이 좋다.

가령, NGINX pod를 만드는데, 해당 pod가 적절하게 실행되기 위해서는 512M를 요구하고 CPU code의 25%를 요구한다면 다음과 같이 쓸 수 있다.

  • pod-in-namespace-with-request.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-with-request
  namespace: custom-ns
spec:
  containers:
  - name: nginx
    image: nginx:latest
    resources:
      requests:
        memory: "512Mi"
        cpu: "250m"

resourcesresources.requests가 있고 memorycpu를 정의해주면 된다. 또한, 이 resourcescontainers의 하위 레벨이기 때문에 컨테이너마다 자원의 양을 따로 설정해줄 수 있다는 것도 알 수 있다.

memory는 바이트로 표현되지만, CPU의 밀리코어(millicore-> 10^-3)로 표현된다. 따라서, CPU의 한 코어를 전부쓰고 싶다면 1000m으로 써주면 된다. 하나의 반 코어를 쓰고 싶다면 500m으로 써줘도 되고, 0.5도 된다. 위에서는 512Mb의 메모리를 요구하고, 한 코어의 25%인 250m를 강제적으로 사용하려고 할 것이다. 즉, nginx 컨테이너가 더 적은 자원을 쓴다해도 강제적으로 선점하려고 하는 것이다.

해당 yaml파일을 cluster에 배포하게되면 scheduler는 worker node에게 이 resource를 감당할 충분한 자원이 있는 지 확인한다. 만약 충분한 자원이 없다면 pod는 시작되지 못하고 정체되어 있는데, 다른 pod를 지워서 자원의 충분한 양을 만들거나 다른 worker node를 추가해주어야 시작될 것이다.

따라서, requests부분은 현명하게 작성해야하며 pod가 동작하기 위한 최소한의 자원을 적도록해야한다. 만약, 너무 높은 자원양을 요구하면 실행이 안될 수 있기 때문이다. 단, 실행만 된다면 pod는 곧 죽어도 requests만큼의 자원은 확보하게 된다.

pod의 과도한 자원 사용을 제한하는 방법

limits를 설정하게 되면 해당 pod는 절대 그 이상의 자원을 소모하려고 하지않는다. 이를 통해 한 pod가 너무 많은 자원을 독재하는 것을 막는 것이다.

단, limits에 대해서 조심해야할 것은 이건 해당 pod를 살려주기위한 자원확보가 아니라, 해당 pod가 너무 많은 자원을 소모하여 다른 pod에 영향을 미치지 않도록 하는 하나의 방어책이라는 것이다. 따라서 CPU나 Memory 한계에 부딫히면 pod에서 동작중인 container가 crash날 수 있다.

앞선 nginx pod에서 memory는 1G를 넘지않고, cpu는 1코어를 쓰지 않도록 설정해자.

  • pod-in-namespace-with-request-and-limit.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-with-request
  namespace: custom-ns
spec:
  containers:
  - name: nginx
    image: nginx:latest
    resources:
      requests:
        memory: "512Mi"
        cpu: "250m"
      limits:
        memory: "1Gi"
        cpu: "1000m"

resources.limitsmemorycpu를 설정해주면 된다. limitsrequests와 같은 레벨에 있다는 것에 유념하자.

ResourceQuota를 사용해야하는 이유

kubernetes cluster의 application을 담당하는 부분은 pod이기 때문에, 이제 pod의 자원을 resources로 제어만 한다면 더 이상 자원 때문에 문제될 것은 없다.

다만, 이는 언제나 pod에 자원을 설정해줄 때의 가정이고 자원 설정은 생각보다 까먹기도 쉽다. 누군가가 이를 설정하지 않으면 최악의 경우 cluster를 다운시키게되고 문제를 해결하기위해서 pod를 하나하나 찾아보겠지만 문제를 찾기 쉽지 않을 것이다.

kubernetes에서는 이러한 문제를 완화시켜주기 위해서 두가지 object들을 제공하는데, 하나는 ResourceQuota이고 하나는 LimitRange이다. 이 두 가지 object들은 매우 효율적인데 왜냐하면 이들이 자원의 constraints를 namespace level에서 설정할 수 있기 때문이다.

ResourceQuotaLimitRange는 kubernetes object로 pod와 같은 kind로 정의된다.

네임스페이스를 만들고 네임스페이스에 ResourceQuotaLimitRange를 설정해주도록 하자. 해당 네임스페이스에 시작되는 모든 pod들은 이 두 object들에 의해 제한을 받게된다.

가령 quota는 네임스페이스에서 동작중인 pod들이 사용하는 전체 메모리의 양을 4GB가 넘지 않도록 설정할 수 있다. 따라서, 언제나 ResourceQuotaLimitRange는 각 네임스페이스에 정의할 것을 추천한다.

일반적으로 ResourceQuota는 다음과 같은 상황에서 쓰인다.
1. namespace에서 CPU소모를 제한할 때
2. namespace에서 memory소모를 제한할 때
3. namespace에서 동작 중인 pod들의 절대적인 수를 제한할 때

이것말고도 다양한 케이스들이 있다.

ResourceQuota를 만드는 방법

ResourceQuota를 만들기 전에 먼저 네임스페이스를 만들어야 한다. 없는 namespace에서 할당될 수는 없기 때문이다.

custom-ns를 만들어보자.

kubectl create ns custom-ns
namespace/custom-ns created

ResourceQuota를 만들어서 custom-ns 네임스페이스의 모든 pod들이 사용할 자원의 양을 제한하는 limit을 만들고, 최소한의 자원을 보장하는 requests도 만들도록 하자.

  • resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-resourcequota
  namespace: custom-ns
spec:
  hard:
    requests.cpu: "1000m"
    requests.memory: "1Gi"
    limits.cpu: "2000m"
    limits.memory: "2Gi"

ResourceQuotarequestslimits를 두어 해당 namespace에 배포되는 pod에게 적용시킨다. 한가지 명심해야할 것은 ResourceQuota는 오직 한 네임스페이스에만 적용된다는 것이다.

해당 네임스페이스에 pod가 배포되면 다음의 룰을 따른다.
1. 모든 pod들을 합쳐 해당 네임스페이스에서 하나의 CPU core 이상으로는 자원을 request하지 못한다.
2. 모든 pod들을 합쳐 해당 네임스페이스에서 1GiB 메모리 이상을 request하지 못한다.
3. 모든 pod들을 합쳐 해당 네임스페이스에서 두 개이상의 CPU core를 사용할 수 없다.
4. 모든 pod들을 합쳐 해당 네임스페이스에서 2GiB 이상의 메모리를 사용할 수 없다.

추가적으로 cpu랑 memory자원 이외에 kubernetes object의 개수도 제한할 수 있다. 가령, 해당 네임스페이스에 ConfigMap은 10개 이상은 못갖고, service는 5개로 한정하고 싶다면 다음과 같이하면 된다.

  • resourcequota-with-object-count.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-resourcequota-with-object-count
spec:
  hard:
    requests.cpu: "1000m"
    requests.memory: "1Gi"
    limits.cpu: "2000m"
    limits.memory: "2Gi"
    configmaps: "10"
    services: "5"

spec.hard.configmapsspec.hard.services를 설정해주며 된다.

namespace를 따로 설정해주지 않았는데, create할 때 -n옵션으로 설정해주면 된다.

kubectl create -f ./resourcequota-with-object-count.yaml -n=
custom-ns 
resourcequota/my-resourcequota-with-object-count created

ResourceQuota 조회와 삭제

ResourceQuota도 kubernetes object이기 때문에 조회와 삭제가 가능하다.

kubectl get quota로 불러올 수 있는데, -n으로 네임스페이스를 지정하는 것을 잊지말자.

kubectl get quota -n custom-ns
NAME                                 AGE   REQUEST                                                                      LIMIT
my-resourcequota-with-object-count   1s    configmaps: 1/10, requests.cpu: 0/1, requests.memory: 0/1Gi, services: 0/5   limits.cpu: 0/2, limits.memory: 0/2Gi

위에서 만든 결과가 나왔다.

삭제하는 방법도 네임스페이스를 잊지말도록 하자.

kubectl delete -f ./resourcequota-with-object-count.yaml -n custom-ns
resourcequota "my-resourcequota-with-object-count" deleted

LimitRange

ResourceQuota처럼 namespace에서 동작하지만, ResourceQuota가 namespace 전체의 자원에 대한 cpu, memory, resource 개수 제한이라면 LimitRange는 개별 pod, container 단위로 cpu와 memory에 제한을 주거나 default값을 설정하도록 할 수 있다. 이는 ResourceQuota가 있더라도 이는 언제나 네임스페이스 범위에서의 cpu, memory제한이기 때문에 하나의 pod가 모든 자원을 소모할 수도 있다. 때문에 LimitRange를 만들면 네임스페이스에서 하나의 pod 또는 container가 너무 많은 자원을 소모하지 못하게 할 수 있다. 또한, 특정 pod가 너무 적은 자원만을 갖지못하게도 할 수 있다. 즉, 너무 적은 자원을 또는 너무 많은 자원을 소모하지 못하게 막는 것이다.

다음은 한 pod의 container가 가지는 limit을 제한한 LimitRange이다.

  • limitrange.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: my-limitrange
  namespace: custom-ns
spec:
  limits:
  - default:
      memory: "256Mi"
      cpu: "500m"
    defaultRequest:
      memory: "128Mi"
      cpu: "250m"
    max:
      memory: "1Gi"
      cpu: "1000Mi"
    min:
      memory: "128Mi"
      cpu: "250m"
    type: Container

LimitRangelimits에 5개의 키워드를 나란히 적는 것이 끝이다.

  1. type: pod또는 container에 적용할 지 결정한다.
  2. default: type(현재는 container)에 memory, cpu limit을 설정해준다. 단, 이는 pod level의 limit을 설정하지 않았을 때만 동작한다.
  3. defaultRequest: default와 비슷하지만 defaultlimits이라면 defaultRequestrequests를 안 적었을 때 동작한다.
  4. max: 만약 limits가 적혔다면 max를 넘지 못한다. 즉, max보다 더 큰 limits가 적혀있다면 max보다 작아야한다. 따라서, defaultlimits를 설정하므로 max보다 커서는 안된다.
  5. min: 만약 requests가 적혔다면 min보다 작을 순 없다. 즉, 최소한의 자원으로 defaultRequestmin보다 작아서는 안된다.

만약, defaultdefaultRequest를 까먹었다면 maxmin이 대신 그 역할을 해준다.

LimitRange가 네임스페이스에 있는 한 개별 pod의 자원은 너무 적거나, 너무 많이 잡아먹는 일이 없어지므로 반드시 설정해주는 것이 좋다.

실행 방법은 다른 object와 동일하다.

kubectl create -f ./limitrange.yaml
limitrange/my-limitrange created

LimitRange를 조회와 삭제

LimitRange도 object이기 때문에 조회와 삭제가 가능하다. 재밌는 것은 축약어로 limits이라고 한다.

namespace를 까먹지 말도록 하자.

ubectl get limits -n custom-ns
NAME            CREATED AT
my-limitrange   2023-06-19T14:44:13Z

삭제할 때도 namespace를 까먹지 말자

ubectl delete -f ./limitrange.yaml 
limitrange "my-limitrange" deleted
post-custom-banner

0개의 댓글