계층적 리소스 할당량 사용

Kubernetes 리소스 할당량은 관리자가 여러 사용자 간에 리소스를 공정하게 공유할 수 있게 해주는 도구입니다. ResourceQuota 객체로 정의된 리소스 할당량은 단일 네임스페이스에서 집계 리소스 소비를 제한하는 제약조건을 제공합니다.

계층 컨트롤러는 계층적 네임스페이스를 지원하도록 네임스페이스별 리소스 할당량 개념을 확장합니다. HierarchicalResourceQuota 객체는 하위 트리의 모든 네임스페이스에서 집계 리소스 소비를 제한하므로 관리자가 여러 관련 네임스페이스에서 리소스 소비를 제한할 수 있습니다.

계층적 리소스 할당량이 사용 설정되면 계층 컨트롤러는 허용 웹훅 유효성 검증 두 개를 설치합니다. 이 중 하나는 실제로 리소스 소비 한도를 적용하고 다른 하나는 계층적 리소스 할당량 유효성을 자체적으로 검증합니다.

계층적 리소스 할당량 사용 설정

계층 컨트롤러에서 계층적 리소스 할당량을 제공합니다. 계층적 리소스 할당량을 사용 설정하려면 다음 단계를 수행합니다.

  1. 구성 동기화 1.6.2 이상을 사용하여 계층 컨트롤러를 설치합니다.

  2. ConfigManagement Operator 구성 파일의 spec.hierarchyController 객체에서 enableHierarchicalResourceQuota 값을 true로 설정합니다.

    # config-management.yaml
    
    apiVersion: configmanagement.gke.io/v1
    kind: ConfigManagement
    metadata:
      name: config-management
    spec:
      hierarchyController:
        enabled: true
        # Set to true to enable hierarchical resource quotas:
        enableHierarchicalResourceQuota: true
      # ...other fields...
    
  3. 구성을 적용합니다.

    kubectl apply -f config-management.yaml
    

    약 1분 후에 클러스터에서 계층 컨트롤러와 계층적 리소스 할당량을 사용할 수 있습니다.

계층적 리소스 할당량이 사용 설정되었는지 확인하려면 다음 단계를 수행합니다.

  1. 다음과 같이 모든 네임스페이스에 HierarchicalResourceQuota 객체를 만듭니다.

    cat > example-hrq.yaml <<EOF
    apiVersion: hierarchycontroller.configmanagement.gke.io/v1alpha1
    kind: HierarchicalResourceQuota
    metadata:
      name: example-hrq
    spec:
      hard:
        configmaps: "1"
    EOF
    
    kubectl apply -f example-hrq.yaml -n default
    
  2. 동일한 spec.hardconfigmap이 1개 있는 네임스페이스에 gke-hc-hrq라는 새 ResourceQuota 객체가 생성되었는지 확인합니다. 예를 들면 다음과 같습니다.

    kubectl describe resourcequota gke-hc-hrq -n default
    

    출력:

    Name:           gke-hc-hrq
    Namespace:      default
    Resource        Used    Hard
    --------        ----    ----
    configmaps      0       1
    
  3. 삭제

    kubectl delete hrq -n default example-hrq
    

    자동으로 생성된 객체가 삭제되었는지 확인합니다.

    kubectl get resourcequota gke-hc-hrq -n default
    

    출력:

    Error from server (NotFound): resourcequotas "gke-hc-hrq" not found
    

계층적 리소스 할당량 사용

할당량 설정

HierarchicalResourceQuota 설정은 일반 ResourceQuota 설정과 동일하지만 apiVersionkind가 다릅니다. 따라서 ResourceQuota에서와 같이 spec.hard 필드에서 리소스에 한도를 설정할 수 있습니다.

service-a라는 서비스를 소유하고 있고 team-b라는 하위 팀이 있는 team-a라는 팀이 있다고 가정해 보겠습니다. 모든 팀은 다음과 같이 계층적 네임스페이스로 표현됩니다.

kubectl hns tree team-a

출력:

team-a
├── service-a
└── team-b

team-aconfigmaps 수를 제한하고 하위 요소 수를 제한하지 않으려면 다음과 같이 일반 ResourceQuota를 만들면 됩니다.

cat > team-a-rq.yaml <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-rq
  namespace: team-a
spec:
  hard:
    configmaps: "1"
EOF

kubectl apply -f team-a-rq.yaml

반대로 team-a의 총 configmaps 수와 결합된 하위 요소를 제한하려면 이전 예시의 apiVersionkind를 바꿉니다.

cat > team-a-hrq.yaml <<EOF
# Modify the following two lines:
apiVersion: hierarchycontroller.configmanagement.gke.io/v1alpha1
kind: HierarchicalResourceQuota
# Everything below this line remains the same
metadata:
  name: team-a-hrq
  namespace: team-a
spec:
  hard:
    configmaps: "1"

EOF

kubectl apply -f team-a-hrq.yaml

