기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
systemd를 사용하여 AL2023에서 프로세스 리소스 사용 제한
Amazon Linux 2023(AL2023)에서는 systemd를 사용하여 프로세스 또는 프로세스 그룹에서 사용할 수 있는 리소스를 제어하는 것이 좋습니다. systemd 사용은 cgroups를 수동으로 조작하거나, 이전에는 타사 EPEL 리포지토리의 Amazon Linux에서만 사용할 수 있었던 cpulimit 같은 유틸리티의 사용을 대체할 수 있는 강력하고 간편한 방법입니다.
자세한 내용은 systemd.resource-controlsystemd 설명서 또는 AL2023 인스턴스의 systemd.resource-control에 대한 man 페이지를 참조하세요.
아래 예제에서는 stress-ng CPU 스트레스 테스트(stress-ng 패키지)를 사용하여 CPU 사용량이 많은 애플리케이션을 시뮬레이션하고, memcached를 사용하여 메모리 사용량이 많은 애플리케이션을 시뮬레이션합니다.
아래 예제에서는 일회성 명령에 CPU 제한을 적용하고 서비스에 메모리 제한을 적용하는 방법을 다룹니다. systemd에서 제공하는 대부분의 리소스 제약 조건은 systemd가 프로세스를 실행할 모든 위치에서 사용할 수 있으며 여러 개를 동시에 사용할 수 있습니다. 아래 예제는 설명을 위한 단일 제약으로 제한됩니다.
일회성 명령 실행을 위한 systemd-run을 사용한 리소스 제어
일반적으로 시스템 서비스와 연결되지만 systemd는 루트 사용자가 아닌 사용자가 서비스를 실행하거나 타이머를 예약하거나 일회성 프로세스를 실행하는 데도 사용할 수 있습니다. 다음 예제에서는 stress-ng를 예제 애플리케이션으로 사용합니다. 첫 번째 예제에서는 ec2-user 기본 계정에서 systemd-run을 사용하여 실행하고, 두 번째 예제에서는 CPU 사용량에 제한을 둡니다.
예 명령줄에서 systemd-run을 사용하여 리소스 사용량을 제한하지 않고 프로세스를 실행합니다.
-
stress-ng패키지를 예제에 사용할 예정이므로 해당 패키지가 설치되어 있는지 확인합니다.[ec2-user ~]$sudo dnf install -ystress-ng -
사용 가능한 CPU 양을 제한하지 않고
systemd-run으로 10초 CPU 스트레스 테스트를 실행합니다.[ec2-user ~]$systemd-run --user --tty --wait --property=CPUAccounting=1stress-ng --cpu 1 --timeout 10Running as unit: run-u6.service Press ^] three times within 1s to disconnect TTY. stress-ng: info: [339368] setting to a 10 second run per stressor stress-ng: info: [339368] dispatching hogs: 1 cpu stress-ng: info: [339368] successful run completed in 10.00s Finished with result: success Main processes terminated with: code=exited/status=0 Service runtime: 10.068s CPU time consumed: 9.060s--user옵션은systemd-run에 로그인한 사용자로 명령을 실행하도록 지시하고,--tty옵션은 TTY가 연결되어 있음을 의미하며,--wait는 서비스가 완료될 때까지 기다리는 것을 의미하고,--property=CPUAccounting=1옵션은systemd-run에 프로세스를 실행하는 데 사용되는 CPU 시간을 기록하도록 지시합니다.--property명령줄 옵션을 사용하여systemd.unit구성 파일에서 구성할 수 있는systemd-run설정을 전달할 수 있습니다.
CPU에 로드를 배치하라는 지시를 받으면 stress-ng 프로그램은 실행을 요청하는 기간 동안 사용 가능한 모든 CPU 시간을 사용하여 테스트를 수행합니다. 실제 애플리케이션의 경우 프로세스의 총 런타임에 제한을 두는 것이 좋습니다. 아래 예제에서는 systemd-run을 사용하여 최대 기간 제한보다 더 오래 stress-ng를 실행하도록 요청합니다.
예 명령줄에서 systemd-run을 사용하여 프로세스를 실행하고 CPU 사용량을 1초로 제한합니다.
-
이 예제를 실행하려면
stress-ng가 설치되어 있는지 확인합니다. -
LimitCPU속성은 이 프로세스가 사용할 수 있는 CPU의 최대 시간을 제한하는ulimit -t와 동일합니다. 이 경우 10초 스트레스 실행을 요청하고 CPU 사용량을 1초로 제한하므로 명령은SIGXCPU신호를 수신하고 실패합니다.[ec2-user ~]$systemd-run --user --tty --wait --property=CPUAccounting=1 --property=LimitCPU=1stress-ng --cpu 1 --timeout 10Running as unit: run-u12.service Press ^] three times within 1s to disconnect TTY. stress-ng: info: [340349] setting to a 10 second run per stressor stress-ng: info: [340349] dispatching hogs: 1 cpu stress-ng: fail: [340349] cpu instance 0 corrupted bogo-ops counter, 1370 vs 0 stress-ng: fail: [340349] cpu instance 0 hash error in bogo-ops counter and run flag, 3250129726 vs 0 stress-ng: fail: [340349] metrics-check: stressor metrics corrupted, data is compromised stress-ng: info: [340349] unsuccessful run completed in 1.14s Finished with result: exit-code Main processes terminated with: code=exited/status=2 Service runtime: 1.201s CPU time consumed: 1.008s
더 일반적으로는 특정 프로세스에서 사용할 수 있는 CPU 시간 비율을 제한할 수 있습니다. 아래 예제에서는 stress-ng에서 사용할 수 있는 CPU 시간의 비율을 제한합니다. 실제 서비스의 경우 사용자 요청을 처리하는 프로세스에 리소스를 자유롭게 두기 위해 백그라운드 프로세스에서 사용할 수 있는 최대 CPU 시간 비율을 제한하는 것이 좋습니다.
예 하나의 CPU에서 프로세스를 CPU 시간의 10%로 제한하는 데 systemd-run 사용
-
이 예제를 실행하려면
stress-ng가 설치되어 있는지 확인합니다. -
CPUQuota속성을 사용하여systemd-run에 실행할 명령의 CPU 사용량을 제한하도록 지시합니다. 프로세스가 실행할 수 있는 시간만 제한하는 것이 아니라 사용할 수 있는 CPU 양을 제한합니다.[ec2-user ~]$systemd-run --user --tty --wait --property=CPUAccounting=1 --property=CPUQuota=10%stress-ng --cpu 1 --timeout 10Running as unit: run-u13.service Press ^] three times within 1s to disconnect TTY. stress-ng: info: [340664] setting to a 10 second run per stressor stress-ng: info: [340664] dispatching hogs: 1 cpu stress-ng: info: [340664] successful run completed in 10.08s Finished with result: success Main processes terminated with: code=exited/status=0 Service runtime: 10.140s CPU time consumed: 1.014sCPU 회계를 통해 서비스가 10초 동안 실행되었지만 실제 CPU 시간 중 1초만 소비되었음을 알 수 있습니다.
CPU, 메모리, 네트워킹 및 IO에 대한 리소스 사용을 제한하도록 systemd를 구성하는 방법에는 여러 가지가 있습니다. 포괄적인 설명서는 systemd.resource-controlsystemd 설명서 또는 AL2023 인스턴스의 systemd.resource-control에 대한 man 페이지를 참조하세요.
백그라운드에서 systemd는 cgroups 같은 Linux 커널의 기능을 사용하여 이러한 제한을 구현하는 동시에 수동으로 구성할 필요가 없도록 합니다. cgroup-v2용 Linux 커널 설명서cgroups 작동 방식에 대한 광범위한 세부 정보가 포함되어 있습니다.
systemd 서비스의 리소스 제어
시스템 리소스 사용을 제어하기 위해 systemd 서비스의 [Service] 섹션에 추가할 수 있는 몇 가지 파라미터가 있습니다. 여기에는 하드 제한과 소프트 제한이 모두 포함됩니다. 각 옵션의 정확한 동작은 systemd.resource-controlsystemd 설명서 또는 AL2023 인스턴스의 systemd.resource-control에 대한 man 페이지를 참조하세요.
일반적으로 사용되는 제한은 메모리 사용량에 대한 스로틀링 제한을 지정하는 MemoryHigh, 하드 상한(이에 도달하면 OOM 킬러가 간접 호출됨)을 설정하는 MemoryMax 및 CPUQuota(이전 섹션에서 설명)입니다. 고정된 숫자 대신 가중치와 우선순위를 구성할 수도 있습니다.
예 systemd를 사용하여 서비스에 대한 메모리 사용량 제한 설정
이 예제에서는 간단한 키-값 캐시인 memcached에 대한 하드 메모리 사용량 제한을 설정하고 전체 시스템이 아닌 해당 서비스에 대해 OOM 킬러가 간접 호출되는 방법을 보여줍니다.
-
먼저 이 예제에 필요한 패키지를 설치해야 합니다.
[ec2-user ~]$sudo dnf install -ymemcached libmemcached-awesome-tools -
memcached.service를 활성화한 다음memcached가 실행되도록 서비스를 시작합니다.[ec2-user ~]$sudo systemctl enablememcached.serviceCreated symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /usr/lib/systemd/system/memcached.service.[ec2-user ~]$sudo systemctl startmemcached.service -
memcached.service가 실행 중인지 확인합니다.[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Active: active (running) since Fri 2025-01-31 22:36:42 UTC; 1s ago Main PID: 356294 (memcached) Tasks: 10 (limit: 18907) Memory: 1.8M CPU: 20ms CGroup: /system.slice/memcached.service └─356294 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 22:35:36 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
memcached가 설치되고 실행 중이므로 일부 무작위 데이터를 캐시에 삽입하여 작동하는지 확인할 수 있습니다./etc/sysconfig/memcached에서CACHESIZE변수는 기본적으로 64로 설정되며, 이는 64메가바이트를 의미합니다. 최대 캐시 크기보다 더 많은 데이터를 캐시에 삽입하면 캐시를 채우고 일부 항목은memcached-tool을 사용하여 제거되며memcached.service가 약 64MB의 메모리를 사용하고 있음을 알 수 있습니다.[ec2-user ~]$for i in $(seq 1 150); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done[ec2-user ~]$memcached-tool localhost display# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM 2 120B 0s 1 0 no 0 0 0 39 512.0K 4s 63 126 yes 24 2 0[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Active: active (running) since Fri 2025-01-31 22:36:42 UTC; 7min ago Main PID: 356294 (memcached) Tasks: 10 (limit: 18907) Memory: 66.7M CPU: 203ms CGroup: /system.slice/memcached.service └─356294 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 22:36:42 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
MemoryMax속성을 사용하여memcached.service에 대한 하드 제한을 설정하며, 이 제한에 도달하면 OOM 킬러가 간접 호출됩니다. 재정의 파일에 추가하여 서비스에 대한 추가 옵션을 설정할 수 있습니다. 이 작업은/etc/systemd/system/memcached.service.d/override.conf파일을 직접 편집하거나systemctl의edit명령을 사용하여 대화식으로 수행할 수 있습니다.[ec2-user ~]$sudo systemctl editmemcached.service아래를 재정의에 추가하여 서비스에 대한 메모리 하드 제한을 32MB로 설정합니다.
[Service] MemoryMax=32M -
systemd에 구성을 다시 로드하도록 지시[ec2-user ~]$sudo systemctl daemon-reload -
이제
memcached.service가 32MB의 메모리 제한으로 실행 중인지 확인합니다.[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Drop-In: /etc/systemd/system/memcached.service.d └─override.conf Active: active (running) since Fri 2025-01-31 23:09:13 UTC; 49s ago Main PID: 358423 (memcached) Tasks: 10 (limit: 18907) Memory: 1.8M (max: 32.0M available: 30.1M) CPU: 25ms CGroup: /system.slice/memcached.service └─358423 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 23:09:13 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
서비스는 32MB 미만의 메모리를 사용하는 동안 정상적으로 작동하며, 32MB 미만의 임의 데이터를 캐시에 로드한 다음 서비스 상태를 확인하여 확인할 수 있습니다.
[ec2-user ~]$for i in $(seq 1 30); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Drop-In: /etc/systemd/system/memcached.service.d └─override.conf Active: active (running) since Fri 2025-01-31 23:14:48 UTC; 3s ago Main PID: 359492 (memcached) Tasks: 10 (limit: 18907) Memory: 18.2M (max: 32.0M available: 13.7M) CPU: 42ms CGroup: /system.slice/memcached.service └─359492 /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1 Jan 31 23:14:48 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. -
이제 기본
memcached구성인 64MB의 전체 캐시를 사용하려고 시도하여memcached가 32MB 이상의 메모리를 사용하도록 할 수 있습니다.[ec2-user ~]$for i in $(seq 1 150); do dd if=/dev/random of=$i bs=512k count=1; memcp -s localhost $i; done위 명령 중 어느 시점에
memcached서버에 연결 오류가 있는 것을 확인할 수 있습니다. 이는 OOM Killer가 프로세스에 적용한 제한으로 인해 프로세스를 종료했기 때문입니다. 나머지 시스템은 정상적으로 작동하며 OOM Killer는 다른 프로세스를 고려하지 않습니다. 제한한 대상이memcached.service뿐이기 때문입니다.[ec2-user ~]$sudo systemctl statusmemcached.service● memcached.service - memcached daemon Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; preset: disabled) Drop-In: /etc/systemd/system/memcached.service.d └─override.conf Active: failed (Result: oom-kill) since Fri 2025-01-31 23:20:28 UTC; 2s ago Duration: 2.901s Process: 360130 ExecStart=/usr/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS (code=killed, signal=KILL) Main PID: 360130 (code=killed, signal=KILL) CPU: 94ms Jan 31 23:20:25 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: Started memcached.service - memcached daemon. Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: A process of this unit has been killed by the OOM killer. Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: Main process exited, code=killed, status=9/KILL Jan 31 23:20:28 ip-1-2-3-4.us-west-2.compute.internal systemd[1]: memcached.service: Failed with result 'oom-kill'.