코딩일지(2024-05-05)
블루스크린 문제를 해결하자!
블루스크린 이슈… 너란 녀석!
대회전, 우리 DonkeyBro팀은 원래 듀얼부팅을 통해 ROS환경을 구축한 후 터틀봇과 연동하려고 한게 아니라 도커를 통해 ROS환경을 가상컨테이너에다가 구축해보고 이를 활용해보면서 도커를 학습하는 것이 본 취지였다. 하지만 도커개발이 늦어지게 되었는데, 이는 도커위에 올린 ROS와 터틀봇이 bringup으로 물리지가 않아서였다. 원래 브링업으로 물려야 이제 컨테이너 속 ROS에서도 제대로 된 동작이 이루어지는데, 그러지 못했던 것이다. 그래서 시간도 없고 그래서 하는 수 없이 기존 듀얼부팅방식을 고수해서 터틀봇 연습을 주행하고 대회에 이상태로 나가게 된 것이었다.
어쨋든 이미 지난거고, 이제 블루스크린이 내 컴퓨터에서 발생하는 패턴에 대해서 역으로 분석을 해보면은,
- 도커를 켠 상태에서 오랫동안 방치하면 간헐적으로 블루스크린 이슈가 발생함.
- 도커를 켜고 <고클린>에 들어가서 [시작프로그램 관리 복원]버튼을 눌러 디스크 청소를 진행하면, 블루스크린 이슈가 발생함.고클린>
이와 같이 총 두가지 케이스로 블루스크린 이슈가 발생하는 것을 목격하였다. 이를 해결하기 위해 구글링을 진행해보니, 다음과 같은 키워드와 연관이 있다는 것을 알게 되었다.
- OOM Killer Issue
- WSL2로의 업그레이드 필요
- 가상 메모리 할당(페이징기법)을 적용
그래서 이에 대해 좀 더 분석을 진행해보았다.
1. OOM Killer Issue
WhaTap이라는 사이트에 들어가보니 이런 내용이 있었다.
OOM(Out Of Memory) Killed는 쿠버네티스 클러스터 내에서 일부 컨테이너에 할당된 가용 메모리의 한계가 초과되어 시스템이 해당 컨테이너를 강제로 종료시키는 상황을 의미합니다.
아,, OOM이 메모리초과를 의미하는구나… 쉽게 말해서 내가 쓸수있는 방의 평수가 1평인데, 1평 이상의 공간을 차지할 만큼 만은 짐들이 있어서 그공간안에 다 넣을 수 없는, 그래서 “아 몰라!!” 하고 강제로 뻗어버리는 그런 상황이라고 생각하면 될 것 같다.
다른 사람들의 블로그에서 경험담을 들어보니 /var/log 밑에 syslog를 열어보면 oom killer가 도커를 죽이는 것 같다는 글이 있다.
로그에 찍히는 강제 종료 메시지는 다음과 같다.
Jan 10 17:37:01 p-master kernel: Out of memory: Kill process 9267 (gmaster) score 485 or sacrifice child
Jan 10 17:37:01 p-master kernel: Killed process 9267, UID 500, (gmaster) total-vm:86877900kB, anon-rss:75280kB, file-rss:68979468kB
OOM Killer가 발생하는 원인을 좀더 구체적으로 말하자면,
커널은 VM을 활용해서 메모리 얼로케이션을 진행하기 때문에, 실제 물리적 메모리보다 큰 프로그램을 구동하는게 가능하다. 근데!
당장 사용하지 않은 메모리는 나중에 할당하여 사용하기, 실제 메모리를 넘는 프로그램들도 구동하는 게 불가능한 한건 아니고, 생각보다 종종 이런방식으로 많이 쓰인다고 한다.(그리고 애초에 이에 대한 용어도 있다. 오버커밋?이라고 불리는 것 같다.)
문제는ㅋㅋ 이 이미 오버커밋 되어 버린 메모리에 쓰여지게 되는 경우 메모리가 모자라는 사태가 발생하여 OOM(Out Of Memory)가 발생한다고 한다.
그럼 이걸 해결하기 위해서 우리가 뭘 알아야 할까? 바로 Priority, 즉 프로세스를 종료시키는 우선순위라 하더라,
일단 oom_badness() 메소드(커널쪽 명령어인가?ㄷㄷ)에서 각 프로세서별로 점수를 매겨주고 이를 기반으로 종료시킬 프로세스를 순차적으로 선택하는 거다.
근데! 여기서 핵심이 사용자가 특별히 지정하여 순위를 변동시킬 수 있다는 것이다.
그럼 이 oom_badness() 메소드를 활용해서 순위를 수동으로 선정 및 조작하는 방법에 대해서 알려주겠지 했는데, 일단 잘 안나와있더라;;;
우선 네가지 조건을 나열해보자면은
1 .특정 프로세스를 죽임으로써, 가능한 적은 양의 프로세스만 잃는가?
- 가능한 많은 메모리를 회수할 수 있는가?
- 프로세스 중 Leak가 되지 않는가?
- 특별히 지정한 프로세스인가?
이외에 1.nice
와 2.score
기반으로 순위를 선정하는 계산은 복잡해서 따로 자세히 보지는 않고 그냥 넘어갔다.
오케이! 그러면 이 우선순위를 알아야 한다는 것까지는 힌트고, 이제 실제로 OOM Killer 순위 결정 방법에 대해서 알아보았다!
- 특정 프로세스의 PID 조회한다.
- /proc/PID/oom_adj 의 파일에 -17을 입력한다. oom_adj는 -17~15의 값을 가지며, 낮은 일수록 우선순위에서 밀려나는 것을 확인했다.
- /proc/PID/oom_score_adj의 파일에 -1000을 입력한다. oom_score_adj는 -1000~1000의 값을 가지며, 낮은 값일수록 우선순위에서 밀려난다.
# pidof gmaster
18907
# echo -17 > /proc/18907/oom_adj
# echo -1000 > /proc/18907/oom_score_adj
최종적으로 우리는 OOM KIller순위 결정 방법에 대해서 알아보았다. 이를 위해 우선순위를 낮추는 접근을 진행했고 말이다.
근데 나는 한가지 의문인 게 리눅스에서 메모리 누수로 인한 시스템 이슈가 재발하는 것을 방지하게 위해 OOM KIller 자체를 끌 수 있는 방법은 없을까 하고 찾아보았지만 그런 거는 없다고 하더라,
대신에 위의 설정처럼 oom_adj파일 -17의 값을 넣게 되면, OOM Killer 는 설정된 프로세스를 선택하지 않게 된다.
내일부터는 다시 깃허브 개발에 필요한 보조환경과 깃허브 개발에 착수할거다!
댓글남기기