First Korean l10n Work For Release 1.18

* Update to Outdated files in the dev-1.18-ko.1 branch (#19886)
* Translate reference/glossary/service-catalog.md in Korean (#20055)
* Translate storage/dynamic-provisioning.md in Korean (#19952)
* Translate extend-kubernetes/extend-cluster.md in Korean (#20031)
* Translate storage/persistent-volumes.md in Korean (#19906)
* Translate partners/_index.html in Korean (#19967)
* Translate extend-kubernetes/operator.md in Korean (#20037)
* Translate assign-pods-nodes to Korean (#20035)
* Translate scheduling/kube-scheduler.md in Korean (#19879)
* Translate concepts/containers/overview in Korean (#19885)
* Translate policy/pod-security-policy.md in Korean (#19922)
* Translate policy/limit-range.md in Korean (#19912)
* Translate policy/resource-quotas.md in Korean (#19931)
* Translate extend-kubernetes/api-extension/custom-resources.md in Korean (#20093)
* Translate reference/glossary/managed-service.md in Korean (#20150)

Co-authored-by: Jerry Park <jaehwa@gmail.com>
Co-authored-by: heechang lee <bluefriday86@gmail.com>
Co-authored-by: Yuk, Yongsu <ysyukr@gmail.com>
Co-authored-by: Seokho Son <shsongist@gmail.com>
Co-authored-by: coolguyhong <podolsmith@naver.com>
Co-authored-by: santachopa <santachopa@naver.com>
Co-authored-by: Jesang Myung <jesang.myung@gmail.com>
Co-authored-by: June Yi <june.yi@samsung.com>
This commit is contained in:
Yuk, Yongsu
2020-03-31 09:24:40 +09:00
committed by June Yi
parent efbf9a9e6e
commit 264869ae3a
65 changed files with 4046 additions and 615 deletions
@@ -0,0 +1,4 @@
---
title: "정책"
weight: 90
---
@@ -0,0 +1,388 @@
---
title: 리밋 레인지(Limit Range)
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
기본적으로 컨테이너는 쿠버네티스 클러스터에서 무제한 [컴퓨팅 리소스](/docs/user-guide/compute-resources)로 실행된다.
리소스 쿼터을 사용하면 클러스터 관리자는 네임스페이스별로 리소스 사용과 생성을 제한할 수 있다.
네임스페이스 내에서 파드나 컨테이너는 네임스페이스의 리소스 쿼터에 정의된 만큼의 CPU와 메모리를 사용할 수 있다. 하나의 파드 또는 컨테이너가 사용 가능한 모든 리소스를 독점할 수 있다는 우려가 있다. 리밋레인지는 네임스페이스에서 리소스 할당(파드 또는 컨테이너)을 제한하는 정책이다.
{{% /capture %}}
{{% capture body %}}
_리밋레인지_ 는 다음과 같은 제약 조건을 제공한다.
- 네임스페이스에서 파드 또는 컨테이너별 최소 및 최대 컴퓨팅 리소스 사용량을 지정한다.
- 네임스페이스에서 스토리지클래스별 최소 및 최대 스토리지 요청을 지정한다.
- 네임스페이스에서 리소스에 대한 요청과 제한 사이의 비율을 지정한다.
- 네임스페이스에서 컴퓨팅 리소스에 대한 기본 요청/제한을 설정하고 런타임에 있는 컨테이너에 자동으로 설정한다.
## 리밋레인지 활성화
많은 쿠버네티스 배포판에 리밋레인지 지원이 기본적으로 활성화되어 있다. apiserver `--enable-admission-plugins=` 플래그의 인수 중 하나로 `LimitRanger` 어드미션 컨트롤러가 있는 경우 활성화된다.
해당 네임스페이스에 리밋레인지 오브젝트가 있는 경우 특정 네임스페이스에 리밋레인지가 지정된다.
리밋레인지 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야한다.
### 범위 제한의 개요
- 관리자는 하나의 네임스페이스에 하나의 `LimitRange`를 만든다.
- 사용자는 네임스페이스에서 파드, 컨테이너 및 퍼시스턴트볼륨클레임과 같은 리소스를 생성한다.
- `LimitRanger` 어드미션 컨트롤러는 컴퓨팅 리소스 요청 사항을 설정하지 않은 모든 파드와 컨테이너에 대한 기본값과 제한을 지정하고 네임스페이스의 리밋레인지에 정의된 리소스의 최소, 최대 및 비율을 초과하지 않도록 사용량을 추적한다.
- 리밋레인지 제약 조건을 위반하는 리소스(파드, 컨테이너, 퍼시스턴트볼륨클레임)를 생성하거나 업데이트하는 경우 HTTP 상태 코드 `403 FORBIDDEN` 및 위반된 제약 조건을 설명하는 메시지와 함께 API 서버에 대한 요청이 실패한다.
- `cpu`, `memory`와 같은 컴퓨팅 리소스의 네임스페이스에서 리밋레인지가 활성화된 경우 사용자는 해당 값에 대한 요청 또는 제한을 지정해야 한다. 그렇지 않으면 시스템에서 파드 생성이 거부될 수 있다.
- 리밋레인지 유효성 검사는 파드 실행 단계가 아닌 파드 어드미션 단계에서만 발생한다.
범위 제한을 사용하여 생성할 수 있는 정책의 예는 다음과 같다.
- 용량이 8GiB RAM과 16 코어인 2 노드 클러스터에서 네임스페이스의 파드를 제한하여 CPU의 최대 제한이 500m인 CPU 100m를 요청하고 메모리의 최대 제한이 600M인 메모리 200Mi를 요청하라.
- 스펙에 CPU 및 메모리 요청없이 시작된 컨테이너에 대해 기본 CPU 제한 및 요청을 150m로, 메모리 기본 요청을 300Mi로 정의하라.
네임스페이스의 총 제한이 파드/컨테이너의 제한 합보다 작은 경우 리소스에 대한 경합이 있을 수 있다.
이 경우 컨테이너 또는 파드가 생성되지 않는다.
경합이나 리밋레인지 변경은 이미 생성된 리소스에 영향을 미치지 않는다.
## 컨테이너 컴퓨팅 리소스 제한
다음 절에서는 컨테이너 레벨에서 작동하는 리밋레인지 생성에 대해 설명한다.
4개의 컨테이너가 있는 파드가 먼저 생성된다. 파드 내의 각 컨테이너에는 특정 `spec.resource` 구성이 있다.
파드 내의 각 컨테이너는 `LimitRanger` 어드미션 컨트롤러에 의해 다르게 처리된다.
다음 kubectl 명령을 사용하여 네임스페이스 `limitrange-demo`를 생성한다.
```shell
kubectl create namespace limitrange-demo
```
kubectl 명령에서 네임스페이스 대상인 `limitrange-demo`를 빠트리지 않으려면 다음 명령으로 컨텍스트를 변경한다.
```shell
kubectl config set-context --current --namespace=limitrange-demo
```
다음은 리밋레인지 오브젝트의 구성 파일이다.
{{< codenew file="admin/resource/limit-mem-cpu-container.yaml" >}}
이 오브젝트는 컨테이너에 적용할 최소 및 최대 CPU/메모리 제한, 기본 CPU/메모리 요청과 CPU/메모리 리소스에 대한 기본 제한을 정의한다.
다음 kubectl 명령을 사용하여 `limit-mem-cpu-per-container` 리밋레인지를 생성한다.
```shell
kubectl create -f https://k8s.io/examples/admin/resource/limit-mem-cpu-container.yaml
```
```shell
kubectl describe limitrange/limit-mem-cpu-per-container
```
```shell
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 100m 800m 110m 700m -
Container memory 99Mi 1Gi 111Mi 900Mi -
```
다음은 4개의 컨테이너가 포함된 파드의 구성 파일로 리밋레인지 기능을 보여준다.
{{< codenew file="admin/resource/limit-range-pod-1.yaml" >}}
`busybox1` 파드를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-1.yaml
```
### 유효한 CPU/메모리 요청과 제한이 있는 컨테이너 스펙
`busybox-cnt01`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[0].resources"
```
```json
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
```
- `busybox` 파드 내의 `busybox-cnt01` 컨테이너는 `requests.cpu=100m``requests.memory=100Mi`로 정의됐다.
- `100m <= 500m <= 800m`, 컨테이너 CPU 제한(500m)은 승인된 CPU 리밋레인지 내에 있다.
- `99Mi <= 200Mi <= 1Gi`, 컨테이너 메모리 제한(200Mi)은 승인된 메모리 리밋레인지 내에 있다.
- CPU/메모리에 대한 요청/제한 비율 검증이 없으므로 컨테이너가 유효하며 생성되었다.
### 유효한 CPU/메모리 요청은 있지만 제한이 없는 컨테이너 스펙
`busybox-cnt02`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[1].resources"
```
```json
{
"limits": {
"cpu": "700m",
"memory": "900Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
```
- `busybox1` 파드 내의 `busybox-cnt02` 컨테이너는 `requests.cpu=100m``requests.memory=100Mi`를 정의했지만 CPU와 메모리에 대한 제한은 없다.
- 컨테이너에 제한 섹션이 없다. `limit-mem-cpu-per-container` 리밋레인지 오브젝트에 정의된 기본 제한은 `limits.cpu=700mi``limits.memory=900Mi`로 이 컨테이너에 설정된다.
- `100m <= 700m <= 800m`, 컨테이너 CPU 제한(700m)이 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 900Mi <= 1Gi`, 컨테이너 메모리 제한(900Mi)이 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
### 유효한 CPU/메모리 제한은 있지만 요청은 없는 컨테이너 스펙
`busybox-cnt03`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[2].resources"
```
```json
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "500m",
"memory": "200Mi"
}
}
```
- `busybox1` 파드 내의 `busybox-cnt03` 컨테이너는 `limits.cpu=500m``limits.memory=200Mi`를 정의했지만 CPU와 메모리에 대한 요청은 없다.
- 컨테이너에 요청 섹션이 정의되지 않았다. `limit-mem-cpu-per-container` 리밋레인지에 정의된 기본 요청은 제한 섹션을 채우는 데 사용되지 않지만 컨테이너에 의해 정의된 제한은 `limits.cpu=500m``limits.memory=200Mi`로 설정된다.
- `100m <= 500m <= 800m`, 컨테이너 CPU 제한(500m)은 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 200Mi <= 1Gi`, 컨테이너 메모리 제한(200Mi)은 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
### CPU/메모리 요청/제한이 없는 컨테이너 스펙
`busybox-cnt04`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[3].resources"
```
```json
{
"limits": {
"cpu": "700m",
"memory": "900Mi"
},
"requests": {
"cpu": "110m",
"memory": "111Mi"
}
}
```
- `busybox1``busybox-cnt04` 컨테이너는 제한이나 요청을 정의하지 않았다.
- 컨테이너는 제한 섹션을 정의하지 않으며 `limit-mem-cpu-per-container` 리밋레인지에 정의된 기본 제한은 `limit.cpu=700m``limits.memory=900Mi`로 설정된다.
- 컨테이너는 요청 섹션을 정의하지 않으며 `limit-mem-cpu-per-container` 리밋레인지에 정의된 defaultRequest는 `requests.cpu=110m``requests.memory=111Mi`로 설정된다.
- `100m <= 700m <= 800m`, 컨테이너 CPU 제한(700m)은 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 900Mi <= 1Gi`, 컨테이너 메모리 제한(900Mi)은 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
`busybox` 파드에 정의된 모든 컨테이너는 리밋레인지 유효성 검사를 통과했으므로 이 파드는 유효하며 네임스페이스에서 생성된다.
## 파드 컴퓨팅 리소스 제한
다음 절에서는 파드 레벨에서 리소스를 제한하는 방법에 대해 설명한다.
{{< codenew file="admin/resource/limit-mem-cpu-pod.yaml" >}}
`busybox1` 파드를 삭제하지 않고 `limitrange-demo` 네임스페이스에 `limit-mem-cpu-pod` 리밋레인지를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-mem-cpu-pod.yaml
```
리밋레인지가 생성되고 파드별로 CPU가 2 코어로, 메모리가 2Gi로 제한된다.
```shell
limitrange/limit-mem-cpu-per-pod created
```
다음 kubectl 명령을 사용하여 `limit-mem-cpu-per-pod` 리밋레인지 오브젝트의 정보를 나타낸다.
```shell
kubectl describe limitrange/limit-mem-cpu-per-pod
```
```shell
Name: limit-mem-cpu-per-pod
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod cpu - 2 - - -
Pod memory - 2Gi - - -
```
이제 `busybox2` 파드를 생성한다.
{{< codenew file="admin/resource/limit-range-pod-2.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-2.yaml
```
`busybox2` 파드 정의는 `busybox1`과 동일하지만 이제 파드 리소스가 제한되어 있으므로 오류가 보고된다.
```shell
Error from server (Forbidden): error when creating "limit-range-pod-2.yaml": pods "busybox2" is forbidden: [maximum cpu usage per Pod is 2, but limit is 2400m., maximum memory usage per Pod is 2Gi, but limit is 2306867200.]
```
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[].resources.limits.memory"
"200Mi"
"900Mi"
"200Mi"
"900Mi"
```
해당 컨테이너의 총 메모리 제한이 리밋레인지에 정의된 제한보다 크므로 `busybox2` 파드는 클러스터에서 허용되지 않는다.
`busyRange1`은 리밋레인지를 생성하기 전에 클러스터에서 생성되고 허용되므로 제거되지 않는다.
## 스토리지 리소스 제한
리밋레인지를 사용하여 네임스페이스에서 각 퍼시스턴트볼륨클레임이 요청할 수 있는 [스토리지 리소스](/ko/docs/concepts/storage/persistent-volumes/)의 최소 및 최대 크기를 지정할 수 있다.
{{< codenew file="admin/resource/storagelimits.yaml" >}}
`kubectl create`를 사용하여 YAML을 적용한다.
```shell
kubectl create -f https://k8s.io/examples/admin/resource/storagelimits.yaml
```
```shell
limitrange/storagelimits created
```
생성된 오브젝트의 정보를 나타낸다.
```shell
kubectl describe limits/storagelimits
```
출력은 다음과 같다.
```shell
Name: storagelimits
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
PersistentVolumeClaim storage 1Gi 2Gi - - -
```
{{< codenew file="admin/resource/pvc-limit-lower.yaml" >}}
```shell
kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-lower.yaml
```
`requests.storage`가 리밋레인지의 Min 값보다 낮은 PVC를 만드는 동안 서버에서 발생하는 오류는 다음과 같다.
```shell
Error from server (Forbidden): error when creating "pvc-limit-lower.yaml": persistentvolumeclaims "pvc-limit-lower" is forbidden: minimum storage usage per PersistentVolumeClaim is 1Gi, but request is 500Mi.
```
`requests.storage`가 리밋레인지의 Max 값보다 큰 경우에도 동일한 동작이 나타난다.
{{< codenew file="admin/resource/pvc-limit-greater.yaml" >}}
```shell
kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-greater.yaml
```
```shell
Error from server (Forbidden): error when creating "pvc-limit-greater.yaml": persistentvolumeclaims "pvc-limit-greater" is forbidden: maximum storage usage per PersistentVolumeClaim is 2Gi, but request is 5Gi.
```
## 제한/요청 비율
`LimitRangeSpec``LimitRangeItem.maxLimitRequestRatio`가 지정되어 있으면 명명된 리소스는 제한을 요청으로 나눈 값이 열거된 값보다 작거나 같은 0이 아닌 값을 요청과 제한 모두 가져야 한다.
다음의 리밋레인지는 메모리 제한이 네임스페이스의 모든 파드에 대한 메모리 요청 양의 최대 두 배가 되도록 한다.
{{< codenew file="admin/resource/limit-memory-ratio-pod.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-memory-ratio-pod.yaml
```
다음의 kubectl 명령으로 `limit-memory-ratio-pod` 리밋레인지의 정보를 나타낸다.
```shell
kubectl describe limitrange/limit-memory-ratio-pod
```
```shell
Name: limit-memory-ratio-pod
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod memory - - - - 2
```
`requests.memory=100Mi``limits.memory=300Mi`로 파드를 생성한다.
{{< codenew file="admin/resource/limit-range-pod-3.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-3.yaml
```
위 예에서 제한/요청 비율(`3`)이 `limit-memory-ratio-pod` 리밋레인지에 지정된 제한 비율(`2`)보다 커서 파드 생성에 실패했다.
```
Error from server (Forbidden): error when creating "limit-range-pod-3.yaml": pods "busybox3" is forbidden: memory max limit to request ratio per Pod is 2, but provided ratio is 3.000000.
```
## 정리
모든 리소스를 해제하려면 `limitrange-demo` 네임스페이스를 삭제한다.
```shell
kubectl delete ns limitrange-demo
```
다음 명령을 사용하여 컨텍스트를 `default` 네임스페이스로 변경한다.
```shell
kubectl config set-context --current --namespace=default
```
## 예제
- [네임스페이스별 컴퓨팅 리소스를 제한하는 방법에 대한 튜토리얼](/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)을 참고하길 바란다.
- [스토리지 사용을 제한하는 방법](/docs/tasks/administer-cluster/limit-storage-consumption/#limitrange-to-limit-requests-for-storage)을 확인하라.
- [네임스페이스별 쿼터에 대한 자세한 예](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/)를 참고하길 바란다.
{{% /capture %}}
{{% capture whatsnext %}}
보다 자세한 내용은 [LimitRanger 설계 문서](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md)를 참고하길 바란다.
{{% /capture %}}
@@ -0,0 +1,635 @@
---
title: 파드 시큐리티 폴리시
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state state="beta" >}}
파드 시큐리티 폴리시를 사용하면 파드 생성 및 업데이트에 대한 세분화된 권한을
부여할 수 있다.
{{% /capture %}}
{{% capture body %}}
## 파드 시큐리티 폴리시란?
_Pod Security Policy_ 는 파드 명세의 보안 관련 측면을 제어하는 ​​클러스터-레벨의
리소스이다. [파드시큐리티폴리시](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) 오브젝트는
관련 필드에 대한 기본값뿐만 아니라 시스템에 적용하기 위해 파드가 실행해야만 하는
조건 셋을 정의한다. 관리자는
다음을 제어할 수 있다.
| 제어 측면 | 필드 이름 |
| ----------------------------------------------------| ------------------------------------------- |
| 특권을 가진(privileged) 컨테이너의 실행 | [`privileged`](#privileged) |
| 호스트 네임스페이스의 사용 | [`hostPID`, `hostIPC`](#host-namespaces) |
| 호스트 네트워킹과 포트의 사용 | [`hostNetwork`, `hostPorts`](#host-namespaces) |
| 볼륨 유형의 사용 | [`volumes`](#volumes-and-file-systems) |
| 호스트 파일시스템의 사용 | [`allowedHostPaths`](#volumes-and-file-systems) |
| FlexVolume 드라이버의 화이트리스트 | [`allowedFlexVolumes`](#flexvolume-drivers) |
| 파드 볼륨을 소유한 FSGroup 할당 | [`fsGroup`](#volumes-and-file-systems) |
| 읽기 전용 루트 파일시스템 사용 필요 | [`readOnlyRootFilesystem`](#volumes-and-file-systems) |
| 컨테이너의 사용자 및 그룹 ID | [`runAsUser`, `runAsGroup`, `supplementalGroups`](#users-and-groups) |
| 루트 특권으로의 에스컬레이션 제한 | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) |
| 리눅스 기능 | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) |
| 컨테이너의 SELinux 컨텍스트 | [`seLinux`](#selinux) |
| 컨테이너에 허용된 Proc 마운트 유형 | [`allowedProcMountTypes`](#allowedprocmounttypes) |
| 컨테이너가 사용하는 AppArmor 프로파일 | [어노테이션](#apparmor) |
| 컨테이너가 사용하는 seccomp 프로파일 | [어노테이션](#seccomp) |
| 컨테이너가 사용하는 sysctl 프로파일 | [`forbiddenSysctls`,`allowedUnsafeSysctls`](#sysctl) |
## 파드 시큐리티 폴리시 활성화
파드 시큐리티 폴리시 제어는 선택 사항(하지만 권장함)인
[어드미션
컨트롤러](/docs/reference/access-authn-authz/admission-controllers/#podsecuritypolicy)로
구현된다. [어드미션 컨트롤러 활성화](/docs/reference/access-authn-authz/admission-controllers/#how-do-i-turn-on-an-admission-control-plug-in)하면
파드시큐리티폴리시가 적용되지만,
정책을 승인하지 않고 활성화하면 클러스터에
**파드가 생성되지 않는다.**
파드 시큐리티 폴리시 API(`policy/v1beta1/podsecuritypolicy`)는
어드미션 컨트롤러와 독립적으로 활성화되므로 기존 클러스터의 경우
어드미션 컨트롤러를 활성화하기 전에 정책을 추가하고 권한을
부여하는 것이 좋다.
## 정책 승인
파드시큐리티폴리시 리소스가 생성되면 아무 것도 수행하지 않는다. 이를 사용하려면
요청 사용자 또는 대상 파드의
[서비스 어카운트](/docs/tasks/configure-pod-container/configure-service-account/)는
정책에서 `use` 동사를 허용하여 정책을 사용할 권한이 있어야 한다.
대부분의 쿠버네티스 파드는 사용자가 직접 만들지 않는다. 대신 일반적으로
컨트롤러 관리자를 통해
[디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/),
[레플리카셋](/ko/docs/concepts/workloads/controllers/replicaset/), 또는 기타
템플릿 컨트롤러의 일부로 간접적으로 생성된다. 컨트롤러에 정책에 대한 접근 권한을 부여하면
해당 컨트롤러에 의해 생성된 *모든* 파드에 대한 접근 권한이 부여되므로 정책을 승인하는
기본 방법은 파드의 서비스 어카운트에 대한 접근 권한을
부여하는 것이다([](#다른-파드를-실행) 참고).
### RBAC을 통한 방법
[RBAC](/docs/reference/access-authn-authz/rbac/)은 표준 쿠버네티스 권한 부여 모드이며,
정책 사용 권한을 부여하는 데 쉽게 사용할 수 있다.
먼저, `Role` 또는 `ClusterRole`은 원하는 정책을 `use` 하려면 접근 권한을 부여해야 한다.
접근 권한을 부여하는 규칙은 다음과 같다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <role name>
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- <list of policies to authorize>
```
그런 다음 `(Cluster)Role`이 승인된 사용자에게 바인딩된다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <binding name>
roleRef:
kind: ClusterRole
name: <role name>
apiGroup: rbac.authorization.k8s.io
subjects:
# Authorize specific service accounts:
- kind: ServiceAccount
name: <authorized service account name>
namespace: <authorized pod namespace>
# Authorize specific users (not recommended):
- kind: User
apiGroup: rbac.authorization.k8s.io
name: <authorized user name>
```
`RoleBinding`(`ClusterRoleBinding` 아님)을 사용하는 경우, 바인딩과 동일한 네임스페이스에서
실행되는 파드에 대해서만 사용 권한을 부여한다. 네임스페이스에서 실행되는 모든 파드에 접근 권한을
부여하기 위해 시스템 그룹과 쌍을 이룰 수 있다.
```yaml
# Authorize all service accounts in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts
# Or equivalently, all authenticated users in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
```
RBAC 바인딩에 대한 자세한 예는,
[역할 바인딩 예제](/docs/reference/access-authn-authz/rbac#role-binding-examples)를 참고하길 바란다.
파드시큐리티폴리시 인증에 대한 전체 예제는
[아래](#예제)를 참고하길 바란다.
### 문제 해결
- [컨트롤러 관리자](/docs/admin/kube-controller-manager/)는
[보안 API 포트](/docs/reference/access-authn-authz/controlling-access/)에 대해 실행해야 하며,
슈퍼유저 권한이 없어야 한다. 그렇지 않으면 요청이 인증 및 권한 부여 모듈을 우회하고,
모든 파드시큐리티폴리시 오브젝트가 허용되며
사용자는 특권있는 컨테이너를 만들 수 있다. 컨트롤러 관리자 권한 구성에 대한 자세한
내용은 [컨트롤러 역할](/docs/reference/access-authn-authz/rbac/#controller-roles)을
참고하길 바란다.
## 정책 순서
파드 생성 및 업데이트를 제한할 뿐만 아니라 파드 시큐리티 폴리시를 사용하여
제어하는 ​​많은 필드에 기본값을 제공할 수도 있다. 여러 정책을
사용할 수 있는 경우 파드 시큐리티 폴리시 컨트롤러는
다음 기준에 따라 정책을 선택한다.
1. 기본 설정을 변경하거나 파드를 변경하지 않고 파드를 있는 그대로 허용하는 파드시큐리티폴리시가
선호된다. 이러한 비-변이(non-mutating) 파드시큐리티폴리시의
순서는 중요하지 않다.
2. 파드를 기본값으로 설정하거나 변경해야 하는 경우, 파드를 허용할 첫 번째 파드시큐리티폴리시
(이름순)가 선택된다.
{{< note >}}
업데이트 작업 중(파드 스펙에 대한 변경이 허용되지 않는 동안) 비-변이 파드시큐리티폴리시만
파드의 유효성을 검사하는 데 사용된다.
{{< /note >}}
## 예제
_이 예에서는 파드시큐리티폴리시 어드미션 컨트롤러가 활성화된 클러스터가 실행 중이고
클러스터 관리자 권한이 있다고 가정한다._
### 설정
이 예제와 같이 네임스페이스와 서비스 어카운트를 설정한다.
이 서비스 어카운트를 사용하여 관리자가 아닌 사용자를 조정한다.
```shell
kubectl create namespace psp-example
kubectl create serviceaccount -n psp-example fake-user
kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user
```
어떤 사용자로 활동하고 있는지 명확하게 하고 입력 내용을 저장하려면 2개의 별칭(alias)을
만든다.
```shell
alias kubectl-admin='kubectl -n psp-example'
alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example'
```
### 정책과 파드 생성
파일에서 예제 파드시큐리티폴리시 오브젝트를 정의한다. 이는 특권있는 파드를
만들지 못하게 하는 정책이다.
파드시큐리티폴리시 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names#dns-서브도메인-이름)이어야 한다.
{{< codenew file="policy/example-psp.yaml" >}}
그리고 kubectl로 생성한다.
```shell
kubectl-admin create -f example-psp.yaml
```
이제 권한이 없는 사용자로서 간단한 파드를 생성해보자.
```shell
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
Error from server (Forbidden): error when creating "STDIN": pods "pause" is forbidden: unable to validate against any pod security policy: []
```
**무슨 일이 일어났나?** 파드시큐리티폴리시가 생성되었지만, 파드의 서비스 어카운트나 `fake-user`
새 정책을 사용할 권한이 없다.
```shell
kubectl-user auth can-i use podsecuritypolicy/example
no
```
예제 정책에서 `fake-user`에게 `use` 동사를 부여하는 rolebinding을
생성한다.
{{< note >}}
이 방법은 권장하지 않는다! 선호하는 방법은 [다음 절](#다른-파드를-실행)을
참고하길 바란다.
{{< /note >}}
```shell
kubectl-admin create role psp:unprivileged \
--verb=use \
--resource=podsecuritypolicy \
--resource-name=example
role "psp:unprivileged" created
kubectl-admin create rolebinding fake-user:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:fake-user
rolebinding "fake-user:psp:unprivileged" created
kubectl-user auth can-i use podsecuritypolicy/example
yes
```
이제 파드 생성을 다시 시도하자.
```shell
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
pod "pause" created
```
예상대로 작동한다! 그러나 특권있는 파드를 만들려는 시도는 여전히
거부되어야 한다.
```shell
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: privileged
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
securityContext:
privileged: true
EOF
Error from server (Forbidden): error when creating "STDIN": pods "privileged" is forbidden: unable to validate against any pod security policy: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]
```
계속 진행하기 전에 파드를 삭제하자.
```shell
kubectl-user delete pod pause
```
### 다른 파드를 실행
약간 다르게 다시 시도해보자.
```shell
kubectl-user run pause --image=k8s.gcr.io/pause
deployment "pause" created
kubectl-user get pods
No resources found.
kubectl-user get events | head -n 2
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
1m 2m 15 pause-7774d79b5 ReplicaSet Warning FailedCreate replicaset-controller Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request
```
**무슨 일이 일어났나?** 우리는 이미 `fake-user`에 대해 `psp:unprivileged` 역할을 바인딩했는데,
`Error creating: pods "pause-7774d79b5-" is
forbidden: no providers available to validate pod request` 오류가
발생하는 이유는 무엇인가? 그 답은 소스인 `replicaset-controller`에 있다. Fake-user가
디플로이먼트를 성공적으로 생성했지만(레플리카셋을 성공적으로 생성했음), 레플리카셋이
파드를 생성했을 때 podsecuritypolicy 예제를
사용할 권한이 없었다.
이 문제를 해결하려면 `psp:unprivileged` 역할을 파드의 서비스 어카운트에 대신
바인딩한다. 이 경우(지정하지 않았으므로) 서비스 어카운트는
`default`이다.
```shell
kubectl-admin create rolebinding default:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:default
rolebinding "default:psp:unprivileged" created
```
이제 다시 한번 해본다면 replicaset-controller가
파드를 성공적으로 생성할 것이다.
```shell
kubectl-user get pods --watch
NAME READY STATUS RESTARTS AGE
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 ContainerCreating 0 1s
pause-7774d79b5-qrgcb 1/1 Running 0 2s
```
### 정리
네임스페이스를 삭제하여 대부분의 예제 리소스를 정리한다.
```shell
kubectl-admin delete ns psp-example
namespace "psp-example" deleted
```
`PodSecurityPolicy` 리소스는 네임스페이스에 포함되지 않으므로 별도로
정리해야 한다.
```shell
kubectl-admin delete psp example
podsecuritypolicy "example" deleted
```
### 정책 예제
다음은 파드 시큐리티 폴리시 어드미션 컨트롤러를 사용하지 않는 것과 동일하게 만들 수 있는
최소한의 제한 정책이다.
{{< codenew file="policy/privileged-psp.yaml" >}}
다음은 권한이 없는 사용자로서의 실행을 필요로 하고, 루트로의 에스컬레이션(escalation) 가능성을 차단하고,
여러 보안 메커니즘을 사용을 필요로 하는 제한적
정책의 예제이다.
{{< codenew file="policy/restricted-psp.yaml" >}}
## 정책 레퍼런스
### 특권을 가진
**Privileged** - 파드의 컨테이너가 특권 모드를 사용할 수 있는지 여부를 결정한다.
기본적으로 컨테이너는 호스트의 모든 장치에 접근할 수 없지만
"특권을 가진" 컨테이너는 호스트의 모든 장치에 접근할 수 있다. 이것은
컨테이너가 호스트에서 실행되는 프로세스와 거의 동일한 접근을 허용한다.
이것은 네트워크 스택 조작 및 장치 접근과 같은
리눅스 기능을 사용하려는 컨테이너에 유용하다.
### 호스트 네임스페이스
**HostPID** - 파드 컨테이너가 호스트 프로세스 ID 네임스페이스를 공유할 수 있는지 여부를
제어한다. ptrace와 함께 사용하면 컨테이너 외부로 권한을 에스컬레이션하는 데 사용할 수
있다(ptrace는 기본적으로 금지되어 있음).
**HostIPC** - 파드 컨테이너가 호스트 IPC 네임스페이스를 공유할 수 있는지 여부를
제어한다.
**HostNetwork** - 파드가 노드 네트워크 네임스페이스를 사용할 수 있는지 여부를 제어한다.
이렇게 하면 파드에 루프백 장치에 접근 권한을 주고, 서비스는 로컬호스트(localhost)를 리스닝할 수 있으며,
동일한 노드에 있는 다른 파드의 네트워크 활동을 스누핑(snoop)하는 데
사용할 수 있다.
**HostPorts** - 호스트 네트워크 네임스페이스에 허용되는 포트 범위의 화이트리스트(whitelist)를
제공한다. `min``max`를 포함하여 `HostPortRange`의 목록으로 정의된다.
기본값은 허용하는 호스트 포트 없음(no allowed host ports)이다.
### 볼륨 및 파일시스템
**Volumes** - 허용되는 볼륨 유형의 화이트리스트를 제공한다. 허용 가능한 값은
볼륨을 생성할 때 정의된 볼륨 소스에 따른다. 볼륨 유형의 전체 목록은
[볼륨 유형들](/ko/docs/concepts/storage/volumes/#볼륨-유형들)에서 참고한다.
또한 `*`를 사용하여 모든 볼륨 유형을
허용할 수 있다.
새 PSP에 허용되는 볼륨의 **최소 권장 셋** 은 다음과 같다.
- 컨피그맵
- 다운워드API
- emptyDir
- 퍼시스턴트볼륨클레임
- 시크릿
- 프로젝티드(projected)
{{< warning >}}
파드시큐리티폴리시는 `PersistentVolumeClaim`이 참조할 수 있는 `PersistentVolume`
오브젝트의 유형을 제한하지 않으며 hostPath 유형
`PersistentVolumes`은 읽기-전용 접근 모드를 지원하지 않는다. 신뢰할 수 있는 사용자만
`PersistentVolume` 오브젝트를 생성할 수 있는 권한을 부여 받아야 한다.
{{< /warning >}}
**FSGroup** - 일부 볼륨에 적용되는 보충 그룹(supplemental group)을 제어한다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MayRunAs* - 하나 이상의 `range`를 지정해야 한다. 기본값을 제공하지 않고
`FSGroups`을 설정하지 않은 상태로 둘 수 있다. `FSGroups`이 설정된 경우 모든 범위에 대해
유효성을 검사한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `fsGroup` ID의 지정도 허용한다.
**AllowedHostPaths** - hostPath 볼륨에서 사용할 수 있는 호스트 경로의 화이트리스트를
지정한다. 빈 목록은 사용되는 호스트 경로에 제한이 없음을 의미한다.
이는 단일 `pathPrefix` 필드가 있는 오브젝트 목록으로 정의되며, hostPath 볼륨은
허용된 접두사로 시작하는 경로를 마운트할 수 있으며 `readOnly` 필드는
읽기-전용으로 마운트 되어야 함을 나타낸다.
예를 들면 다음과 같습니다.
```yaml
allowedHostPaths:
# 이 정책은 "/foo", "/foo/", "/foo/bar" 등을 허용하지만,
# "/fool", "/etc/foo" 등은 허용하지 않는다.
# "/foo/../" 는 절대 유효하지 않다.
- pathPrefix: "/foo"
readOnly: true # 읽기 전용 마운트만 허용
```
{{< warning >}}호스트 파일시스템에 제한없는 접근을 부여하며, 컨테이너가 특권을 에스컬레이션
(다른 컨테이너들에 있는 데이터를 읽고, 시스템 서비스의 자격 증명을 어뷰징(abusing)하는 등)할
수 있도록 만드는 다양한 방법이 있다. 예를 들면, Kubelet과 같다.
쓰기 가능한 hostPath 디렉토리 볼륨을 사용하면, 컨테이너가 `pathPrefix` 외부의
호스트 파일시스템에 대한 통행을 허용하는 방식으로 컨테이너의 파일시스템 쓰기(write)를 허용한다.
쿠버네티스 1.11 이상 버전에서 사용 가능한 `readOnly: true`는 지정된 `pathPrefix`에 대한
접근을 효과적으로 제한하기 위해 **모든** `allowedHostPaths`에서 사용해야 한다.
{{< /warning >}}
**ReadOnlyRootFilesystem** - 컨테이너는 읽기-전용 루트 파일시스템(즉, 쓰기 가능한 레이어 없음)으로
실행해야 한다.
### FlexVolume 드라이버
flexvolume에서 사용할 수 있는 FlexVolume 드라이버의 화이트리스트를 지정한다.
빈 목록 또는 nil은 드라이버에 제한이 없음을 의미한다.
[`volumes`](#볼륨-및-파일시스템) 필드에 `flexVolume` 볼륨 유형이 포함되어
있는지 확인한다. 그렇지 않으면 FlexVolume 드라이버가 허용되지 않는다.
예를 들면 다음과 같다.
```yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: allow-flex-volumes
spec:
# ... 다른 스펙 필드
volumes:
- flexVolume
allowedFlexVolumes:
- driver: example/lvm
- driver: example/cifs
```
### 사용자 및 그룹
**RunAsUser** - 컨테이너를 실행할 사용자 ID를 제어힌다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MustRunAsNonRoot* - 파드가 0이 아닌 `runAsUser`로 제출되거나
이미지에 `USER` 지시문이 정의되어 있어야 한다(숫자 UID 사용). `runAsNonRoot` 또는
`runAsUser` 설정을 지정하지 않은 파드는 `runAsNonRoot=true`를 설정하도록
변경되므로 컨테이너에 0이 아닌 숫자가 정의된 `USER` 지시문이
필요하다. 기본값은 제공되지 않는다.
이 전략에서는 `allowPrivilegeEscalation=false`를 설정하는 것이 좋다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `runAsUser`의 지정도 허용한다.
**RunAsGroup** - 컨테이너가 실행될 기본 그룹 ID를 제어한다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MayRunAs* - `RunAsGroup`을 지정할 필요가 없다. 그러나 `RunAsGroup`을 지정하면
정의된 범위에 속해야 한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `runAsGroup`의 지정도 허용한다.
**SupplementalGroups** - 컨테이너가 추가할 그룹 ID를 제어한다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MayRunAs* - 하나 이상의 `range`를 지정해야 한다. `supplementalGroups`
기본값을 제공하지 않고 설정하지 않은 상태로 둘 수 있다.
`supplementalGroups`가 설정된 경우 모든 범위에 대해 유효성을 검증한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `supplementalGroups`의 지정도
허용한다.
### 권한 에스컬레이션
이 옵션은 `allowPrivilegeEscalation` 컨테이너 옵션을 제어한다. 이 bool은
컨테이너 프로세스에서
[`no_new_privs`](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt)
플래그가 설정되는지 여부를 직접 제어한다. 이 플래그는 `setuid` 바이너리가
유효 사용자 ID를 변경하지 못하게 하고 파일에 추가 기능을 활성화하지 못하게
한다(예: `ping` 도구 사용을 못하게 함). `MustRunAsNonRoot`를 효과적으로
강제하려면 이 동작이 필요하다.
**AllowPrivilegeEscalation** - 사용자가 컨테이너의 보안 컨텍스트를
`allowPrivilegeEscalation=true`로 설정할 수 있는지 여부를 게이트한다.
이 기본값은 setuid 바이너리를 중단하지 않도록 허용한다. 이를 `false`로 설정하면
컨테이너의 하위 프로세스가 상위 프로세스보다 더 많은 권한을 얻을 수 없다.
**DefaultAllowPrivilegeEscalation** - `allowPrivilegeEscalation` 옵션의
기본값을 설정한다. 이것이 없는 기본 동작은 setuid 바이너리를 중단하지 않도록
권한 에스컬레이션을 허용하는 것이다. 해당 동작이 필요하지 않은 경우 이 필드를 사용하여
기본적으로 허용하지 않도록 설정할 수 있지만 파드는 여전히 `allowPrivilegeEscalation`
명시적으로 요청할 수 있다.
### 기능
리눅스 기능은 전통적으로 슈퍼유저와 관련된 권한을 보다 세밀하게 분류한다.
이러한 기능 중 일부는 권한 에스컬레이션 또는 컨테이너 분류에 사용될 수 있으며
파드시큐리티폴리시에 의해 제한될 수 있다. 리눅스 기능에 대한 자세한 내용은
[기능(7)](http://man7.org/linux/man-pages/man7/capabilities.7.html)을
참고하길 바란다.
다음 필드는 대문자로 표기된 기능 이름 목록을
`CAP_` 접두사 없이 가져온다.
**AllowedCapabilities** - 컨테이너에 추가될 수 있는 기능의 화이트리스트를
제공한다. 기본적인 기능 셋은 암시적으로 허용된다. 비어있는 셋은
기본 셋을 넘어서는 추가 기능이 추가되지 않는 것을
의미한다. `*`는 모든 기능을 허용하는 데 사용할 수 있다.
**RequiredDropCapabilities** - 컨테이너에서 삭제해야 하는 기능이다.
이러한 기능은 기본 셋에서 제거되며 추가해서는 안된다.
`RequiredDropCapabilities`에 나열된 기능은 `AllowedCapabilities` 또는
`DefaultAddCapabilities`에 포함되지 않아야 한다.
**DefaultAddCapabilities** - 런타임 기본값 외에 기본적으로 컨테이너에 추가되는 기능이다.
도커 런타임을 사용할 때 기본 기능 목록은
[도커 문서](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)를
참고하길 바란다.
### SELinux
- *MustRunAs* - `seLinuxOptions`을 구성해야 한다.
`seLinuxOptions`을 기본값으로 사용한다. `seLinuxOptions`에 대해 유효성을 검사한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `seLinuxOptions`의 지정도
허용한다.
### AllowedProcMountTypes
`allowedProcMountTypes`는 허용된 ProcMountTypes의 화이트리스트이다.
비어 있거나 nil은 `DefaultProcMountType`만 사용할 수 있음을 나타낸다.
`DefaultProcMount`는 /proc의 읽기 전용 및 마스킹(masking)된 경로에 컨테이너 런타임
기본값을 사용한다. 대부분의 컨테이너 런타임은 특수 장치나 정보가 실수로 보안에
노출되지 않도록 /proc의 특정 경로를 마스킹한다. 이것은 문자열
`Default`로 표시된다.
유일하게 다른 ProcMountType은 `UnmaskedProcMount`로, 컨테이너 런타임의
기본 마스킹 동작을 무시하고 새로 작성된 /proc 컨테이너가 수정없이
그대로 유지되도록 한다. 이 문자열은
`Unmasked`로 표시된다.
### AppArmor
파드시큐리티폴리시의 어노테이션을 통해 제어된다. [AppArmor
문서](/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations)를 참고하길 바란다.
### Seccomp
파드에서 seccomp 프로파일의 사용은 파드시큐리티폴리시의 어노테이션을 통해
제어할 수 있다. Seccomp는 쿠버네티스의 알파 기능이다.
**seccomp.security.alpha.kubernetes.io/defaultProfileName** - 컨테이너에
적용할 기본 seccomp 프로파일을 지정하는 어노테이션이다. 가능한 값은
다음과 같다.
- `unconfined` - 대안이 제공되지 않으면 Seccomp가 컨테이너 프로세스에 적용되지
않는다(쿠버네티스의 기본값임).
- `runtime/default` - 기본 컨테이너 런타임 프로파일이 사용된다.
- `docker/default` - 도커 기본 seccomp 프로파일이 사용된다. 쿠버네티스 1.11 부터 사용 중단(deprecated)
되었다. 대신 `runtime/default` 사용을 권장한다.
- `localhost/<path>` - `<seccomp_root>/<path>`에 있는 노드에서 파일을 프로파일로
지정한다. 여기서 `<seccomp_root>`는 Kubelet의 `--seccomp-profile-root` 플래그를
통해 정의된다.
**seccomp.security.alpha.kubernetes.io/allowedProfileNames** - 파드 seccomp
어노테이션에 허용되는 값을 지정하는 어노테이션. 쉼표로 구분된
허용된 값의 목록으로 지정된다. 가능한 값은 위에 나열된 값과
모든 프로파일을 허용하는 `*` 이다.
이 주석이 없으면 기본값을 변경할 수 없다.
### Sysctl
기본적으로 모든 안전한 sysctls가 허용된다.
- `forbiddenSysctls` - 특정 sysctls를 제외한다. 목록에서 안전한 것과 안전하지 않은 sysctls의 조합을 금지할 수 있다. 모든 sysctls 설정을 금지하려면 자체적으로 `*`를 사용한다.
- `allowedUnsafeSysctls` - `forbiddenSysctls`에 나열되지 않는 한 기본 목록에서 허용하지 않은 특정 sysctls를 허용한다.
[Sysctl 문서](
/docs/concepts/cluster-administration/sysctl-cluster/#podsecuritypolicy)를 참고하길 바란다.
{{% /capture %}}
{{% capture whatsnext %}}
API 세부 정보는 [파드 시큐리티 폴리시 레퍼런스](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) 참조
{{% /capture %}}
@@ -0,0 +1,600 @@
---
title: 리소스 쿼터
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
여러 사용자나 팀이 정해진 수의 노드로 클러스터를 공유할 때
한 팀이 공정하게 분배된 리소스보다 많은 리소스를 사용할 수 있다는 우려가 있다.
리소스 쿼터는 관리자가 이 문제를 해결하기 위한 도구이다.
{{% /capture %}}
{{% capture body %}}
`ResourceQuota` 오브젝트로 정의된 리소스 쿼터는 네임스페이스별 총 리소스 사용을 제한하는
제약 조건을 제공한다. 유형별로 네임스페이스에서 만들 수 있는 오브젝트 수와
해당 프로젝트의 리소스가 사용할 수 있는 총 컴퓨트 리소스의 양을
제한할 수 있다.
리소스 쿼터는 다음과 같이 작동한다.
- 다른 팀은 다른 네임스페이스에서 작동한다. 현재 이것은 자발적이지만 ACL을 통해 이 필수 사항을
적용하기 위한 지원이 계획되어 있다.
- 관리자는 각 네임스페이스에 대해 하나의 `ResourceQuota`를 생성한다.
- 사용자는 네임스페이스에서 리소스(파드, 서비스 등)를 생성하고 쿼터 시스템은
사용량을 추적하여 `ResourceQuota`에 정의된 하드(hard) 리소스 제한을 초과하지 않도록 한다.
- 리소스를 생성하거나 업데이트할 때 쿼터 제약 조건을 위반하면 위반된 제약 조건을 설명하는
메시지와 함께 HTTP 상태 코드 `403 FORBIDDEN`으로 요청이 실패한다.
- `cpu`, `memory`와 같은 컴퓨트 리소스에 대해 네임스페이스에서 쿼터가 활성화된 경우
사용자는 해당값에 대한 요청 또는 제한을 지정해야 한다. 그렇지 않으면 쿼터 시스템이
파드 생성을 거부할 수 있다. 힌트: 컴퓨트 리소스 요구 사항이 없는 파드를 기본값으로 설정하려면 `LimitRanger` 어드미션 컨트롤러를 사용하자.
이 문제를 회피하는 방법에 대한 예제는 [연습](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/)을 참고하길 바란다.
`ResourceQuota` 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names#dns-서브도메인-이름)이어야 한다.
네임스페이스와 쿼터를 사용하여 만들 수 있는 정책의 예는 다음과 같다.
- 용량이 32GiB RAM, 16 코어인 클러스터에서 A 팀이 20GiB 및 10 코어를 사용하고
B 팀은 10GiB 및 4 코어를 사용하게 하고 2GiB 및 2 코어를 향후 할당을 위해 보유하도록 한다.
- "testing" 네임스페이스를 1 코어 및 1GiB RAM을 사용하도록 제한한다.
"production" 네임스페이스에는 원하는 양을 사용하도록 한다.
클러스터의 총 용량이 네임스페이스의 쿼터 합보다 작은 경우 리소스에 대한 경합이 있을 수 있다.
이것은 선착순으로 처리된다.
경합이나 쿼터 변경은 이미 생성된 리소스에 영향을 미치지 않는다.
## 리소스 쿼터 활성화
많은 쿠버네티스 배포판에 기본적으로 리소스 쿼터 지원이 활성화되어 있다.
API 서버 `--enable-admission-plugins=` 플래그의 인수 중 하나로
`ResourceQuota`가 있는 경우 활성화된다.
해당 네임스페이스에 `ResourceQuota`가 있는 경우 특정 네임스페이스에 리소스 쿼터가 적용된다.
## 컴퓨트 리소스 쿼터
지정된 네임스페이스에서 요청할 수 있는 총 [컴퓨트 리소스](/docs/user-guide/compute-resources) 합을 제한할 수 있다.
다음과 같은 리소스 유형이 지원된다.
| 리소스 이름 | 설명 |
| --------------------- | ----------------------------------------------------------- |
| `limits.cpu` | 터미널이 아닌 상태의 모든 파드에서 CPU 제한의 합은 이 값을 초과할 수 없음 |
| `limits.memory` | 터미널이 아닌 상태의 모든 파드에서 메모리 제한의 합은 이 값을 초과할 수 없음 |
| `requests.cpu` | 터미널이 아닌 상태의 모든 파드에서 CPU 요청의 합은 이 값을 초과할 수 없음 |
| `requests.memory` | 터미널이 아닌 상태의 모든 파드에서 메모리 요청의 합은 이 값을 초과할 수 없음 |
### 확장된 리소스에 대한 리소스 쿼터
위에서 언급한 리소스 외에도 릴리스 1.10에서는
[확장된 리소스](/docs/concepts/configuration/manage-compute-resources-container/#extended-resources)에 대한 쿼터 지원이 추가되었다.
확장된 리소스에는 오버커밋(overcommit)이 허용되지 않으므로 하나의 쿼터에서
동일한 확장된 리소스에 대한 `requests``limits`을 모두 지정하는 것은 의미가 없다. 따라서 확장된
리소스의 경우 지금은 접두사 `requests.`이 있는 쿼터 항목만 허용된다.
예를 들어, 리소스 이름이 `nvidia.com/gpu`이고 네임스페이스에서 요청된 총 GPU 수를 4개로 제한하려는 경우,
GPU 리소스를 다음과 같이 쿼터를 정의할 수 있다.
* `requests.nvidia.com/gpu: 4`
자세한 내용은 [쿼터 보기 및 설정](#쿼터-보기-및-설정)을 참고하길 바란다.
## 스토리지 리소스 쿼터
지정된 네임스페이스에서 요청할 수 있는 총 [스토리지 리소스](/ko/docs/concepts/storage/persistent-volumes/) 합을 제한할 수 있다.
또한 연관된 ​​스토리지 클래스를 기반으로 스토리지 리소스 사용을 제한할 수 있다.
| 리소스 이름 | 설명 |
| --------------------- | ----------------------------------------------------------- |
| `requests.storage` | 모든 퍼시스턴트 볼륨 클레임에서 스토리지 요청의 합은 이 값을 초과할 수 없음 |
| `persistentvolumeclaims` | 네임스페이스에 존재할 수 있는 총 [퍼시스턴트 볼륨 클레임](/ko/docs/concepts/storage/persistent-volumes/#퍼시스턴트볼륨클레임) 수 |
| `<storage-class-name>.storageclass.storage.k8s.io/requests.storage` | storage-class-name과 관련된 모든 퍼시스턴트 볼륨 클레임에서 스토리지 요청의 합은 이 값을 초과할 수 없음 |
| `<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims` | storage-class-name과 관련된 모든 퍼시스턴트 볼륨 클레임에서 네임스페이스에 존재할 수 있는 총 [퍼시스턴트 볼륨 클레임](/ko/docs/concepts/storage/persistent-volumes/#퍼시스턴트볼륨클레임) 수 |
예를 들어, 운영자가 `bronze` 스토리지 클래스와 별도로 `gold` 스토리지 클래스를 사용하여 스토리지에 쿼터를 지정하려는 경우 운영자는 다음과 같이
쿼터를 정의할 수 있다.
* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi`
* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi`
릴리스 1.8에서는 로컬 임시 스토리지에 대한 쿼터 지원이 알파 기능으로 추가되었다.
| 리소스 이름 | 설명 |
| ------------------------------- |----------------------------------------------------------- |
| `requests.ephemeral-storage` | 네임스페이스의 모든 파드에서 로컬 임시 스토리지 요청의 합은 이 값을 초과할 수 없음 |
| `limits.ephemeral-storage` | 네임스페이스의 모든 파드에서 로컬 임시 스토리지 제한의 합은 이 값을 초과할 수 없음 |
## 오브젝트 수 쿼터
1.9 릴리스는 다음 구문을 사용하여 모든 표준 네임스페이스 리소스 유형에 쿼터를 지정하는 지원을 추가했다.
* `count/<resource>.<group>`
다음은 사용자가 오브젝트 수 쿼터 아래에 배치하려는 리소스 셋의 예이다.
* `count/persistentvolumeclaims`
* `count/services`
* `count/secrets`
* `count/configmaps`
* `count/replicationcontrollers`
* `count/deployments.apps`
* `count/replicasets.apps`
* `count/statefulsets.apps`
* `count/jobs.batch`
* `count/cronjobs.batch`
* `count/deployments.extensions`
1.15 릴리스는 동일한 구문을 사용하여 사용자 정의 리소스에 대한 지원을 추가했다.
예를 들어 `example.com` API 그룹에서 `widgets` 사용자 정의 리소스에 대한 쿼터를 생성하려면 `count/widgets.example.com`을 사용한다.
`count/*` 리소스 쿼터를 사용할 때 서버 스토리지 영역에 있다면 오브젝트는 쿼터에 대해 과금된다.
이러한 유형의 쿼터는 스토리지 리소스 고갈을 방지하는 데 유용하다. 예를 들어,
크기가 큰 서버에서 시크릿 수에 쿼터를 지정할 수 있다. 클러스터에 시크릿이 너무 많으면 실제로 서버와
컨트롤러가 시작되지 않을 수 있다! 네임스페이스에 너무 많은 작업을 생성하는
잘못 구성된 크론 잡으로 인해 서비스 거부를 유발하는 것으로부터 보호하기 위해 작업의 쿼터를 지정하도록 선택할 수 있다.
1.9 릴리스 이전에는 제한된 리소스 셋에서 일반 오브젝트 수 쿼터를 적용할 수 있었다.
또한, 특정 리소스에 대한 쿼터를 유형별로 추가로 제한할 수 있다.
다음 유형이 지원된다.
| 리소스 이름 | 설명 |
| ------------------------------- | ------------------------------------------------- |
| `configmaps` | 네임스페이스에 존재할 수 있는 총 구성 맵 수 |
| `persistentvolumeclaims` | 네임스페이스에 존재할 수 있는 총 [퍼시스턴트 볼륨 클레임](/ko/docs/concepts/storage/persistent-volumes/#퍼시스턴트볼륨클레임) 수 |
| `pods` | 네임스페이스에 존재할 수 있는 터미널이 아닌 상태의 파드의 총 수. `.status.phase in (Failed, Succeeded)`가 true인 경우 파드는 터미널 상태임 |
| `replicationcontrollers` | 네임스페이스에 존재할 수 있는 총 레플리케이션 컨트롤러 수 |
| `resourcequotas` | 네임스페이스에 존재할 수 있는 총 [리소스 쿼터](/docs/reference/access-authn-authz/admission-controllers/#resourcequota) 수 |
| `services` | 네임스페이스에 존재할 수 있는 총 서비스 수 |
| `services.loadbalancers` | 네임스페이스에 존재할 수 있는 로드 밸런서 유형의 총 서비스 수 |
| `services.nodeports` | 네임스페이스에 존재할 수 있는 노드 포트 유형의 총 서비스 수 |
| `secrets` | 네임스페이스에 존재할 수 있는 총 시크릿 수 |
예를 들어, `pods` 쿼터는 터미널이 아닌 단일 네임스페이스에서 생성된 `pods` 수를 계산하고 최대값을 적용한다.
사용자가 작은 파드를 많이 생성하여 클러스터의 파드 IP 공급이 고갈되는 경우를 피하기 위해
네임스페이스에 `pods` 쿼터를 설정할 수 있다.
## 쿼터 범위
각 쿼터에는 연결된 범위 셋이 있을 수 있다. 쿼터는 열거된 범위의 교차 부분과 일치하는 경우에만
리소스 사용량을 측정한다.
범위가 쿼터에 추가되면 해당 범위와 관련된 리소스를 지원하는 리소스 수가 제한된다.
허용된 셋 이외의 쿼터에 지정된 리소스는 유효성 검사 오류가 발생한다.
| 범위 | 설명 |
| ----- | ----------- |
| `Terminating` | `.spec.activeDeadlineSeconds >= 0`에 일치하는 파드 |
| `NotTerminating` | `.spec.activeDeadlineSeconds is nil`에 일치하는 파드 |
| `BestEffort` | 최상의 서비스 품질을 제공하는 파드 |
| `NotBestEffort` | 서비스 품질이 나쁜 파드 |
`BestEffort` 범위는 다음의 리소스(파드)를 추적하도록 쿼터를 제한한다.
`Terminating`, `NotTerminating``NotBestEffort` 범위는 쿼터를 제한하여 다음의 리소스를 추적한다.
* `cpu`
* `limits.cpu`
* `limits.memory`
* `memory`
* `pods`
* `requests.cpu`
* `requests.memory`
### PriorityClass별 리소스 쿼터
{{< feature-state for_k8s_version="1.12" state="beta" >}}
특정 [우선 순위](/docs/concepts/configuration/pod-priority-preemption/#pod-priority)로 파드를 생성할 수 있다.
쿼터 스펙의 `scopeSelector` 필드를 사용하여 파드의 우선 순위에 따라 파드의 시스템 리소스 사용을
제어할 수 있다.
쿼터 스펙의 `scopeSelector`가 파드를 선택한 경우에만 쿼터가 일치하고 사용된다.
이 예에서는 쿼터 오브젝트를 생성하여 특정 우선 순위의 파드와 일치시킨다.
예제는 다음과 같이 작동한다.
- 클러스터의 파드는 "low(낮음)", "medium(중간)", "high(높음)"의 세 가지 우선 순위 클래스 중 하나를 가진다.
- 각 우선 순위마다 하나의 쿼터 오브젝트가 생성된다.
다음 YAML을 `quota.yml` 파일에 저장한다.
```yaml
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-high
spec:
hard:
cpu: "1000"
memory: 200Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["high"]
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-medium
spec:
hard:
cpu: "10"
memory: 20Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["medium"]
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-low
spec:
hard:
cpu: "5"
memory: 10Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["low"]
```
`kubectl create`를 사용하여 YAML을 적용한다.
```shell
kubectl create -f ./quota.yml
```
```shell
resourcequota/pods-high created
resourcequota/pods-medium created
resourcequota/pods-low created
```
`kubectl describe quota`를 사용하여 `Used` 쿼터가 `0`인지 확인하자.
```shell
kubectl describe quota
```
```shell
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 1k
memory 0 200Gi
pods 0 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
```
우선 순위가 "high"인 파드를 생성한다. 다음 YAML을
`high-priority-pod.yml` 파일에 저장한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: high-priority
spec:
containers:
- name: high-priority
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
resources:
requests:
memory: "10Gi"
cpu: "500m"
limits:
memory: "10Gi"
cpu: "500m"
priorityClassName: high
```
`kubectl create`로 적용하자.
```shell
kubectl create -f ./high-priority-pod.yml
```
"high" 우선 순위 쿼터가 적용된 `pods-high`에 대한 "Used" 통계가 변경되었고
다른 두 쿼터는 변경되지 않았는지 확인한다.
```shell
kubectl describe quota
```
```shell
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 500m 1k
memory 10Gi 200Gi
pods 1 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
```
`scopeSelector``operator` 필드에서 다음 값을 지원한다.
* `In`
* `NotIn`
* `Exist`
* `DoesNotExist`
## 요청과 제한의 비교 {#requests-vs-limits}
컴퓨트 리소스를 할당할 때 각 컨테이너는 CPU 또는 메모리에 대한 요청과 제한값을 지정할 수 있다.
쿼터는 값에 대한 쿼터를 지정하도록 구성할 수 있다.
쿼터에 `requests.cpu``requests.memory`에 지정된 값이 있으면 들어오는 모든
컨테이너가 해당 리소스에 대한 명시적인 요청을 지정해야 한다. 쿼터에 `limits.cpu`
`limits.memory`에 지정된 값이 있으면 들어오는 모든 컨테이너가 해당 리소스에 대한 명시적인 제한을 지정해야 한다.
## 쿼터 보기 및 설정
Kubectl은 쿼터 생성, 업데이트 및 보기를 지원한다.
```shell
kubectl create namespace myspace
```
```shell
cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
requests.nvidia.com/gpu: 4
EOF
```
```shell
kubectl create -f ./compute-resources.yaml --namespace=myspace
```
```shell
cat <<EOF > object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
pods: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"
EOF
```
```shell
kubectl create -f ./object-counts.yaml --namespace=myspace
```
```shell
kubectl get quota --namespace=myspace
```
```shell
NAME AGE
compute-resources 30s
object-counts 32s
```
```shell
kubectl describe quota compute-resources --namespace=myspace
```
```shell
Name: compute-resources
Namespace: myspace
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
requests.cpu 0 1
requests.memory 0 1Gi
requests.nvidia.com/gpu 0 4
```
```shell
kubectl describe quota object-counts --namespace=myspace
```
```shell
Name: object-counts
Namespace: myspace
Resource Used Hard
-------- ---- ----
configmaps 0 10
persistentvolumeclaims 0 4
pods 0 4
replicationcontrollers 0 20
secrets 1 10
services 0 10
services.loadbalancers 0 2
```
Kubectl은 `count/<resource>.<group>` 구문을 사용하여 모든 표준 네임스페이스 리소스에 대한
오브젝트 수 쿼터를 지원한다.
```shell
kubectl create namespace myspace
```
```shell
kubectl create quota test --hard=count/deployments.extensions=2,count/replicasets.extensions=4,count/pods=3,count/secrets=4 --namespace=myspace
```
```shell
kubectl run nginx --image=nginx --replicas=2 --namespace=myspace
```
```shell
kubectl describe quota --namespace=myspace
```
```shell
Name: test
Namespace: myspace
Resource Used Hard
-------- ---- ----
count/deployments.extensions 1 2
count/pods 2 3
count/replicasets.extensions 1 4
count/secrets 1 4
```
## 쿼터 및 클러스터 용량
`ResourceQuotas`는 클러스터 용량과 무관하다. 그것들은 절대 단위로 표현된다.
따라서 클러스터에 노드를 추가해도 각 네임스페이스에 더 많은 리소스를
사용할 수 있는 기능이 자동으로 부여되지는 *않는다*.
가끔 다음과 같은 보다 복잡한 정책이 필요할 수 있다.
- 여러 팀으로 전체 클러스터 리소스를 비례적으로 나눈다.
- 각 테넌트가 필요에 따라 리소스 사용량을 늘릴 수 있지만, 실수로 리소스가 고갈되는 것을
막기 위한 충분한 제한이 있다.
- 하나의 네임스페이스에서 요구를 감지하고 노드를 추가하며 쿼터를 늘린다.
이러한 정책은 쿼터 사용을 감시하고 다른 신호에 따라 각 네임스페이스의 쿼터 하드 제한을
조정하는 "컨트롤러"를 작성하여 `ResourceQuotas`를 구성 요소로
사용하여 구현할 수 있다.
리소스 쿼터는 통합된 클러스터 리소스를 분할하지만 노드에 대한 제한은 없다.
여러 네임스페이스의 파드가 동일한 노드에서 실행될 수 있다.
## 기본적으로 우선 순위 클래스 소비 제한
파드가 특정 우선 순위, 예를 들어 일치하는 쿼터 오브젝트가 존재하는 경우에만 "cluster-services"가 네임스페이스에 허용되어야 힌다.
이 메커니즘을 통해 운영자는 특정 우선 순위가 높은 클래스의 사용을 제한된 수의 네임스페이스로 제한할 수 있으며 모든 네임스페이스가 기본적으로 이러한 우선 순위 클래스를 사용할 수 있는 것은 아니다.
이를 적용하려면 kube-apiserver 플래그 `--admission-control-config-file`을 사용하여 다음 구성 파일의 경로를 전달해야 한다.
{{< tabs name="example1" >}}
{{% tab name="apiserver.config.k8s.io/v1" %}}
```yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: ResourceQuotaConfiguration
limitedResources:
- resource: pods
matchScopes:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
```
{{% /tab %}}
{{% tab name="apiserver.k8s.io/v1alpha1" %}}
```yaml
# Deprecated in v1.17 in favor of apiserver.config.k8s.io/v1
apiVersion: apiserver.k8s.io/v1alpha1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
# Deprecated in v1.17 in favor of apiserver.config.k8s.io/v1, ResourceQuotaConfiguration
apiVersion: resourcequota.admission.k8s.io/v1beta1
kind: Configuration
limitedResources:
- resource: pods
matchScopes:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
```
{{% /tab %}}
{{< /tabs >}}
이제 "cluster-services" 파드는 `scopeSelector`와 일치하는 쿼터 오브젝트가 있는 네임스페이스에서만 허용된다.
예를 들면 다음과 같다.
```yaml
scopeSelector:
matchExpressions:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
```
자세한 내용은 [LimitedResources](https://github.com/kubernetes/kubernetes/pull/36765)와 [우선 순위 클래스에 대한 쿼터 지원 디자인 문서](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/pod-priority-resourcequota.md)를 참고하길 바란다.
## 예제
[리소스 쿼터를 사용하는 방법에 대한 자세한 예](/docs/tasks/administer-cluster/quota-api-object/)를 참고하길 바란다.
{{% /capture %}}
{{% capture whatsnext %}}
자세한 내용은 [리소스쿼터 디자인 문서](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md)를 참고하길 바란다.
{{% /capture %}}