Kubernetes में OpenVPN पॉड कुछ भी आगे नहीं भेजता? ip_forward जाँचें
क्लाइंट VPN पॉड को पिंग करते हैं और उससे आगे कुछ नहीं। नेमस्पेस में फ़ॉरवर्डिंग बंद है, और सुधार को admission, रीस्टार्ट और वापसी मार्ग से गुज़रना होगा।
आपका लैपटॉप हरा टनल दिखाता है, क्लाइंट लॉग बताता है कि रूट पुश हुए, और जवाब देने वाला एकमात्र पता VPN सर्वर का अपना टनल IP है। उससे आगे के पिंग आप चाहे जिसे निशाना बनाएँ, मर जाते हैं, चाहे वह ClusterIP हो, किसी दूसरे पॉड का पता हो या कोई सार्वजनिक होस्टनाम। यह संयोजन अस्पष्ट नहीं, निदानात्मक है: डीकैप्सुलेशन काम करता है, और दूसरी हॉप नहीं।
मुझे यह एक Debian नोड पर मिला जो chart से इंस्टॉल की गई OpenVPN इमेज चला रहा था, और टनल आसान हिस्सा था। क्लाइंट ने 10.8.0.x लीज़ ली, 10.8.0.1 ने जवाब दिया, और 10.96.0.10, क्लस्टर DNS सेवा, टाइमआउट हो गई। सर्वर लॉग में कुछ भी बीमार नहीं दिखा, और ठीक इसीलिए लोग iptables नियम फिर से लिखने लगते हैं जिन्हें उन्हें कभी छूने की ज़रूरत नहीं थी।
VPN पॉड एक राउटर है, और यह सीधे कहना बनता है। एन्क्रिप्टेड पैकेट आते हैं, पॉड के अपने नेटवर्क नेमस्पेस में खुलते हैं, और फिर किसी दूसरे इंटरफ़ेस से बाहर जाना पड़ता है। Linux उस दूसरे कदम से इंकार करता है जब तक उसी नेमस्पेस के अंदर फ़ॉरवर्डिंग चालू न हो।
क्लाइंट क्या पहुँच सकता है और क्या नहीं
जो पता जवाब देता है वह टनल एंडपॉइंट का है, और VPN प्रक्रिया उसे स्थानीय रूप से रखती है, इसलिए फ़ॉरवर्डिंग बिल्कुल शामिल नहीं है। बाकी सब कुछ, दूसरा पॉड, सेवा VIP या इंटरनेट सहित, को कर्नेल से tun0 से eth0 तक पैकेट ले जाने की ज़रूरत है। जब वह स्थानांतरण अस्वीकार होता है, लक्षण अस्वीकृति नहीं बल्कि एकसमान सन्नाटा है, क्योंकि टनल के नीचे वापस कोई ICMP त्रुटि पैदा नहीं होती। आपको टाइमआउट मिलते हैं, अप्राप्य संदेश नहीं, और यही संकेत है कि कोई राउट ही नहीं कर रहा।
दो मिनट का वर्गीकरण परत को सीमित करता है। अगर DNS नाम विफल होते हैं जबकि सेवा IP पर कच्चे पिंग सफल होते हैं, तो समस्या फ़ॉरवर्डिंग में नहीं, DNS प्लंबिंग में है। अगर पीयर पते से आगे का हर गंतव्य टाइमआउट होता है, नंगे IP सहित, तो नेमस्पेस से शुरू करें।
नेमस्पेस के अंदर की सेटिंग पढ़ें
हर पॉड को अपना नेटवर्क नेमस्पेस मिलता है, और net.ipv4.ip_forward प्रति-नेमस्पेस sysctl है। नोड पर इसे बदलने से कंटेनर के बारे में कुछ पता नहीं चलता, और यह गलत मशीन पर दोपहर बिताने का भरोसेमंद तरीका है।
kubectl exec -it deploy/openvpn -- sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 0
शून्य निदान की पुष्टि करता है। मान नोड के रनटाइम कॉन्फ़िगरेशन से भी विरासत में नहीं मिलता: हर बार कंटेनर बनने पर यह इमेज के डिफ़ॉल्ट से शुरू होता है। इसलिए kubectl exec ... sysctl -w से हाथ से लगाया गया सुधार अगले रीस्टार्ट में गायब हो जाता है और रुक-रुक कर दिखने वाली खराबी के रूप में लौटता है।
इसे चालू करना ताकि मैनिफ़ेस्ट इसे रखे
टिकाऊ विकल्प एक init कंटेनर है जो उसी पॉड सैंडबॉक्स में चलता है और VPN कंटेनर शुरू होने से पहले मान लिखता है। पॉड में कंटेनर एक नेटवर्क नेमस्पेस साझा करते हैं, इसलिए सेटिंग मुख्य कंटेनर में चली जाती है।
initContainers:
- name: enable-forwarding
image: busybox:1.36
command: ["sysctl", "-w", "net.ipv4.ip_forward=1"]
securityContext:
privileged: true
वही privileged: true वह पंक्ति है जिस पर समीक्षक आपत्ति करते हैं, और वे सही हैं। sysctl लिखने के लिए या तो विशेषाधिकार चाहिए या सीमित क्षमता, और प्रतिबंधित Pod Security Standard चलाने वाला क्लस्टर विशेषाधिकार प्राप्त init कंटेनर को सीधे मना कर सकता है। अगर admission पॉड को अस्वीकार करता है, तो आपको निर्माण के समय पता चलता है, जो कम से कम ईमानदार और पढ़ने में आसान है।
साफ़ विकल्प पॉड-स्तरीय securityContext.sysctls सूची है, जो kubelet को किसी भी कंटेनर को विशेषाधिकार दिए बिना नेमस्पेस्ड sysctl लागू करने देती है। यह केवल क्लस्टर की अनुमति-सूची के नामों को कवर करती है। net.ipv4.ip_forward उस सूची में है या नहीं यह इस पर निर्भर है कि kubelet कैसे कॉन्फ़िगर हुआ, और उससे बाहर sysctl माँगने वाला पॉड admission में अस्वीकार होता है या सैंडबॉक्स दोबारा आज़माए जाने के दौरान CreateContainerConfigError में अटक जाता है। फ़ील्ड टूटा है यह मानने से पहले अनुमति-सूची जाँचें।
दोनों में से कोई भी तरीका हाथ से बनाने से पहले देखें कि chart पहले से स्विच देता है या नहीं, अक्सर ipForwardInitContainer: true जैसा कुछ। chart का मान उपयोग करने से आपकी override फ़ाइल छोटी रहती है और अगले अपग्रेड तक चलती है, जो हाथ से पैच किए गए Deployment बदलाव नहीं करते।
दूसरा आधा: वापसी मार्ग और नीति
फ़ॉरवर्डिंग चालू होना ज़रूरी है, पर्याप्त नहीं। अगर क्लाइंट ऐसा निजी पूल उपयोग करते हैं जिसके लिए क्लस्टर नेटवर्क का कोई रूट नहीं है, तो जवाब टनल में वापस रास्ता नहीं पाते, और पॉड को उस ट्रैफ़िक को उसके गंतव्य की ओर मास्क करना पड़ता है।
नीति उसके ऊपर बैठती है। NetworkPolicy ऑब्जेक्ट और क्लाउड फ़ायरवॉल नियम उस स्रोत पते के विरुद्ध मूल्यांकित होते हैं जो पैकेट अनुवाद के बाद वहन करता है, इसलिए क्लाइंट पूल के लिए लिखा नियम मास्किंग चालू होने पर चुपचाप मेल खाना बंद कर सकता है।
जब क्लाइंट को केवल क्लस्टर के अंदर की सेवाओं तक पहुँचना हो, तो VPN को सेवा VIP पर समाप्त करना पॉड नेटवर्क में राउट करने से छोटा डिज़ाइन है। यह क्लाइंट पूल को CNI की राउटिंग तालिका से पूरी तरह बाहर रखता है।
विफल हॉप को क्लाइंट से अलग करना
बाहर की ओर काम करें और पहले शांत कदम पर रुकें। VPN पीयर से शुरू करें, फिर किसी पॉड का पता आज़माएँ, फिर सेवा VIP, और उसके बाद ही कोई सार्वजनिक गंतव्य। हर सफलता सीमा को एक हॉप आगे बढ़ाती है, और हर विफलता उस परत का नाम लेती है जिसे देखना बनता है। किसी भी रोलआउट के बाद exec करके अंदर जाएँ और sysctl फिर पढ़ें, क्योंकि बदला गया पॉड इमेज के डिफ़ॉल्ट से शुरू होता है और मैनिफ़ेस्ट में कभी न रहा सुधार पहले ही जा चुका है।
Kubernetes का दस्तावेज़ क्लस्टर में sysctl के उपयोग पर सूची देता है कि कौन-से नाम पॉड सुरक्षा संदर्भ से सेट किए जा सकते हैं, और admission द्वारा बदलाव अस्वीकार होने पर वहीं पहले देखना चाहिए।