eBPF Documentary

eBPF प्रलेखन

eBPF एक क्रांतिकारी तकनीक है जिसकी उत्पत्ति लिनक्स कर्नेल में हुई है जो ऑपरेटिंग सिस्टम कर्नेल जैसे विशेषाधिकार प्राप्त संदर्भ में सैंडबॉक्स किए गए प्रोग्राम चला सकती है। इसका उपयोग कर्नेल स्रोत कोड को बदलने या कर्नेल मॉड्यूल लोड किए बिना कर्नेल की क्षमताओं को सुरक्षित और कुशलतापूर्वक बढ़ाने के लिए किया जाता है।

ऐतिहासिक रूप से, ऑपरेटिंग सिस्टम हमेशा से ही अवलोकन, सुरक्षा और नेटवर्किंग कार्यक्षमता को लागू करने के लिए एक आदर्श स्थान रहा है, क्योंकि कर्नेल की संपूर्ण सिस्टम की देखरेख और नियंत्रण करने की विशेषाधिकार प्राप्त क्षमता है। साथ ही, ऑपरेटिंग सिस्टम कर्नेल को इसकी केंद्रीय भूमिका और स्थिरता और सुरक्षा के प्रति उच्च आवश्यकता के कारण विकसित करना कठिन है। इस प्रकार ऑपरेटिंग सिस्टम स्तर पर नवाचार की दर पारंपरिक रूप से ऑपरेटिंग सिस्टम के बाहर कार्यान्वित कार्यक्षमता की तुलना में कम रही है।

Overview

eBPF इस सूत्र को मौलिक रूप से बदल देता है। ऑपरेटिंग सिस्टम के भीतर सैंडबॉक्स किए गए प्रोग्राम चलाने की अनुमति देकर, एप्लिकेशन डेवलपर्स रनटाइम पर ऑपरेटिंग सिस्टम में अतिरिक्त क्षमताएँ जोड़ने के लिए eBPF प्रोग्राम चला सकते हैं। ऑपरेटिंग सिस्टम तब सुरक्षा और निष्पादन दक्षता की गारंटी देता है जैसे कि जस्ट-इन-टाइम (JIT) कंपाइलर और सत्यापन इंजन की सहायता से मूल रूप से संकलित किया गया हो। इसने अगली पीढ़ी के नेटवर्किंग, अवलोकन और सुरक्षा कार्यक्षमता सहित उपयोग के मामलों की एक विस्तृत श्रृंखला को कवर करने वाली eBPF-आधारित परियोजनाओं की लहर को जन्म दिया है।

आज, eBPF का उपयोग कई तरह के उपयोग के मामलों को आगे बढ़ाने के लिए बड़े पैमाने पर किया जाता है: आधुनिक डेटा सेंटर और क्लाउड नेटिव वातावरण में उच्च-प्रदर्शन नेटवर्किंग और लोड-बैलेंसिंग प्रदान करना, कम ओवरहेड पर बारीक सुरक्षा अवलोकन डेटा निकालना, एप्लिकेशन डेवलपर्स को एप्लिकेशन का पता लगाने में मदद करना, प्रदर्शन समस्या निवारण, निवारक एप्लिकेशन और कंटेनर रनटाइम सुरक्षा प्रवर्तन के लिए अंतर्दृष्टि प्रदान करना, और बहुत कुछ। संभावनाएं अनंत हैं, और eBPF द्वारा अनलॉक किया जा रहा नवाचार अभी शुरू ही हुआ है।

eBPF.io हर किसी के लिए eBPF के विषय पर सीखने और सहयोग करने का स्थान है। eBPF एक खुला समुदाय है और हर कोई इसमें भाग ले सकता है और साझा कर सकता है। चाहे आप eBPF का पहला परिचय पढ़ना चाहते हों, आगे की पठन सामग्री ढूँढना चाहते हों, या प्रमुख eBPF परियोजनाओं में योगदानकर्ता बनने के लिए अपना पहला कदम उठाना चाहते हों, eBPF.io आपकी हर तरह से मदद करेगा।

