Container 환경에서 출력하는 eBPF bpf_get_current_pid_tgid의 pid가 존재하지 않는 이유
지난 글에 eBPF 코드를,
Golang + bpf2go를 사용한 eBPF 기본 예제
; https://www.sysnet.pe.kr/2/0/13769
WSL에서 수행해 보면, bpf_printk로 출력한 pid, thread_id가 정상적인 값이 나오지 않습니다. 예를 들어, Ubuntu 20.04 WSL 터미널을 2개 열어 놓고 아래의 코드를 실행해 보면,
// 터미널 A에서 eBPF 예제 실행
$ sudo ./ebpf_sample
loaded: {{Kprobe(kprobe_sys_clone)#7} {}}
link.Kprobe: &{{0xc0000c4058 } 0xc000014220}
Press any key to exit...
// 터미널 B에서 trace_pipe를 출력
$ sudo cat /sys/kernel/debug/tracing/trace_pipe
...[생략]...
bash-12269 [004] ....1 3121.817004: bpf_trace_printk: pid == 12269, thread_id == 12269
sudo-12661 [006] ....1 3121.821072: bpf_trace_printk: pid == 12661, thread_id == 12661
bash-7377 [000] ....1 3124.738210: bpf_trace_printk: pid == 7377, thread_id == 7377
cri-dockerd-2159 [006] ....1 3124.773875: bpf_trace_printk: pid == 2155, thread_id == 2159
cri-dockerd-2159 [014] ....1 3124.777303: bpf_trace_printk: pid == 2155, thread_id == 2159
...[생략]...
출력이 된 7377, 12661, 12269 같은 프로세스가 ps aux 명령어로 확인해 보면 존재하지 않는다는 것을 알 수 있습니다. 관련해서 검색해 보면,
The pid of the process in wsl2 differs from the pid returned in ebpf program bpf_get_current_pid_tgid() #12115
; https://github.com/microsoft/WSL/issues/12115
이런 답변이 나옵니다.
This is the expected behavior. Internally, WSL uses different PID namespaces for each distros (so each distro has init with pid=1).
What you're most likely seeing in your eBPF program is the PID from the root namespace's perspective, which is different from the one you're seeing in the distro namespace.
그렇습니다, 지난 글에서 설명한 것처럼,
pid 네임스페이스 구성으로 본 WSL 2 배포본의 계층 관계
; https://www.sysnet.pe.kr/2/0/13772
pid 네임스페이스 구성으로 본 WSL 2 + docker-desktop
; https://www.sysnet.pe.kr/2/0/13773
WSL 배포본의 리눅스 인스턴스는 이미 루트 네임스페이스로부터 분리돼 있기 때문에 eBPF의 출력이 정상적이지 않은 것처럼 나오는 것입니다. 이것이 WSL 환경인 경우 더욱 문제가 되는 이유는, 일반적인 리눅스 머신이라면 루트 네임스페이스를 소유한 Shell에 접속해 eBPF의 출력을 그나마 쉽게 해석할 수 있지만, WSL이라면 "--debug-shell"로 진입한 화면에서만 가능하기 때문에 현실적으로 그냥 불가능하다고 봐야 하기 때문입니다.
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]