AKS(Azure Kubernetes Service)의 Pod 샌드박싱 배포의 경우 리소스 관리, 메모리 관리, CPU 관리 및 보안과 관련하여 고려해야 할 몇 가지 항목이 있습니다.
리소스 관리
Pod 샌드박싱을 사용하는 메모리 및 CPU 관리 동작은 일부 사용자에게 익숙하지 않을 수 있습니다. 이러한 고려 사항은 특히 더 크고 리소스가 중요한 워크로드의 경우 배포에서 리소스를 지정할 때 관련이 있습니다.
Kata 구성 요소
Kata 배포에는 일반적으로 배포되는 두 가지 구성 요소 패밀리가 있습니다. 호스트 구성 요소와게스트 구성 요소가 있습니다.
- 주요 호스트 구성 요소는Kata shim, 클라우드 하이퍼바이저 및 virtiofsd로 구성됩니다.
- Kata shim은 Pod VM 수명 주기를 관리합니다.
- 클라우드 하이퍼바이저 는 Kata shim에서 사용하는 VMM(Virtual Machine Monitor)입니다.
- virtiofsd 는 각 Pod VM과 해당 컨테이너 호스트 간에 파일을 공유하는 데 사용되는 디먼입니다.
- 주요 게스트 구성 요소 에는 사용자의 워크로드, Pod VM 커널 및 Kata 에이전트가 포함됩니다.
- Kata 에이전트는 Pod VM 내의 컨테이너를 관리합니다.
메모리 관리
Kata Pod를 사용하면 워크로드를 호스트하는 Pod VM의 메모리 양을 지정할 수 있습니다. Pod에 충분한 리소스가 있지만 사용되지 않는 메모리가 Pod에 할당되지 않도록 값을 적절하게 구성하는 것이 중요합니다.
Pod VM 메모리 크기
컨테이너를 실행하는 각 Pod VM에 할당된 메모리 양이 있습니다. 이 VM 메모리 크기는 Kata 게스트 구성 요소를 실행하는 데 필요한 모든 메모리를 포함합니다. 사용자는 kata 에이전트 또는 VM 커널과 같은 다른 게스트 구성 요소의 소비를 고려하기 위해 워크로드의 예상 소비를 초과하는 추가 메모리를 버퍼링하는지 확인해야 합니다. 이 문서의 뒷부분에서 일반적인 메모리 값에 대한 예제가 제공됩니다.
Pod VM 메모리 크기는 사용자가 지정한 Kubernetes Pod 메모리 제한 과 동일합니다. 사용자는 Pod 메모리 제한을 변경하여 값을 변경할 수 있습니다. 값을 지정하지 않으면 기본 크기인 512Mi가 적용됩니다. Pod가 시작되면 크기가 변하지 않고 고정됩니다.
Pod VM 메모리 크기가 증가함에 따라 런타임 클래스 메모리 오버헤드가 함께 증가해야 합니다.
런타임 클래스 메모리 오버헤드
Pod 샌드박싱 워크로드에는 리소스에 대한 기본 오버헤드와 함께 제공되는 기본 kata 런타임 클래스(kata-vm-isolation)가 함께 제공됩니다. 리소스 할당량을 더 세밀하게 제어하려는 사용자는 특정 리소스 오버헤드 를 사용하여 사용자 지정 런타임 클래스를 설정할 수 있습니다. 이렇게 할 때 사용자는 런타임 클래스의 메모리 오버헤드 값이 kata 배포의 호스트 구성 요소 에 대해 예상되는 모든 사용량을 포함하는 것으로 충분한지 확인해야 합니다. 런타임 클래스 메모리 오버헤드는 게스트 구성 요소의 예상 메모리 소비를 고려할 필요가 없습니다.
RuntimeClass 매니페스트의 overhead 필드를 통해 특수 런타임을 만들고 런타임 클래스의 메모리 오버헤드를 지정할 수 있습니다.
예를 들어 사용량이 더 적을 것으로 예상되는 워크로드에 대한 런타임을 만들려고 한다고 가정해 보겠습니다.
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: small-kata-pods
handler: kata
overhead:
podFixed:
memory: "120Mi"
오버헤드를 지정하는 것은 필요하지 않으며 워크로드에 대해 따로 설정되는 리소스를 더 세부적으로 제어하려는 경우 제안됩니다. 기본 kata-vm-isolation 런타임 클래스를 사용하고 YAML에서 오버헤드를 지정하지 않으면 Pod VM 크기의 오버헤드는 기본적으로 512Mi로 설정되고 런타임 클래스 오버헤드는 기본값인 600Mi입니다. 이 기본 런타임 오버헤드는 기본 Pod VM 크기(512Mi)와 이러한 VM 크기(~88Mi)에 대한 호스트 구성 요소에 필요한 대략적인 메모리로 계산됩니다.
사용자 워크로드
사용자가 Kata 워크로드를 배포할 때, 최대 구성된 Pod VM 메모리 크기에서 Kata 에이전트 및 게스트 VM 커널과 같은 다른 게스트 구성 요소를 제외한 메모리를 사용할 수 있습니다.
이러한 구성 요소에서 사용하는 메모리의 근사치를 얻으려면 다음을 수행합니다.
- Pod VM에 연결하여(
kubectl exec또는kubectl debug을 통해) Pod 내부에서 셸을 엽니다. -
free명령을 실행합니다. - 출력에서 "사용된" 열을 검사하여 게스트 커널/카타 에이전트가 사용하는 메모리를 파악합니다.
메모리 cgroups
Kata Pod가 실행되도록 예약되면 kubelet은 Pod를 메모리 cgroup에 할당합니다. 이렇게 하면 cgroup Pod의 메모리 제한/요청을 적용하여 사용자가 Pod에 사용할 수 있는 리소스 할당량을 정의할 수 있습니다.
메모리 cgroup내에는 고려해야 할 두 가지 중요한 필드가 있습니다.
-
memory.current는 호스트 구성 요소 및 Pod VM 메모리 크기가 할당하는 메모리의 바이트 수를 정의합니다. -
memory.max선택 사항으로, 사용자가 메모리 제한을 적용하려는 Pod의 memory.current 상한을 정의합니다.- kubelet은 이 값을 Pod의 메모리 제한과 런타임 클래스 메모리 오버헤드의 합계로 계산합니다.
언제든지 memory.current의 값이 memory.max을 초과하면, 메모리 압력이 감지될 경우 커널이 그 포드에서 OOMKill을 트리거할 수 있습니다.
참조 사용량 값
사용자는 이러한 값을 활용하여 일반적인 메모리 사용량 및 다양한 변수의 값에 대한 참조 역할을 할 수 있습니다. 128Mi 미만의 Pod VM 메모리 크기는 지원되지 않습니다.
| Pod VM 메모리 크기 | 런타임 클래스 오버헤드 | memory.current | memory.max | 호스트 구성 요소에 사용 가능한 여유 메모리 |
|---|---|---|---|---|
| 128Mi | 16Mi | 133Mi | 144Mi | 11Mi |
| 256Mi | 32Mi | 263Mi | 288Mi | 25Mi |
| 1기가바이트 | 128Mi | 1034Mi | 1152Mi | 118Mi |
| 2Gi | 256Mi | 2063Mi | 2304Mi | 241Mi |
| 4Gi | 374Mi | 4122Mi | 4470Mi | 348Mi |
| 8Gi | 512Mi | 8232Mi | 8704Mi | 472Mi |
| 32Gi | 640Mi | 32918Mi | 33408Mi | 490Mi |
| 64Gi | 768Mi | 65825Mi | 66304Mi | 479Mi |
| 96Gi | 896Mi | 98738Mi | 99200Mi | 462Mi |
| 128Gi | 1기가바이트 | 131646Mi | 132096Mi | 450Mi |
CPU 관리
메모리와 비슷한 맥락에서 Kata 워크로드에 CPU 리소스를 할당할 수도 있습니다. 이렇게 하는 것이 좋습니다. Kata Pod에 대한 CPU 제한을 선언하지 않으면 Kata 호스트 구성 요소는 노드에서 사용할 수 있는 모든 CPU 용량을 사용할 수 있습니다.
CPU 예약
Kata 워크로드에 대한 CPU를 예약할 때 설정할 수 있는 두 개의 필드가 있습니다.
- 런타임 클래스 CPU 오버헤드
- Pod CPU 제한
두 값 중 하나 이상을 지정하면 컨트롤 플레인은 워크로드에 대해 노드에 지정된 CPU 수를 예약합니다. 동일한 노드의 다른 Pod는 이 예약된 용량에 액세스할 수 없습니다.
Pod CPU 제한
애플리케이션의 매니페스트에서 Pod CPU 제한을 선언할 수 있습니다. 지정된 Pod CPU 제한은 연결된 Pod VM의 컨테이너에서 사용할 수 있는 CPU의 제한을 정의합니다.
Pod CPU 제한에 CPU의 분수를 지정하면 해당 분수는 다음 정수로 반올림됩니다. 반올림된 번호는 Pod VM에 할당된 vCPU의 수가 되지만 cgroup Pod CPU 제한에 지정된 분수만 사용하도록 워크로드를 제한합니다.
숫자가 선언되지 않은 경우 노드에서 용량을 사용할 수 있는 경우 하나의 vCPU가 Pod VM에 할당됩니다. Kata 호스트 구성 요소의 CPU 사용량에는 제한이 없습니다.
런타임 클래스 CPU 오버헤드
Kata 호스트 구성 요소에 대한 일부 노드 용량을 선제적으로 예약하려면 런타임 클래스 오버헤드를 지정해야 합니다.
런타임 클래스에서 메모리 오버헤드를 overhead 매니페스트의 RunTimeClass 필드를 통해 지정할 수 있습니다.
예를 들면 다음과 같습니다.
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: custom-kata-runtime
handler: kata
overhead:
podFixed:
cpu: "250m"
모범 사례
메모리 관리
- Pod VM 메모리 크기(매니페스트에서 정의
limits.memory됨)와 모든 배포에 적합한 리소스 할당량을 지정해야 합니다.- VM이 시작되기 전에 일부 노드 용량이 Pod VM에 예약되어 있는지 확인하려면 0이 아닌 Pod 요청을 사용해야 합니다. 요청은 Pod VM 및 해당 VM에서 실행될 것으로 예상되는 컨테이너를 고려해야 합니다.
- 해당 구성 요소가 시작되기 전에 Kata 호스트 구성 요소에 대한 일부 노드 용량을 예약하려는 경우 0이 아닌 런타임 클래스 오버헤드 를 사용해야 합니다.
- Pod 워크로드가 특히 리소스가 부족한 것으로 예상되는 경우 Pod VM에 따라 제한을 지정하여 워크로드에 사용할 수 있는 충분한 리소스가 있는지 확인할 수 있습니다.
- 적절한 런타임 클래스 메모리 오버헤드를 선언하여 호스트 구성 요소에 충분한 메모리를 제공하지만 사용하지 않는 메모리를 할당하지 않도록 너무 많이 걸리지 않습니다.
CPU 관리
노드에 일반적으로 사용 가능 CPU 용량이 많은 경우 이러한 예약이 필요하지 않을 수 있습니다.
노드가 일반적으로 CPU 사용량으로 인해 한도에 도달하는 경우, 0이 아닌 예약을 통해 Pod가 더 안정적으로 실행될 수 있습니다.
- Pod CPU 요청을 활용하여 일부 CPU 노드 용량이 Kata 호스트 구성 요소에 대해 예약되었는지 확인할 수 있습니다. 특정 워크로드에 대한 예약된 용량은 노드의 다른 워크로드에서 사용할 수 없습니다 .
인프라에서 수용할 수 있는 CPU 요청을 지정해야 합니다. 사용 가능한 용량이 0에 가깝게 실행되거나 요청이 너무 큰 경우 워크로드가 시작되지 않을 수 있습니다.
CPU 요청을 CPU 제한에 맞춥니다. Kata shim에는 요청에 대한 표시 여부가 없습니다. 따라서 CPU 제한이 선언되지 않은 경우 Pod VM은 하나의 vCPU로 제한됩니다. 요청 값에 대한 가시성이 있는 Kata 호스트 구성 요소는 요청된 CPU 수의 나머지 부분을 사용하며 CPU 사용량에 제한이 없습니다.
특정 워크로드에 대한 예약된 용량은 노드의 다른 워크로드에서 사용할 수 없습니다 .
예제 선언
| 런타임 클래스 CPU 오버헤드 | Pod CPU 요청/제한 | 예상되는 동작 |
|---|---|---|
| 1 | 1 | 컨트롤 플레인은 노드에 두 개의 CPU를 예약합니다. Pod VM은 하나의 CPU를 가져오고 Pod의 컨테이너는 최대 하나의 vCPU 용량을 사용할 수 있습니다. Kata 호스트 구성 요소와 Pod VM은 노드의 예약된 용량에서 최대 2개의 CPU를 사용할 수 있습니다. |
| 1 | 2.5 | 컨트롤 플레인은 노드에 3.5 CPU를 예약합니다. Pod VM은 3개의 vCPU를 가져오지만 Pod VM의 컨테이너는 최대 2.5개의 vCPU 용량을 사용할 수 있습니다. Kata 호스트 구성 요소와 Pod VM은 노드의 예약된 용량에서 최대 3.5 CPU를 사용할 수 있습니다. |
| None | 1 | 컨트롤 플레인은 노드에 하나의 CPU를 예약합니다. Pod VM은 하나의 vCPU를 가져오고 Pod VM의 컨테이너는 최대 하나의 vCPU 용량을 사용할 수 있습니다. Kata 호스트 구성 요소와 Pod VM은 노드의 예약된 용량에서 최대 하나의 CPU를 사용할 수 있습니다. CPU 요청으로 인해 Pod VM에서 항상 하나의 CPU를 사용할 수 있습니다. |
| 1 | None | 컨트롤 플레인은 노드에 하나의 CPU를 예약합니다. Pod VM은 하나의 vCPU를 가져오고 Pod VM의 컨테이너는 최대 하나의 vCPU 용량을 사용할 수 있습니다. kata 호스트 구성 요소 및 Pod VM은 노드에서 사용할 수 있는 모든 CPU 용량을 사용할 수 있습니다. 오버헤드 예약으로 인해 항상 하나 이상의 CPU를 사용할 수 있습니다. |
Security
Pod Sandboxing은 사용자에게 워크로드를 다른 워크로드 및 호스트로부터 격리할 수 있는 강력한 옵션을 제공합니다. 그럼에도 불구하고 고려해야 할 중요한 보안 문제가 있습니다.
권한 있는 Pod
권한 있는 Pod가 필요할 수 있는 시나리오가 있습니다. 사용자는 권한 있는 Pod를 스핀업할 수 있지만 Pod에 연결된 호스트 디바이스는 없습니다.
권한 있는 컨테이너를 사용하면 게스트 VM의 루트 액세스로 이어지지만 호스트에서 격리된 상태로 유지됩니다.
Pod 샌드박스 환경에서도 권한이 있는 Pod는 꼭 필요할 때만 사용해야 합니다. 권한 있는 Pod는 신뢰할 수 있는 사용자가 계속 관리해야 합니다.
호스트 경로 스토리지 볼륨
hostPath 볼륨을 Kata Pod에 탑재할 수 있습니다. Pod Sandboxing에서 볼륨을 사용하면 hostPath Kata가 제공하는 격리를 잠재적으로 훼손할 수 있습니다. 호스트 파일 시스템의 일부가 컨테이너에 직접 노출되기 때문에 잠재적인 공격 벡터가 열립니다.
업스트림에서 발생하는 경고는 Pod 샌드박싱과도 관련이 있는 것으로 간주되어야 합니다.
몇 가지 예외가 있습니다. 아래 /dev 파일은 호스트 시스템 대신 게스트 시스템에서 컨테이너에 탑재됩니다. 이 경로가 작동하기 위해 탑재되어야 하는 상황에서 Pod 격리를 유지하는 데 도움이 됩니다.
경고
필요한 경우가 아니면 hostPath 스토리지 볼륨을 사용하지 않는 것이 좋습니다.
Azure Policy를 통해 hostPath 차단
Azure Policy 를 사용하면 사용자가 중앙 집중식으로 일관된 방식으로 클러스터 구성 요소에 대규모 적용 및 보호 기능을 적용할 수 있습니다.
모범 사례를 적용하는 AKS에 대한 내장된 정책 집합이 있습니다. 사용자는 이러한 정책 중 하나를 활용하여 hostPaths를 탑재하려는 배포를 차단할 수 있습니다.
다음 단계
준비가 되면 AKS에 Pod 샌드박싱을 배포하는 방법을 알아봅니다.