BPF मूल रूप से बर्कले पैकेट फ़िल्टर के लिए था, लेकिन अब जब eBPF (विस्तारित BPF) पैकेट फ़िल्टरिंग से कहीं ज़्यादा काम कर सकता है, तो संक्षिप्त नाम अब कोई मायने नहीं रखता। eBPF को अब एक अलग शब्द माना जाता है जिसका कोई मतलब नहीं है। लिनक्स स्रोत कोड में, BPF शब्द बना रहता है, और टूलिंग और दस्तावेज़ीकरण में, BPF और eBPF शब्द आम तौर पर एक दूसरे के स्थान पर इस्तेमाल किए जाते हैं। मूल BPF को कभी-कभी eBPF से अलग करने के लिए cBPF (क्लासिक BPF) के रूप में संदर्भित किया जाता है।

मधुमक्खी eBPF का आधिकारिक लोगो है और इसे मूल रूप से वादिम शेकोल्डिन ने बनाया था।. पहले eBPF शिखर सम्मेलन में एक मतदान हुआ, जिसमें मधुमक्खी का नाम eBee रखा गया। (लोगो के स्वीकार्य उपयोगों के विवरण के लिए, कृपया eBPF फाउंडेशन की ब्रांड गाइडलाइन्स देखें। आप यहाँ, लोगो देख सकते हैं।)

निम्नलिखित अध्याय eBPF का एक संक्षिप्त परिचय प्रदान करते हैं। यदि आप eBPF के बारे में अधिक सीखना चाहते हैं, तो eBPF & XDP संदर्भ गाइड देखें। चाहे आप एक डेवलपर हों जो eBPF प्रोग्राम बनाना चाहते हैं, या किसी ऐसे समाधान का उपयोग करना चाहते हैं जो eBPF का उपयोग करता है, इसके बुनियादी अवधारणाओं और संरचना को समझना उपयोगी रहेगा।

eBPF प्रोग्राम इवेंट-ड्रिवन होते हैं और तब निष्पादित होते हैं जब कर्नेल या कोई एप्लिकेशन किसी विशेष हुक पॉइंट से गुजरता है। पहले से परिभाषित हुक में सिस्टम कॉल्स, फ़ंक्शन एंट्री/एग्ज़िट, कर्नेल ट्रेसपॉइंट्स, नेटवर्क इवेंट्स, और अन्य कई शामिल हैं।

सिस्टम कॉल अंकुश

यदि किसी विशिष्ट आवश्यकता के लिए पहले से परिभाषित हुक उपलब्ध नहीं है, तो कर्नेल प्रोब (kprobe) या यूज़र प्रोब (uprobe) बनाकर eBPF प्रोग्राम को कर्नेल या यूज़र-स्पेस एप्लिकेशन में लगभग किसी भी स्थान पर जोड़ा जा सकता है।

अंकुश अवलोकन

कई मामलों में, eBPF को सीधे उपयोग नहीं किया जाता, बल्कि इसे Cilium, bcc, या bpftrace जैसे प्रोजेक्ट्स के माध्यम से अप्रत्यक्ष रूप से उपयोग किया जाता है। ये प्रोजेक्ट्स eBPF के ऊपर एक एब्स्ट्रैक्शन लेयर प्रदान करते हैं, जिससे उपयोगकर्ताओं को सीधे eBPF प्रोग्राम लिखने की आवश्यकता नहीं होती। इसके बजाय, वे इन्टेंट-बेस्ड डिफिनिशन (intent-based definitions) का उपयोग कर सकते हैं, जिन्हें फिर eBPF द्वारा कार्यान्वित किया जाता है।

Clang

