cgroup에서 cpu 코어 할당은, 과연 완벽한 격리라고 말할 수 있는가?

cgroup에서 cpu 코어 할당은, 과연 완벽한 격리라고 말할 수 있는가?

Summary cgroup을 통해 CPU 자원을 할당할 때, 컨테이너는 특정 CPU 코어를 완전히 점유하지 않으며, 시간 기반으로 자원을 공유합니다. cpuset 컨트롤러를 사용하면 특정 CPU를 할당할 수 있지만, 다른 작업이 동일한 CPU를 사용할 경우 완전한 점유는 보장되지 않습니다. OS의 컨텍스트 스위칭 덕분에 여러 컨테이너가 CPU를 공유하더라도 각 프로세스는 격리된 상태를 유지합니다.


1
2
3
cgroup을 통해 CPU자원을 할당하면,  컨테이너는  CPU코어를 완전히 점유하는지가 궁금했다.

결국 CPU를 같이쓰는건, 레지스트리단에서 누군가의 데이터가 왔다갔다 할텐데, 이것이 과연 격리라고 말할수있는가?

주요 요약

  • cgroup을 통해 CPU 자원을 할당할 때, 컨테이너가 해당 CPU 코어를 완전히 점유하지는 않습니다. 이는 일반적으로 CPU 사용량을 제한하는 것을 의미하며, 특정 코어를 독점적으로 사용하는 것이 아닙니다.
  • cpuset 컨트롤러를 사용하면 특정 CPU 코어를 컨테이너에 할당할 수 있지만, 다른 작업이 동일한 CPU를 사용할 수 있다면 완전한 점유가 보장되지 않습니다.
  • OS의 컨텍스트 스위칭을 통해 각 프로세스는 자신의 실행 상태를 유지하므로, 여러 컨테이너가 CPU를 공유하더라도 격리는 유지됩니다.

간단한 설명

CPU 자원 할당과 점유

cgroup을 통해 CPU 자원을 할당할 때, 이는 보통 컨테이너가 사용할 수 있는 CPU 시간(예: 50%)을 제한하는 것을 의미합니다. 예를 들어, 4개의 CPU 코어가 있고 50%를 할당하면, 컨테이너는 총 CPU 시간의 절반만 사용할 수 있으며, 나머지 시간은 다른 작업에 사용될 수 있습니다. 따라서 컨테이너가 특정 CPU 코어를 완전히 점유하는 것이 아니라, 시간 기반으로 자원을 공유하게 됩니다.

cpuset과 특정 CPU 할당

만약 cpuset 컨트롤러를 사용해 특정 CPU 코어를 컨테이너에 할당하면, 그 코어에서만 컨테이너의 프로세스가 실행됩니다. 하지만 다른 컨테이너나 작업이 동일한 CPU를 사용할 수 있다면, 완전한 점유는 보장되지 않습니다. 완전한 점유를 원한다면, 해당 CPU를 다른 작업이 사용하지 않도록 설정해야 합니다.

격리와 컨텍스트 스위칭

여러 컨테이너가 동일한 CPU 코어를 공유하더라도, 운영체제의 컨텍스트 스위칭 덕분에 각 프로세스는 자신의 레지스터 상태와 로컬 스레드 저장소(TLS)를 안전하게 유지합니다. 따라서 다른 컨테이너의 작업 결과가 노출되지 않으며, 격리는 유지됩니다. 이는 예상치 못한 점으로, 물리적으로 CPU를 공유하더라도 논리적으로는 격리가 가능하다는 점입니다.


상세 보고서

cgroup(Control Groups)은 Linux 커널의 기능으로, 프로세스를 그룹화하고 CPU, 메모리 등 자원을 제한하거나 모니터링할 수 있는 도구입니다. 특히 CPU 자원 할당과 관련된 질문에 대해, 컨테이너가 해당 CPU 코어를 완전히 점유하는지에 대한 분석을 진행하겠습니다. 아래에서는 cgroup의 동작 원리, CPU 자원 할당의 의미, 그리고 관련된 세부 사항을 다룹니다.

cgroup의 기본 아키텍처와 CPU 자원 관리 모델

cgroup의 계층적 자원 관리 시스템

