pid 네임스페이스 구성으로 본 WSL 2 배포본의 계층 관계
지난 글의 마지막 즈음에,
// Mariner VM 내에서 실행
# cat /proc/83194/status | grep NSpid
NSpid: 83194 3116 3059
리눅스 배포본 내에 뜬 프로세스가 3개의 네임스페이스를 거쳐 격리된 것이라고 설명했습니다. 이번 글에서는 이에 대해 좀 더 자세하게 살펴보겠습니다.
테스트를 위해 Ubuntu 20.04 WSL 인스턴스에서 sleep을 하나 실행해 둡니다.
// Ubuntu WSL 인스턴스 내에서 실행
$ sleep 680001 &
[1] 4419
// 4419 프로세스의 pid namespace 확인
$ ls -l /proc/4419/ns/pid
lrwxrwxrwx 1 testusr testusr 0 Oct 17 14:46 /proc/4419/ns/pid -> 'pid:[4026532257]'
그다음 debug shell로 연결한 환경에서 저 프로세스를 확인하면,
c:\temp> wsl --debug-shell
// 현재 환경의 pid namespace 확인
# ls -l /proc/1/ns/pid
lrwxrwxrwx 1 root root 0 Oct 17 01:11 /proc/1/ns/pid -> 'pid:[4026531836]'
// Ubuntu WSL 인스턴스 내에서 실행한 프로세스 확인
# ps aux | grep [s]leep
wslg 48950 0.0 0.0 7240 588 ? S 05:40 0:00 sleep 680001
# cat /proc/48950/status | grep NSpid
NSpid: 48950 4578 4419
이렇게 정리가 됩니다.
pid:[4026531836] Mariner VM에 속한 pid namespace
|- 48950 (sleep의 pid)
ㄴ pid:[????????] (unknown)
|- 4578 (sleep의 pid)
ㄴ pid:[4026532257] Ubuntu WSL 인스턴스에 속한 pid namespace
ㄴ 4419 (sleep의 pid)
그렇다면 4578 pid로 나타난 네임스페이스는 뭘까요?
예전에, wsl --debug-shell과 함께 wsl --system을 언급한 적이 있습니다.
c:\temp> wsl --help
...[생략]..
--system
Launches a shell for the system distribution.
...[생략]..
이걸로 들어가 보면,
c:\temp> wsl --system
$ ps aux | grep [s]leep
wslg 4578 0.0 0.0 7240 588 ? S 14:40 0:00 sleep 680001
오호~~~ 우리가 찾던 바로 그 4578 프로세스가 나왔습니다. 그리고 그 사이에 낀 네임스페이스 격리를 Mariner VM 수준에서 다음과 같이 추적할 수 있습니다.
// Mariner VM 내에서 실행
# lsns -t pid 4026532257
PID PPID USER COMMAND
226 221 root /sbin/init
227 226 root |-/init
248 227 root | |-plan9 --control-socket 6 --log-level 4 --server-fd 7 --pipe
939 227 root | |-/bin/login -f
1132 939 root | | `--bash
1363 227 root | |-/init
...[생략]...
보면, 226 PID의 부모로 221이 나오는데요, 그것의 pid namespace를 살펴보면,
// Mariner VM 내에서 실행
# ls -l /proc/221/ns/pid
lrwxrwxrwx 1 root root 0 Oct 17 01:11 /proc/221/ns/pid -> 'pid:[4026532245]'
다른 값이 나왔습니다. 따라서 pid namespace 계층을 정리하면 대충 다음과 같이 나옵니다.
pid:[4026531836] Mariner VM에 속한 pid namespace
|- 48950 (sleep의 pid)
ㄴ pid:[4026532245] WSLg 격리
|- 4578 (sleep의 pid)
ㄴ pid:[4026532257] Ubuntu WSL 인스턴스에 속한 pid namespace
ㄴ 4419 (sleep의 pid)
참고로, WSL 리눅스 인스턴스들이 언제나 저렇게 WSLg 쪽 네임스페이스에 속해 있지는 않습니다. 추가로 새롭게 설치한 Ubuntu 18.04의 경우에는,
$ sleep 180000 &
[1] 32
$ ls -l /proc/32/ns/pid
lrwxrwxrwx 1 testusr testusr 0 Oct 17 15:24 /proc/32/ns/pid -> 'pid:[4026532784]'
wsl --system 환경에서는 보이지 않았습니다.
c:\temp> wsl --system
$ ps aux | grep [s]leep
$
Mariner VM에서 확인해 보면,
// Mariner VM 내에서 실행
# ps aux | grep [s]leep
wslg 56564 0.0 0.0 7936 824 ? S 06:24 0:00 sleep 180000
# cat /proc/56564/status | grep NSpid
NSpid: 56564 87 32
역시 3개의 격리 공간이 나오는데요, 이번에도 WSLg 레벨과 유사한 별도의 네임스페이스가 Ubuntu 18.04 인스턴스의 중간에 존재하는 것을 ppid를 추적해 살펴볼 수 있습니다.
// Mariner VM 내에서 실행
# lsns -t pid 4026532784
PID PPID USER COMMAND
56297 56291 root /init
...[생략]...
56564 56336 wslg | `-sleep 180000
...[생략]...
# ls -l /proc/56291/ns/pid
lrwxrwxrwx 1 root root 0 Oct 17 06:32 /proc/56291/ns/pid -> 'pid:[4026532771]'
이를 감안해 적용해 보면, 대충 이런 식의 WSL 2 배포본의 계층 구조를 유추할 수 있을 것입니다.
Mariner VM
|- WSLg 격리
| |- 리눅스 배포본 A
| |- 리눅스 배포본 B
| .
| .
| ㄴ 리눅스 배포본 N
|- Non-WSLg 격리
| ㄴ 리눅스 배포본 N
.
.
ㄴ Non-WSLg 격리
ㄴ 리눅스 배포본 N
또 한 가지 유의해야 할 점이 있다면, WSLg를
설정을 통해 아예 비활성화시킬 수 있다는 점입니다. (옵션 변경 후 "wsl --shutdown" 명령을 실행해야 적용됩니다.)
// 혹은, wslsettings.exe를 이용해 GUI 환경에서 편집할 수 있습니다.
C:\temp> type %USERPROFILE%\.wslconfig
[wsl2]
guiApplications=false
그리고 이 옵션을 false로 설정한 경우 "wsl --system" 명령어가 동작하지 않습니다. (사실, 거의 쓸 일이 없어 전혀 불편하지 않겠지만.)
C:\temp> wsl --system
GUI application support is disabled via C:\Users\testusr\.wslconfig or /etc/wsl.conf.
Error code: Wsl/Service/CreateInstance/WSL_E_GUI_APPLICATIONS_DISABLED
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]