यदि कोई उच्च-स्तरीय एब्स्ट्रैक्शन मौजूद नहीं है, तो eBPF प्रोग्राम्स को सीधे लिखना आवश्यक होता है। Linux कर्नेल eBPF प्रोग्राम्स को बाइटकोड के रूप में लोड करने की अपेक्षा करता है। हालांकि, बाइटकोड को सीधे लिखना संभव है, लेकिन सामान्यत: डेवलपर्स LLVM जैसी कंपाइलर सूट का उपयोग करते हैं, जो pseudo-C कोड को eBPF बाइटकोड में संकलित करता है।

जब इच्छित हुक की पहचान हो जाती है, तो eBPF प्रोग्राम को Linux कर्नेल में bpf सिस्टम कॉल के माध्यम से लोड किया जा सकता है। आमतौर पर, इसके लिए उपलब्ध eBPF लाइब्रेरीज़ में से किसी एक का उपयोग किया जाता है। अगला अनुभाग उपलब्ध डेवलपमेंट टूलचेन का परिचय प्रदान करता है।

Go

जब प्रोग्राम को Linux कर्नेल में लोड किया जाता है, तो यह अनुरोधित हुक से जुड़ने से पहले दो चरणों से गुजरता है

सत्यापन चरण यह सुनिश्चित करता है कि eBPF प्रोग्राम चलाने के लिए सुरक्षित है। यह जाँचता है कि प्रोग्राम कई शर्तों को पूरा करता है, उदाहरण के लिए:

लोडर
  • eBPF प्रोग्राम लोड करने वाली प्रक्रिया के पास आवश्यक क्षमताएँ (अधिकार) होने चाहिए। जब तक अपरिवर्तनीय eBPF सक्षम नहीं किया जाता, केवल विशेषाधिकार प्राप्त प्रक्रियाएँ ही eBPF प्रोग्राम लोड कर सकती हैं।
  • प्रोग्राम क्रैश नहीं होता है या सिस्टम को किसी अन्य तरीके से नुकसान नहीं पहुँचाता।
  • प्रोग्राम हमेशा निष्पादन पूरा करता है (अर्थात, प्रोग्राम अनंत लूप में नहीं फँसता, जिससे आगे की प्रोसेसिंग रुकी रहे)।

जस्ट-इन-टाइम (JIT) संकलन चरण प्रोग्राम के सामान्य बाइटकोड को मशीन-विशिष्ट निर्देश सेट में अनुवादित करता है ताकि प्रोग्राम के निष्पादन की गति को अनुकूलित किया जा सके। इससे eBPF प्रोग्राम उतनी ही कुशलता से चलते हैं जितना कि देशी संकलित कर्नेल कोड या कर्नेल मॉड्यूल के रूप में लोड किया गया कोड।

eBPF प्रोग्रामों का एक महत्वपूर्ण पहलू एकत्रित जानकारी को साझा करने और स्थिति संग्रहीत करने की क्षमता है। इसके लिए, eBPF प्रोग्राम डेटा को विभिन्न डेटा संरचनाओं में संग्रहीत और पुनर्प्राप्त करने के लिए eBPF मैप्स की अवधारणा का उपयोग कर सकते हैं। eBPF मैप्स तक eBPF प्रोग्रामों से साथ ही उपयोगकर्ता स्पेस में अनुप्रयोगों द्वारा भी सिस्टम कॉल के माध्यम से पहुंचा जा सकता है।

मैप आर्किटेक्चर

निम्नलिखित समर्थित मैप प्रकारों की एक अपूर्ण सूची है, जो डेटा संरचनाओं की विविधता को समझाने में सहायता करती है। विभिन्न मैप प्रकारों के लिए, साझा (shared) और प्रति-CPU (per-CPU) दोनों प्रकार उपलब्ध हैं।

  • हैश टेबल, ऐरे
  • LRU (सबसे हाल ही में कम उपयोग किया गया)
  • रिंग बफर
  • स्टैक ट्रेस
  • LPM (सबसे लंबा उपसर्ग मेल)
  • ...