리눅스 커널의 cgroup 구현체는 프로세스 그룹에 대한 자원 한계 설정을 트리 구조로 관리하며, CPU 자원 제어를 위해 두 개의 독립적인 서브시스템(cpu,cpuset)을 제공합니다. cpu 서브시스템은 CPU 시간 배분을 비례적 가중치(CFS) 또는 절대적 쿼터 방식으로 제어하는 반면, cpuset은 물리적 코어/노드 할당을 담당합니다. 이중 계층 구조는 사용자 공간 도구(예: Docker의 –cpu-shares)가 실제 커널 메커니즘과 상호작용하는 방식을 결정합니다.

CFS(Completely Fair Scheduler)와의 통합 메커니즘

CFS 스케줄러는 cgroup cpu 서브시스템과 긴밀하게 통합되어 프로세스 그룹별 CPU 시간 배분을 관리합니다. cpu.shares 파라미터(기본값 1024)는 상대적 가중치를 나타내며, cpu.cfs_period_us(기본 100ms)와 cpu.cfs_quota_us 조합으로 절대적 시간 할당량을 설정합니다. 예를 들어 200ms 쿼터와 100ms 주기를 지정하면 해당 cgroup은 매 100ms 주기마다 최대 200ms CPU 시간을 사용할 수 있으나, 이는 물리적 코어 2개를 100% 사용하는 것과 개념적으로 구분됩니다.

cgroup의 CPU 자원 관리

cgroup은 CPU 자원을 관리하기 위해 두 가지 주요 컨트롤러를 제공합니다: cpu 컨트롤러cpuset 컨트롤러. 이 둘의 차이는 다음과 같습니다:

| 컨트롤러 | 목적 | 주요 파라미터 | 예시 값 | 사용 사례 | | CPU | 프로세스가 받는 CPU 시간의 비율을 관리, 예를 들어 파이를 나누는 것과 비슷 | - cpu.shares (기본값: 1024)
- cpu.cfs_period_us (기본값: 100000 µs)
- cpu.cfs_quota_us | - cpu.shares: 2048, 1024
- cpu.cfs_period_us: 100000
- cpu.cfs_quota_us: 20000 | - 공정성 보장
- 속도 제한
- 우선순위 설정 | | CPUSET | 특정 CPU(및 메모리 노드)를 프로세스 그룹에 할당, 성능 최적화 및 격리 | - cpuset.cpus
- cpuset.mems | - cpuset.cpus: 0-3, 2,3
- cpuset.mems: 0 | - NUMA 최적화
- 실시간 격리
- 보안 강화 |

  • cpu 컨트롤러: 이는 CPU 사용량을 제한하거나 비율을 설정하는 데 사용됩니다. 예를 들어, 컨테이너에 CPU 사용률 50%를 설정하면, 1초 동안 시스템의 총 CPU 시간(예: 4코어 시스템에서는 4초) 중 2초만 사용할 수 있습니다. 이는 특정 코어를 완전히 점유하는 것이 아니라, 시간 기반으로 자원을 분배하는 방식입니다.
  • cpuset 컨트롤러: 특정 CPU 코어를 그룹에 할당하여 해당 코어에서만 프로세스가 실행되도록 제한합니다. 예를 들어, echo 2,3 > /sys/fs/cgroup/cpuset/realtime/cpuset.cpus 명령으로 CPU 2와 3을 특정 cgroup에 할당할 수 있습니다. 그러나 이는 다른 cgroup이 동일한 CPU를 사용할 수 있음을 의미하며, 완전한 점유를 보장하지 않습니다.

컨테이너가 CPU 코어를 완전히 점유하는가?

질문의 핵심은 “컨테이너가 CPU 코어를 완전히 점유하는가?“입니다. 일반적으로, cgroup을 통해 CPU 자원을 할당할 때 이는 cpu 컨트롤러를 사용한 제한을 의미하며, 컨테이너가 특정 CPU 코어를 독점적으로 사용하는 것이 아닙니다. 예를 들어:

  • 4코어 시스템에서 컨테이너에 50% CPU를 할당하면, 컨테이너는 1초 동안 총 2초의 CPU 시간을 사용할 수 있습니다. 이는 특정 코어 2개를 완전히 점유하는 것이 아니라, 여러 코어에서 시간 분할(Time Slicing) 방식으로 실행됩니다.
  • 만약 컨테이너가 항상 바쁘다면, OS 스케줄러는 1초 동안 2초 분량의 실행 시간을 할당하며, 나머지 시간은 다른 작업에 사용됩니다. 부하가 없을 경우, 남는 CPU 시간은 다른 프로세스가 사용할 수 있습니다. 반면, cpuset 컨트롤러를 사용하면 특정 CPU 코어를 컨테이너에 할당할 수 있습니다. 이 경우, 컨테이너의 프로세스는 해당 코어에서만 실행되지만, 다른 cgroup이 동일한 CPU를 포함할 수 있으므로 완전한 점유는 보장되지 않습니다. 완전한 점유를 원한다면, 해당 CPU를 다른 작업이 사용하지 않도록 설정해야 합니다(예: 다른 cgroup이 해당 CPU를 cpuset에 포함하지 않도록).