이 세 가지 네임스페이스 중 하나에서 처음으로 configmap을 만들려고 하면 성공합니다. 예를 들어 하위 네임스페이스 중 하나에서 configmap을 만들 수 있습니다.

kubectl create configmap config-1 --from-literal key=value -n team-b

출력:

confimap/config-1 created

하지만 형제 네임스페이스나 상위 네임스페이스를 비롯한 세 가지 네임스페이스 중 하나에서 추가로 새 configmap을 만들려고 하면 실패합니다.

kubectl create configmap config-2 --from-literal key=value -n service-a
kubectl create configmap config-2 --from-literal key=value -n team-a

모두에 다음과 같이 출력됩니다.

Error from server (Forbidden): admission webhook "resourcesquotasstatus.hierarchycontroller.configmanagement.gke.io" denied the request: exceeded hierarchical quota in namespace "team-a": "team-a-hrq", requested: configmaps=1, used: configmaps=1, limited: configmaps=1

할당량 검사

HierarchicalResourceQuota의 현재 한도와 사용량을 보려면 kubectl describe 명령어를 사용하여 일반 리소스 할당량을 봅니다.

kubectl describe hrq team-a-hrq -n team-a

출력:

# ...other fields...
Spec:
  Hard:
    Configmaps:  1
Status:
  Hard:
    Configmaps:  1
  Used:
    Configmaps:  1

네임스페이스 계층 구조 업데이트

네임스페이스에는 항상 상위의 모든 HierarchicalResourceQuota가 적용됩니다. 네임스페이스 계층 구조를 수정하면 할당량 사용이 다시 계산됩니다.

계층적 할당량을 사용하여 하위 트리에서 네임스페이스 삭제

네임스페이스가 상위의 계층적 할당량이 있는 하위 트리 외부로 이동하면 더 이상 이러한 할당량이 적용되지 않으며 리소스는 할당량 사용에서 삭제됩니다.

예를 들어 team-b가 이전 하위 트리에서 삭제되면 team-bconfigmap 소비가 제한되지 않습니다. 계층적 할당량 사용량이 0으로 재설정됩니다. 즉, 이제 team-aservice-a에서 모든 configmap를 추가로 소비할 수 있습니다.

계층적 할당량을 사용하여 네임스페이스를 하위 트리에 추가

네임스페이스가 계층적 할당량이 있는 하위 트리에 추가되면 계층적 할당량이 적용되며 리소스 사용량이 할당량 사용에 추가됩니다.

예를 들어 다른 네임스페이스가 이전 하위 트리에 추가되면 새로 추가된 네임스페이스에서 configmap을 더 이상 소비하지 않습니다. 마찬가지로, 새로 추가된 네임스페이스의 기존 configmap 사용량이 계층적 할당량 사용에 추가됩니다.

계층적 할당량은 새 네임스페이스의 사용량이 계층적 할당량 한도를 초과하더라도 새 네임스페이스가 하위 네임스페이스로 이동하지 않도록 합니다. 하지만 한도를 초과하면 사용량이 한도 이하로 내려지거나 한도가 상향될 때까지 추가 리소스를 사용할 수 없습니다. 이는 네임스페이스의 기존 사용량보다 낮은 한도가 적용되는 경우의 Kubernetes ResourceQuota 동작과 유사합니다.

일반 규칙

계층적 리소스 할당량은 특수한 경우에 Kubernetes 사례의 리소스 할당량과 비슷하게 동작합니다. 예를 들면 다음과 같습니다.

  • 동일한 네임스페이스에 계층적 리소스 할당량 여러 개가 적용되면 가장 제한적인 리소스 한도가 적용됩니다.
  • 이미 사용된 리소스 양보다 적은 한도를 만들면 기존 리소스는 삭제되지 않지만 사용량이 한도 이하로 내려지거나 한도가 상향될 때까지 추가 리소스 소비가 금지됩니다.

문제해결

리소스 소비 시 InternalError

예를 들어 configmap를 만들 때 리소스를 소비하면 요청이 10초 동안 응답하지 않으며 다음 오류 메시지가 표시될 수 있습니다.

Error from server (InternalError): Internal error occurred: resource quota evaluates timeout

gke-hc-controller-manager pod가 잘못된 상태가 아니면 이 오류 메시지는 표시되지 않습니다.

이 문제를 해결하려면 권한 있는 관리자가 hnc-system 네임스페이스의 gke-hc-controller-manager- 프리픽스를 직접 사용하여 pod를 삭제하면 됩니다. pod가 자동으로 다시 시작됩니다. pod가 준비되기 전에 다음 사항에 유의하세요.

이렇게 해도 문제가 해결되지 않으면 Google에서 분석할 수 있도록 보고합니다. 다음을 사용하여 얻을 수 있는 로그와 함께 보고하는 것이 좋습니다.

kubectl logs -n hnc-system deployment/gke-hc-controller-manager -c manager

다음 단계