eBPF प्रोग्राम किसी भी यादृच्छिक कर्नेल फ़ंक्शन को कॉल नहीं कर सकते। यदि इसकी अनुमति दी जाए, तो eBPF प्रोग्राम विशेष कर्नेल संस्करणों पर निर्भर हो जाएंगे और प्रोग्राम की संगतता जटिल हो जाएगी। इसके बजाय, eBPF प्रोग्राम कर्नेल द्वारा प्रदान किए गए एक स्थिर और सुव्यवस्थित API के तहत हेल्पर फ़ंक्शनों को कॉल कर सकते हैं।

हेल्पर

उपलब्ध हेल्पर कॉल्स का सेट लगातार विकसित हो रहा है। उपलब्ध हेल्पर कॉल्स के कुछ उदाहरण:

  • यादृच्छिक संख्याएँ उत्पन्न करना
  • वर्तमान समय और तिथि प्राप्त करना
  • eBPF मैप तक पहुँच
  • प्रक्रिया/सीग्रुप संदर्भ प्राप्त करना
  • नेटवर्क पैकेट और फ़ॉरवर्डिंग लॉजिक को संसाधित करना

eBPF प्रोग्राम टेल और फ़ंक्शन कॉल्स की अवधारणा के साथ संयोजित किए जा सकते हैं। फ़ंक्शन कॉल्स eBPF प्रोग्राम के भीतर फ़ंक्शनों को परिभाषित करने और उन्हें कॉल करने की अनुमति देते हैं। टेल कॉल्स किसी अन्य eBPF प्रोग्राम को कॉल और निष्पादित कर सकते हैं तथा निष्पादन संदर्भ को प्रतिस्थापित कर सकते हैं, ठीक वैसे ही जैसे execve() सिस्टम कॉल सामान्य प्रक्रियाओं के लिए काम करता है।

टेल कॉल्स

eBPF एक अत्यंत शक्तिशाली तकनीक है और अब कई महत्वपूर्ण सॉफ़्टवेयर अवसंरचना घटकों के केंद्र में कार्य करती है। eBPF के विकास के दौरान, इसे Linux कर्नेल में शामिल करने पर विचार करते समय इसकी सुरक्षा सबसे महत्वपूर्ण पहलू था। eBPF की सुरक्षा को कई स्तरों के माध्यम से सुनिश्चित किया जाता है:

आवश्यक विशेषाधिकार

जब तक अपरिवर्तनीय eBPF सक्षम नहीं किया जाता, सभी प्रक्रियाएँ जो eBPF प्रोग्राम को Linux कर्नेल में लोड करना चाहती हैं, उन्हें विशेषाधिकार प्राप्त मोड (root) में चलना आवश्यक होता है या उनके पास CAP_BPF क्षमता होनी चाहिए। इसका अर्थ है कि अविश्वसनीय प्रोग्राम eBPF प्रोग्राम लोड नहीं कर सकते।

यदि अपरिवर्तनीय eBPF सक्षम किया जाता है, तो अपरिवर्तनीय प्रक्रियाएँ सीमित कार्यक्षमता और कर्नेल तक सीमित पहुंच के साथ कुछ eBPF प्रोग्राम लोड कर सकती हैं।

सत्यापनकर्ता (Verifier)

