ePBF란?
BPF는 Unix계열 OS의 Kernel Level에서 Bytecode에 따라 동작하는 경량화된 Virtual Machine이다. 처음에는 packet filter라는 이름 그대로 Network Packet을 Filtering하는 Program 을 구동하는 용도로 사용되었다. 하지만 사용자가 원하는 Program을 언제든지 Kernel Level에서 구동할 수 있다는 장점 때문에 BPF는 꾸준히 발전하게 되었고, 현재는 다양한 기능을 수행할 수 있게 되었다.
BPF가 다양한 기능을 수행하게 되면서 기존의 매우 제한적인 Resource들이 큰 걸림돌이 됐다. 이러한 문제점을 해결하기 위해서 Linux는 더 많은 Resource와 기능을 이용할 수 있는 Extened BPF, 즉 eBPF를 정의했다.
BPF와 eBPF의 차이
왼쪽의 cBPF는 초기의 BPF, classic BPF이고 오른쪽은 eBPF의 그림이다. 기존의 BPF는 2개의 32비트 레지스터와 메모리로 활용되는 15개의 32비트 스크레치 패드로 이루어져 있었다. 여기서 더 발전해서 eBPF에서는 11개의 64비트 레지스터, 512개의 32비트 스택, 그리고 eBPF 프로그램을 통해 수집된 정보를 키 벨류 형태로 저장할 수 있는 map을 무한개 사용할 수 있게 되었다.
또한 실행할 수 있는 Bytecode도 추가되어 Kernel이 eBPF 지원을 위해 제공하는 Kernel Helper Function을 호출하거나 다른 eBPF Program을 호출할 수 있게 되었다. 이처럼 eBPF는 BPF보다 많은 리소스 및 기능을 이용하기 때문에 보다 더 다양한 기능의 Program을 구동 할 수 있게 되었다.
eBPF의 동작 과정
위의 그림은 eBPF Program의 Compile 과정과 bpf() System Call의 동작을 나타내고 있다. 개발자가 eBPF Source Code를 작성하면 LLVM/clang을 통해서 eBPF Bytecode로 컴파일된다. 그 후 Bytecode는 tc나 iproute2 같은 어플리케이션을 통해 Kernel의 eBPF에 적재되는데, 이 과정에서 bpf시스템콜을 이용하고 있다.
eBPF Bytecode는 Kernel Level에서 동작하기 때문에 system 전체에 영향을 줄 수 있는 위험한 상황을 방지하기 위하여 Verifier로 이상이 없는지 검사한후 커널에 적재하도록 설계되어 있다. Verifier는 Bytecode가 허용되지 않은 Memory 영역을 참조하거나 무한 Loop가 발생하는 경우가 있는지도 검사한다.
또한 허용되지 않은 Kernel Helper Function을 호출했는지도 검사한다. 검사를 통과한 Bytecode는 eBPF에 적재되어 동작하는데, 필요에 따라 일부는 JIT (Just-in-time) Compiler를 통해서 Native Code로 변환되어 Kernel에서 동작하게 된다.
bpf() System Call은 Bytecode를 적재하는 것 뿐 아니라 어플리케이션이 Map에 접근할 수 있게 만들어준다. 따라서 어플리케이션과 eBPF는 Map을 이용하여 통신을 할 수 있고, 이를 활용하여 더욱 다양한 기능을 수행할 수 있다.
'Study > Linux' 카테고리의 다른 글
[Linux] eBPF의 활용 (BCC, bpftrace) (0) | 2022.08.25 |
---|