메모리 제한이 설정되지 않은 경우 cgroups v2를 사용하여 메모리 부족 이벤트 수신

메모리 제한이 설정되지 않은 경우 cgroups v2를 사용하여 메모리 부족 이벤트 수신

cgroups v1을 사용하면 메모리 부족과 관련된 이벤트를 수신할 수 있습니다. ~에 따르면문서, 필요

  • 새로 만들기eventfd
  • memory.pressure_level읽기용으로 열림
  • 공개 cgroup.event_control글쓰기
  • {eventfd} {pressure_level_fd} {level}( level, low또는 medium) critical에 쓰기event_control
  • eventfd에서 읽은 내용에서 8바이트가 반환될 때까지 기다립니다.

메모리가 부족해지기 직전인 프로그램에 이 작업을 수행하면 긴 low이벤트 목록과 일부 medium합계가 수신되고 critical마지막으로 OOM 킬러가 실행됩니다. 이것을 확신하고 싶으시다면 제가 준비한 것이 있습니다.Rust의 작은 예, 를 사용하여 실행할 수 있습니다 cargo build --release --examples && sudo target/release/examples/cv1.

cgroups v2의 경우(문서), 유사한 이벤트가 전달될 수 있습니다.

  • inotify 시계 설정memory.events.local
  • 파일을 완전히 읽고 구문 분석하여 각 이벤트가 수신된 후 숫자를 비교합니다.

high이는 cgroup에서 메모리 제한을 설정할 때 작동하며(v1과 달리 루트 없이도) 일반적으로 메모리 제한이 증가하는 곳이나 시기에 적어도 일부 inotify 이벤트를 받게 됩니다 max. (이 사실을 다시 한번 확신하고 싶다면 systemd-run --same-dir --pty --user -p MemoryMax=1G cargo run --example cv2위의 사항을 따르십시오.)

그러나 메모리 제한이 설정되지 않거나 제한이 사용 가능한 메모리보다 높은 경우 이벤트를 수신하지 않고 프로세스가 종료됩니다. 뷰는 memory.pressure강한 증가를 보여주므로 커널은 OOM 킬러를 호출하기 전에 무슨 일이 일어나고 있는지 알았음에 틀림없습니다. cgroups v1과 같은 좋은 동작이 사전에 많은 경고를 제공한다는 것을 알려주는 방법이 있습니까?

참고: 저는 몇 가지 관련 질문을 알고 있습니다(1,2), 하지만:

  • 오래되었으며 질문/답변에서는 cgroups v1만 고려합니다.
  • oom Killer가 활성화되기 전에 트리거되어 "spawn high oom_score_adj canary process" 해커가 표시되지 않기를 원합니다.

답변1

읽고 나서문서조금 더 자세히 살펴보니 답을 찾았습니다. 요약하자면, some 50000 2000000\0fd 에 쓴 /proc/pressure/memory다음 이벤트에 대해 fd를 폴링 하여 PRI메모리 부족을 관찰 할 수 있습니다.

나는 이것이 만족스럽지 않기 때문에 승인된 것으로 표시하지 않았습니다.

  • cgroups 기반 변형(at $CGROUP_FS/$GROUP/memory.pressure)은 루트에서만 작동합니다. 에서 전역 변형을 사용하는 경우 /proc/pressure/프로세스에 여전히 많은 여유 메모리가 있어도 이벤트를 받을 수 있습니다.
  • 루트가 아닌 사용자의 최소 간격은 2초입니다. 스왑이 없는 시스템에서는 첫 번째 이벤트가 발생하기 전에 OOM에 의해 종료될 수 있습니다.

관련 정보