यदि किसी प्रक्रिया को eBPF प्रोग्राम लोड करने की अनुमति दी जाती है, तो भी सभी प्रोग्राम eBPF सत्यापनकर्ता (verifier) से गुजरते हैं। eBPF सत्यापनकर्ता प्रोग्राम की सुरक्षा सुनिश्चित करता है। इसका अर्थ है, उदाहरण के लिए:

  • प्रोग्रामों को इस प्रकार सत्यापित किया जाता है कि वे हमेशा निष्पादन पूरा करें, उदाहरण के लिए, कोई eBPF प्रोग्राम कभी भी ब्लॉक नहीं होगा या अनंत लूप में नहीं फँसेगा। eBPF प्रोग्राम सीमित लूप (bounded loops) रख सकते हैं, लेकिन प्रोग्राम तभी स्वीकार किया जाता है जब सत्यापनकर्ता यह सुनिश्चित कर सके कि लूप में एक निकास शर्त (exit condition) मौजूद है, जो निश्चित रूप से पूर्ण होगी।
  • प्रोग्राम किसी भी अआरंभित चर (uninitialized variable) का उपयोग नहीं कर सकते और न ही मेमोरी सीमा से बाहर पहुँच सकते हैं।
  • प्रोग्राम को सिस्टम की आकार आवश्यकताओं के भीतर फिट होना चाहिए। मनमाने ढंग से बड़े eBPF प्रोग्राम लोड करना संभव नहीं है।
  • प्रोग्राम की जटिलता सीमित होनी चाहिए। सत्यापनकर्ता सभी संभावित निष्पादन मार्गों का मूल्यांकन करेगा और उसे विन्यस्त (configured) उच्चतम जटिलता सीमा के भीतर विश्लेषण पूरा करने में सक्षम होना चाहिए।

सत्यापनकर्ता एक सुरक्षा उपकरण के रूप में कार्य करता है, जो यह जांचता है कि प्रोग्राम सुरक्षित रूप से निष्पादित हो सकते हैं। यह कोई सुरक्षा उपकरण नहीं है जो यह निरीक्षण करे कि प्रोग्राम क्या कर रहे हैं।

सख्तीकरण

सफलतापूर्वक सत्यापन पूरा होने के बाद, eBPF प्रोग्राम एक सख्तीकरण प्रक्रिया से गुजरता है, जो इस बात पर निर्भर करता है कि प्रोग्राम किसी विशेषाधिकार प्राप्त (privileged) या अपरिवर्तनीय (unprivileged) प्रक्रिया से लोड किया गया है। इस चरण में शामिल है:

  • प्रोग्राम निष्पादन सुरक्षा: जिस कर्नेल मेमोरी में eBPF प्रोग्राम संग्रहीत होता है, उसे सुरक्षित बनाया जाता है और केवल-पढ़ने योग्य (read-only) कर दिया जाता है। यदि किसी कारणवश, चाहे वह कर्नेल बग हो या दुर्भावनापूर्ण हेरफेर, eBPF प्रोग्राम को संशोधित करने का प्रयास किया जाता है, तो कर्नेल इसे जारी रखने की अनुमति देने के बजाय क्रैश हो जाएगा।
  • Spectre के खिलाफ रोकथाम: अनुमानित निष्पादन (speculative execution) के दौरान CPU शाखाओं का गलत पूर्वानुमान लगा सकता है और ऐसे प्रभाव छोड़ सकता है जिन्हें साइड चैनल के माध्यम से निकाला जा सकता है। उदाहरण के लिए: eBPF प्रोग्राम मेमोरी एक्सेस को मास्क करता है ताकि ट्रांज़िएंट इंस्ट्रक्शंस के तहत एक्सेस को नियंत्रित क्षेत्रों में पुनर्निर्देशित किया जा सके। सत्यापनकर्ता उन प्रोग्राम पथों का भी अनुसरण करता है जो केवल अनुमानित निष्पादन के तहत ही सुलभ होते हैं, और JIT कंपाइलर टेल कॉल्स को सीधे कॉल्स में परिवर्तित न कर पाने की स्थिति में Retpolines उत्पन्न करता है।
  • स्थिरांक ब्लाइंडिंग (Constant Blinding): कोड में मौजूद सभी स्थिरांकों (constants) को ब्लाइंड किया जाता है ताकि JIT स्प्रेइंग हमलों को रोका जा सके। यह हमलावरों को स्थिरांकों के रूप में निष्पादनीय कोड डालने से रोकता है, जिससे यदि कर्नेल में कोई अन्य बग मौजूद हो, तो हमलावर eBPF प्रोग्राम की मेमोरी अनुभाग में कूदकर कोड निष्पादित कर सकता है।