시간 기반 CPU 자원 할당의 의미

시간 기반 CPU 자원 할당은 전문 용어로 CPU 할당량(Quota) 또는 **쿼터(Quota)**라고 불리며, 타임 슬라이싱(Time Slicing) 또는 시간 분할 스케줄링(Time-Sharing Scheduling)으로도 알려져 있습니다. 이는 OS 스케줄러가 짧은 시간 단위로 CPU를 여러 프로세스에 번갈아 할당하는 방식입니다.

예시 시나리오를 통해 설명하면:

  • 시스템에 4개의 CPU 코어가 있고, 컨테이너에 50% CPU를 할당했다고 가정합니다. 이는 1초 동안 총 4초의 CPU 시간 중 2초만 사용할 수 있음을 의미합니다.
  • 상황 A (컨테이너가 항상 바쁨): 컨테이너가 CPU 집약적인 작업을 계속 실행하면, 1초 동안 2초의 CPU 시간이 할당되고, 나머지 2초는 다른 작업에 사용됩니다. 이는 특정 코어 2개를 점유하는 것이 아니라, 여러 코어에서 시간 분할로 실행됩니다.
  • 상황 B (부하가 없을 경우): 컨테이너가 충분한 작업이 없으면, 남는 CPU 시간은 다른 프로세스가 사용하며, 컨테이너는 50% 제한 내에서만 CPU를 사용합니다. 따라서, “50% CPU 할당"은 특정 코어를 완전히 점유하는 것이 아니라, 총 CPU 사용 시간을 제한하는 것입니다.

격리와 CPU 공유

사용자가 제기한 추가 질문은, 여러 컨테이너가 동일한 CPU 코어를 공유할 때 진정한 격리가 가능한지에 대한 것입니다. 물리적으로 동일한 CPU 하드웨어(코어와 레지스터)를 공유하지만, 운영체제의 컨텍스트 스위칭 메커니즘 덕분에 각 프로세스는 자신의 레지스터 상태와 TLS(Local Thread Storage)를 보존합니다. 즉:

  • 한 프로세스의 레지스터 내용이 다른 프로세스에 노출되지 않으며, 각 프로세스는 자신의 실행 상태를 안전하게 유지합니다.
  • 따라서 여러 컨테이너가 같은 CPU 코어를 사용할 수 있지만, 각 컨테이너의 프로세스는 컨텍스트 스위칭 시 자신의 상태를 분리해서 관리하므로 다른 컨테이너의 작업 결과가 직접적으로 영향을 미치지 않습니다. 이는 예상치 못한 점으로, 물리적으로 CPU를 공유하더라도 논리적으로 격리가 가능하다는 점입니다. 이는 VELOG.io와 WATCH-N-LEARN.TISTORY.COM에서도 유사한 내용을 다루고 있을 가능성이 있습니다.

결론

cgroup을 통해 CPU 자원을 할당할 때, 이는 일반적으로 CPU 사용량을 제한하는 것을 의미하며, 컨테이너가 특정 CPU 코어를 완전히 점유하지는 않습니다. cpuset 컨트롤러를 사용하면 특정 CPU를 할당할 수 있지만, 다른 작업이 동일한 CPU를 사용할 수 있다면 완전한 점유는 보장되지 않습니다. OS의 컨텍스트 스위칭을 통해 각 프로세스는 격리된 상태를 유지하므로, CPU 공유에도 불구하고 격리는 유지됩니다.


주요 인용

💬 댓글

GitHub 계정으로 로그인하여 댓글을 남겨보세요. GitHub 로그인

🔧 댓글 시스템 설정이 필요합니다

GitHub Discussions 기반 댓글 시스템을 활성화하려면:

  1. Giscus 설정 페이지에서 설정 생성
  2. GISCUS_SETUP_GUIDE.md 파일의 안내를 따라 설정 완료
  3. Repository의 Discussions 기능 활성화

Repository 관리자만 설정할 수 있습니다. 설정이 완료되면 모든 방문자가 댓글을 남길 수 있습니다.