
지난번에 스토리지에 대한 제한 및 격리를 진행했습니다. 이번에는 CPU와 RAM에 대한 제한과 격리 작업을 진행해보겠습니다.
안전한 멀티 테넌시 : 특정 테넌트의 코드가 무한 루프에 빠져 CPU를 점유하거나, 메모리 누수가 발생해도 다른 테넌트와 마스터 노드의 동작에 영향을 주지 않아야 함사양 정의 : t2.micro 인스턴트처럼 1 vCPU, 1GiB RAM 수준의 리소스 프로파일을 테넌트 네임스페이스에 강제함ResourceQuota (총량)LimitRange (개별)📌 자원 제한의 기준 Requests 와 Limits
💡 라즈베리파이는 저전력 장치이기에,, 특정 테넌트에서 OOM이 발생하게 될 경우 노드 전체가 멈추는 Freeze 상황에 놓이기 쉽습니다. 때문에
limits.memory설정이 필수적입니다!
Requests (보장량)
- 파드가 실행되기 위해 최소한으로 필요한 자원
- K8s 스케줄러는 노드에 보장량 만큼의 여유 공간이 있을 때만 파드를 배치함
Limits (상한선)
- 파드가 최대로 사용할 수 있는 자원
CPU: Limit을 넘으면 스로틀링(Throttling)이 발생하여 속도가 느려지지만 파드가 죽지는 않음Memory: Limit 을 넘으면 커널이 파드를 즉시 종료시킴.(OOM Kill)
- → Memory 는 압축할 수 없는 자원이기 때문
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: tenant-alpha
spec:
hard:
requests.cpu: "500m" # 0.5 코어 보장
requests.memory: "512Mi" # 512MiB 보장
limits.cpu: "1000m" # 최대 1 코어 (1000m = 1 vCPU)
limits.memory: "1Gi" # 최대 1GiB (t2.micro 급)
apiVersion: v1
kind: LimitRange
metadata:
name: compute-limit-range
namespace: tenant-alpha
spec:
limits:
- type: Container
default: # Limit 미설정 시 자동 부여
cpu: "500m"
memory: "512Mi"
defaultRequest: # Request 미설정 시 자동 부여
cpu: "200m"
memory: "256Mi"
max: # 개별 컨테이너가 가질 수 있는 최대치
cpu: "800m"
memory: "800Mi"
kubectl apply -f tenant-compute-quota.yaml
kubectl apply -f tenant-compute-limit.yaml
apiVersion: v1
kind: Pod
metadata:
name: limit-test-pod
namespace: tenant-alpha
spec:
containers:
- name: nginx
image: nginx
kubectl apply -f test-pod.yaml
kubectl get pod limit-test-pod -n tenant-alpha -o yaml
이제 테넌트가 CPU와 RAM을 마음껏 사용해도(제한된 범위 내에서) 다른 테넌트에 영향을 주지 않게 되었습니다. 리소스에 대한 제한과 격리는 잘 되었습니다만, 다른 테넌트에 네트워크로 접속해서 데이터를 훔쳐보는(??) 상황은 아직 처리를 안 한 것 같습니다. 다음에는 Zero-Trust Network Policy 를 통해 네트워크 통신까지 제한하는 작업을 해보겠습니다.