सारयुक्त रनटाइम प्रसंग

eBPF प्रोग्राम सीधे किसी भी मनमानी कर्नेल मेमोरी तक पहुंच नहीं सकते। जो डेटा और डेटा संरचनाएँ प्रोग्राम के संदर्भ (context) के बाहर होती हैं, उन्हें केवल eBPF हेल्पर्स के माध्यम से एक्सेस किया जा सकता है। इससे सुसंगत डेटा एक्सेस की गारंटी मिलती है और ऐसा कोई भी एक्सेस eBPF प्रोग्राम की विशेषाधिकार सीमाओं के अधीन होता है। उदाहरण के लिए: केवल उन डेटा संरचनाओं को पढ़ा या (कुछ मामलों में) संशोधित किया जा सकता है, जो प्रोग्राम के प्रकार से संबंधित हैं, बशर्ते सत्यापनकर्ता (verifier) लोडिंग के समय यह सुनिश्चित कर सके कि आउट-ऑफ-बाउंड एक्सेस कभी नहीं होगा। eBPF प्रोग्राम को केवल उन्हीं डेटा संरचनाओं को संशोधित करने की अनुमति दी जाती है, जहाँ यह गारंटी हो कि संशोधन सुरक्षित रहेगा। eBPF प्रोग्राम कर्नेल में किसी भी डेटा संरचना को मनमाने ढंग से संशोधित नहीं कर सकते।

आइए एक उपमा से शुरुआत करें। क्या आपको GeoCities याद है? 20 साल पहले, वेब पेज लगभग पूरी तरह से स्टैटिक मार्कअप लैंग्वेज (HTML) में लिखे जाते थे। एक वेब पेज मूल रूप से एक दस्तावेज़ था जिसे एक एप्लिकेशन (ब्राउज़र) द्वारा प्रदर्शित किया जा सकता था। आज के वेब पेजों को देखें—ये अब पूरी तरह से विकसित एप्लिकेशन बन चुके हैं, और वेब-आधारित तकनीकों ने उन अधिकांश एप्लिकेशनों की जगह ले ली है, जो पहले कंपाइल होने वाली भाषाओं में लिखे जाते थे।

इस विकास को किसने संभव बनाया?

Geocities

संक्षिप्त उत्तर है – जावास्क्रिप्ट के माध्यम से प्रोग्रामेबिलिटी।
इसने एक बड़ी क्रांति को जन्म दिया, जिससे ब्राउज़र लगभग स्वतंत्र ऑपरेटिंग सिस्टम के रूप में विकसित हो गए।

यह विकास क्यों हुआ? अब डेवलपर्स को उपयोगकर्ताओं के विशेष ब्राउज़र संस्करणों पर निर्भर नहीं रहना पड़ता था। पहले, अगर किसी नए फीचर की जरूरत होती, तो HTML में एक नया टैग जोड़ने के लिए स्टैंडर्ड बॉडीज़ को मनाना पड़ता था। लेकिन, जावास्क्रिप्ट और अन्य आवश्यक बिल्डिंग ब्लॉक्स की उपलब्धता ने इनोवेशन की गति को ब्राउज़र से अलग कर दिया और एप्लिकेशन स्वतंत्र रूप से विकसित होने लगे।

यह एक सरल व्याख्या है, क्योंकि HTML भी समय के साथ विकसित हुआ और इसकी भूमिका महत्वपूर्ण थी। लेकिन, सिर्फ HTML का विकास ही पर्याप्त नहीं होता, क्योंकि असली क्रांति प्रोग्रामेबिलिटी के कारण आई।

इस उदाहरण को eBPF पर लागू करने से पहले, आइए उन कुछ मुख्य पहलुओं पर नज़र डालें जो जावास्क्रिप्ट के परिचय में महत्वपूर्ण थे:

  • सुरक्षा (Safety): उपयोगकर्ता के ब्राउज़र में अनट्रस्टेड (अविश्वसनीय) कोड चलता है। इसे हल करने के लिए, जावास्क्रिप्ट प्रोग्राम को सैंडबॉक्सिंग के माध्यम से अलग किया गया और ब्राउज़र डेटा तक सीधे पहुंच को प्रतिबंधित किया गया।

  • निरंतर वितरण (Continuous Delivery): प्रोग्राम लॉजिक का विकास नए ब्राउज़र संस्करणों को बार-बार जारी किए बिना संभव होना चाहिए। इसे हल करने के लिए, ऐसे लो-लेवल बिल्डिंग ब्लॉक्स प्रदान किए गए, जो डेवलपर्स को इच्छानुसार लॉजिक बनाने की स्वतंत्रता देते हैं।

  • प्रदर्शन (Performance): प्रोग्रामेबिलिटी न्यूनतम ओवरहेड के साथ प्रदान की जानी चाहिए। इसे हल करने के लिए Just-in-Time (JIT) कंपाइलर की शुरुआत की गई, जिससे बेहतर निष्पादन गति प्राप्त हुई।

इन सभी पहलुओं के लिए, ठीक ऐसे ही समकक्ष समाधान eBPF में भी मौजूद हैं, और यही कारण है कि eBPF भी इसी तरह की क्रांति ला रहा है।

अब आइए eBPF पर वापस लौटते हैं। Linux कर्नेल पर eBPF के प्रोग्रामेबिलिटी प्रभाव को समझने के लिए, यह जरूरी है कि हम Linux कर्नेल की संरचना और यह कैसे एप्लिकेशन व हार्डवेयर के साथ इंटरैक्ट करता है, इसका एक उच्च-स्तरीय समझ रखें।

कर्नेल संरचना

Linux कर्नेल का मुख्य उद्देश्य हार्डवेयर या वर्चुअल हार्डवेयर को एब्स्ट्रैक्ट करना और एक सुसंगत API (सिस्टम कॉल्स) प्रदान करना है, जिससे एप्लिकेशन चल सकें और संसाधनों को साझा कर सकें। इसे प्राप्त करने के लिए, कई उपप्रणालियों (subsystems) और परतों (layers) को बनाए रखा जाता है ताकि इन जिम्मेदारियों का वितरण किया जा सके। प्रत्येक उपप्रणाली आमतौर पर उपयोगकर्ताओं की विभिन्न आवश्यकताओं के अनुसार कुछ स्तर तक कॉन्फ़िगरेशन की अनुमति देती है। यदि वांछित व्यवहार को कॉन्फ़िगर नहीं किया जा सकता, तो कर्नेल में परिवर्तन की आवश्यकता होती है, जो ऐतिहासिक रूप से दो विकल्पों तक सीमित था:

मूल समर्थन

  1. कर्नेल सोर्स कोड में बदलाव करें और Linux कर्नेल समुदाय को यह विश्वास दिलाएं कि यह बदलाव आवश्यक है।
  2. नए कर्नेल संस्करण के सामान्य रूप से अपनाए जाने के लिए कई वर्षों तक प्रतीक्षा करें।

कर्नेल मॉड्यूल

  1. एक कर्नेल मॉड्यूल लिखें
  2. इसे नियमित रूप से ठीक करें, क्योंकि प्रत्येक कर्नेल रिलीज़ इसे तोड़ सकता है
  3. सुरक्षा सीमाओं की कमी के कारण अपने Linux कर्नेल के भ्रष्ट (corrupt) होने का जोखिम उठाएं

eBPF के साथ, एक नया विकल्प उपलब्ध है जो Linux कर्नेल के व्यवहार को पुनःप्रोग्राम करने की अनुमति देता है, बिना कर्नेल सोर्स कोड में बदलाव किए या कोई कर्नेल मॉड्यूल लोड किए। कई मायनों में, यह उसी तरह है जैसे जावास्क्रिप्ट और अन्य स्क्रिप्टिंग भाषाओं ने उन सिस्टम्स के विकास को संभव बनाया, जिन्हें बदलना कठिन या महंगा हो गया था।

eBPF प्रोग्रामों के विकास और प्रबंधन में सहायता करने के लिए कई विकास टूलचेन उपलब्ध हैं। ये सभी उपयोगकर्ताओं की विभिन्न आवश्यकताओं को पूरा करते हैं:

bcc (BPF Compiler Collection)

BCC एक फ्रेमवर्क है जो उपयोगकर्ताओं को eBPF प्रोग्रामों को एम्बेड करके Python प्रोग्राम लिखने की सुविधा देता है। यह मुख्य रूप से एप्लिकेशन और सिस्टम प्रोफाइलिंग/ट्रेसिंग के उपयोग मामलों के लिए डिज़ाइन किया गया है, जहाँ eBPF प्रोग्राम का उपयोग सांख्यिकी एकत्र करने या इवेंट उत्पन्न करने के लिए किया जाता है, और यूज़र स्पेस में एक समकक्ष प्रोग्राम इन डेटा को एकत्र कर पढ़ने योग्य प्रारूप में प्रदर्शित करता है। Python प्रोग्राम को चलाने पर, यह eBPF बाइटकोड उत्पन्न करता है और इसे कर्नेल में लोड करता है।

bcc

bpftrace

bpftrace एक उच्च-स्तरीय ट्रेसिंग भाषा है, जिसे Linux eBPF के लिए डिज़ाइन किया गया है और यह नवीनतम Linux कर्नेल (4.x और उसके बाद के संस्करणों) में उपलब्ध है। bpftrace LLVM का उपयोग बैकएंड के रूप में करता है, जिससे स्क्रिप्ट को eBPF बाइटकोड में कंपाइल किया जाता है। साथ ही, यह Linux eBPF सबसिस्टम के साथ इंटरैक्ट करने और मौजूदा Linux ट्रेसिंग क्षमताओं का लाभ उठाने के लिए BCC का उपयोग करता है, जिनमें शामिल हैं:

  • कर्नेल डायनामिक ट्रेसिंग (kprobes)
  • यूज़र-लेवल डायनामिक ट्रेसिंग (uprobes)
  • ट्रेसपॉइंट्स (tracepoints)

bpftrace भाषा को awk, C, और पुराने ट्रेसिंग टूल्स जैसे DTrace और SystemTap से प्रेरित होकर विकसित किया गया है।

bpftrace

eBPF Go लाइब्रेरी

eBPF Go लाइब्रेरी एक सामान्य eBPF लाइब्रेरी प्रदान करती है जो eBPF बाइटकोड तक पहुँचने की प्रक्रिया और eBPF प्रोग्रामों को लोड और प्रबंधित करने को अलग करती है। eBPF प्रोग्राम आमतौर पर उच्च-स्तरीय भाषा लिखकर बनाए जाते हैं और फिर clang/LLVM कंपाइलर का उपयोग करके eBPF बाइटकोड में संकलित किया जाता है।

Go

libbpf C/C++ लाइब्रेरी

libbpf लाइब्रेरी एक C/C++-आधारित सामान्य eBPF लाइब्रेरी है जो clang/LLVM कंपाइलर से उत्पन्न eBPF ऑब्जेक्ट फ़ाइलों को कर्नेल में लोड करने में मदद करती है और सामान्य रूप से BPF सिस्टम कॉल के साथ इंटरएक्शन को एब्स्ट्रैक्ट करती है, जो अनुप्रयोगों के लिए उपयोग में आसान लाइब्रेरी APIs प्रदान करती है।

Libbpf

यदि आप eBPF के बारे में अधिक जानना चाहते हैं, तो निम्नलिखित अतिरिक्त सामग्री का उपयोग करके पढ़ाई जारी रखें:

सामान्य

गहन विश्लेषण

Cilium

Hubble