मूल रूप से ब्लॉग द्वारा प्रकाशित
कुबेरनेट्स मानक पुस्तकालय रत्नों से भरा है, जो पारिस्थितिकी तंत्र का हिस्सा कई विभिन्न उप-पैकेजों में छिपा हुआ है। ऐसा एक उदाहरण जो मैंने हाल ही में खोजा है k8s.io/client-go/tools/leaderelection, जिसका उपयोग Kubernetes क्लस्टर के अंदर चल रहे किसी भी एप्लिकेशन में लीडर इलेक्शन प्रोटोकॉल जोड़ने के लिए किया जा सकता है। यह लेख चर्चा करेगा कि नेता का चुनाव क्या है, इसे कुबेरनेट्स पैकेज में कैसे लागू किया जाता है, और एक उदाहरण प्रदान करेगा कि हम इस लाइब्रेरी का उपयोग अपने अनुप्रयोगों में कैसे कर सकते हैं।
नेता चुनाव एक वितरित सिस्टम अवधारणा है जो अत्यधिक उपलब्ध सॉफ़्टवेयर का मुख्य निर्माण खंड है। यह कई समवर्ती प्रक्रियाओं को एक-दूसरे के बीच समन्वयित करने और एक एकल "नेता" प्रक्रिया को चुनने की अनुमति देता है, जो तब डेटा स्टोर पर लिखने जैसी समकालिक क्रियाएं करने के लिए जिम्मेदार होता है।
यह वितरित डेटाबेस या कैश जैसे सिस्टम में उपयोगी है, जहां हार्डवेयर या नेटवर्क विफलताओं के खिलाफ अतिरेक बनाने के लिए कई प्रक्रियाएं चल रही हैं, लेकिन डेटा स्थिरता सुनिश्चित करने के लिए एक साथ स्टोरेज में नहीं लिखा जा सकता है। यदि भविष्य में किसी बिंदु पर नेता प्रक्रिया अनुत्तरदायी हो जाती है, तो शेष प्रक्रियाएं एक नए नेता के चुनाव की शुरुआत करेंगी, और अंततः नेता के रूप में कार्य करने के लिए एक नई प्रक्रिया का चयन करेंगी।
इस अवधारणा का उपयोग करके, हम एक ही लीडर और एकाधिक स्टैंडबाय प्रतिकृतियों के साथ अत्यधिक उपलब्ध सॉफ़्टवेयर बना सकते हैं।
कुबेरनेट्स में, नियंत्रक-रनटाइम पैकेज नियंत्रकों को अत्यधिक उपलब्ध बनाने के लिए लीडर चुनाव का उपयोग करता है। नियंत्रक परिनियोजन में, संसाधन समाधान केवल तभी होता है जब एक प्रक्रिया अग्रणी होती है, और अन्य प्रतिकृतियां स्टैंडबाय पर प्रतीक्षा कर रही होती हैं। यदि लीडर पॉड अनुत्तरदायी हो जाता है, तो शेष प्रतिकृतियां बाद में समाधान करने और सामान्य संचालन फिर से शुरू करने के लिए एक नए लीडर का चुनाव करेंगी।
यह लाइब्रेरी कुबेरनेट्स लीज या वितरित लॉक का उपयोग करती है, जिसे एक प्रक्रिया द्वारा प्राप्त किया जा सकता है। पट्टे मूल कुबेरनेट्स संसाधन हैं जो नवीनीकरण विकल्प के साथ एक निश्चित अवधि के लिए एक ही पहचान द्वारा रखे जाते हैं। यहां दस्तावेज़ों से एक उदाहरण विवरण दिया गया है:
apiVersion: coordination.k8s.io/v1 kind: Lease metadata: labels: apiserver.kubernetes.io/identity: kube-apiserver kubernetes.io/hostname: master-1 name: apiserver-07a5ea9b9b072c4a5f3d1c3702 namespace: kube-system spec: holderIdentity: apiserver-07a5ea9b9b072c4a5f3d1c3702_0c8914f7-0f35-440e-8676-7844977d3a05 leaseDurationSeconds: 3600 renewTime: "2023-07-04T21:58:48.065888Z"
K8s पारिस्थितिकी तंत्र द्वारा पट्टों का उपयोग तीन तरीकों से किया जाता है:
अब आइए एक नमूना कार्यक्रम लिखकर पट्टों के इस दूसरे उपयोग के मामले का पता लगाएं ताकि यह प्रदर्शित किया जा सके कि आप नेता चुनाव परिदृश्यों में उनका उपयोग कैसे कर सकते हैं।
इस कोड उदाहरण में, हम नेता चुनाव और लीज हेरफेर विशिष्टताओं को संभालने के लिए लीडरइलेक्शन पैकेज का उपयोग कर रहे हैं।
package main import ( "context" "fmt" "os" "time" "k8s.io/client-go/tools/leaderelection" rl "k8s.io/client-go/tools/leaderelection/resourcelock" ctrl "sigs.k8s.io/controller-runtime" ) var ( // lockName and lockNamespace need to be shared across all running instances lockName = "my-lock" lockNamespace = "default" // identity is unique to the individual process. This will not work for anything, // outside of a toy example, since processes running in different containers or // computers can share the same pid. identity = fmt.Sprintf("%d", os.Getpid()) ) func main() { // Get the active kubernetes context cfg, err := ctrl.GetConfig() if err != nil { panic(err.Error()) } // Create a new lock. This will be used to create a Lease resource in the cluster. l, err := rl.NewFromKubeconfig( rl.LeasesResourceLock, lockNamespace, lockName, rl.ResourceLockConfig{ Identity: identity, }, cfg, time.Second*10, ) if err != nil { panic(err) } // Create a new leader election configuration with a 15 second lease duration. // Visit https://pkg.go.dev/k8s.io/client-go/tools/leaderelection#LeaderElectionConfig // for more information on the LeaderElectionConfig struct fields el, err := leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{ Lock: l, LeaseDuration: time.Second * 15, RenewDeadline: time.Second * 10, RetryPeriod: time.Second * 2, Name: lockName, Callbacks: leaderelection.LeaderCallbacks{ OnStartedLeading: func(ctx context.Context) { println("I am the leader!") }, OnStoppedLeading: func() { println("I am not the leader anymore!") }, OnNewLeader: func(identity string) { fmt.Printf("the leader is %s\n", identity) }, }, }) if err != nil { panic(err) } // Begin the leader election process. This will block. el.Run(context.Background()) }
नेता चुनाव पैकेज के बारे में अच्छी बात यह है कि यह नेता चुनावों को संभालने के लिए कॉलबैक-आधारित ढांचा प्रदान करता है। इस तरह, आप विशिष्ट राज्य परिवर्तनों पर विस्तृत तरीके से कार्य कर सकते हैं और नए नेता के चुने जाने पर संसाधनों को उचित रूप से जारी कर सकते हैं। इन कॉलबैक को अलग-अलग गोरोइन में चलाकर, पैकेज मशीन संसाधनों का कुशलतापूर्वक उपयोग करने के लिए गो के मजबूत समवर्ती समर्थन का लाभ उठाता है।
इसका परीक्षण करने के लिए, आइए प्रकार का उपयोग करके एक परीक्षण क्लस्टर बनाएं।
$ kind create cluster
नमूना कोड को main.go में कॉपी करें, एक नया मॉड्यूल बनाएं (go mod init लीडरइलेक्शनटेस्ट) और इसकी निर्भरता स्थापित करने के लिए इसे व्यवस्थित करें (go mod tidy)। एक बार जब आप गो रन मेन.गो चलाते हैं, तो आपको इस तरह आउटपुट देखना चाहिए:
$ go run main.go I0716 11:43:50.337947 138 leaderelection.go:250] attempting to acquire leader lease default/my-lock... I0716 11:43:50.351264 138 leaderelection.go:260] successfully acquired lease default/my-lock the leader is 138 I am the leader!
सटीक नेता की पहचान उदाहरण (138) में जो है उससे भिन्न होगी, क्योंकि यह उस प्रक्रिया की केवल पीआईडी है जो लेखन के समय मेरे कंप्यूटर पर चल रही थी।
और यहां वह लीज है जो परीक्षण क्लस्टर में बनाई गई थी:
$ kubectl describe lease/my-lock Name: my-lock Namespace: default Labels:Annotations: API Version: coordination.k8s.io/v1 Kind: Lease Metadata: Creation Timestamp: 2024-07-16T15:43:50Z Resource Version: 613 UID: 1d978362-69c5-43e9-af13-7b319dd452a6 Spec: Acquire Time: 2024-07-16T15:43:50.338049Z Holder Identity: 138 Lease Duration Seconds: 15 Lease Transitions: 0 Renew Time: 2024-07-16T15:45:31.122956Z Events:
देखें कि "धारक की पहचान" प्रक्रिया की पीआईडी, 138 के समान है।
अब, एक और टर्मिनल खोलें और उसी main.go फ़ाइल को एक अलग प्रक्रिया में चलाएँ:
$ go run main.go I0716 11:48:34.489953 604 leaderelection.go:250] attempting to acquire leader lease default/my-lock... the leader is 138
यह दूसरी प्रक्रिया तब तक प्रतीक्षा करती रहेगी, जब तक कि पहली प्रक्रिया प्रतिक्रियाशील न हो जाए। आइए पहली प्रक्रिया को समाप्त करें और लगभग 15 सेकंड प्रतीक्षा करें। अब जबकि पहली प्रक्रिया लीज़ पर अपने दावे को नवीनीकृत नहीं कर रही है, .spec.renewTime फ़ील्ड को अब अपडेट नहीं किया जाएगा। इससे अंततः नए नेता के चुनाव के लिए दूसरी प्रक्रिया शुरू हो जाएगी, क्योंकि लीज़ के नवीनीकरण का समय उसकी अवधि से अधिक पुराना है। क्योंकि यह प्रक्रिया अब चलने वाली एकमात्र प्रक्रिया है, यह स्वयं को नए नेता के रूप में चुनेगी।
the leader is 604 I0716 11:48:51.904732 604 leaderelection.go:260] successfully acquired lease default/my-lock I am the leader!
यदि प्रारंभिक नेता के बाहर निकलने के बाद भी कई प्रक्रियाएं चल रही थीं, तो लीज हासिल करने की पहली प्रक्रिया नए नेता की होगी, और बाकी स्टैंडबाय पर रहेंगे।
यह पैकेज फुलप्रूफ नहीं है, क्योंकि यह "इस बात की गारंटी नहीं देता कि केवल एक ग्राहक ही नेता (उर्फ फेंसिंग) के रूप में कार्य कर रहा है"। उदाहरण के लिए, यदि किसी नेता को रोक दिया जाता है और उसकी लीज समाप्त होने दी जाती है, तो एक अन्य स्टैंडबाय प्रतिकृति लीज का अधिग्रहण कर लेगी। फिर, एक बार जब मूल नेता निष्पादन शुरू कर देता है, तो वह सोचेगा कि वह अभी भी नेता है और नव-निर्वाचित नेता के साथ काम करना जारी रखेगा। इस तरह, आप अंततः दो नेताओं को एक साथ दौड़ते हुए पा सकते हैं।
इसे ठीक करने के लिए, एक फेंसिंग टोकन जो लीज को संदर्भित करता है उसे सर्वर के प्रत्येक अनुरोध में शामिल करने की आवश्यकता है। फेंसिंग टोकन प्रभावी रूप से एक पूर्णांक है जो हर बार लीज में परिवर्तन होने पर 1 बढ़ जाता है। इसलिए पुराने फ़ेंसिंग टोकन वाले क्लाइंट के अनुरोध सर्वर द्वारा अस्वीकार कर दिए जाएंगे। इस परिदृश्य में, यदि कोई पुराना नेता नींद से जागता है और एक नए नेता ने पहले से ही फेंसिंग टोकन बढ़ा दिया है, तो पुराने नेता के सभी अनुरोध अस्वीकार कर दिए जाएंगे क्योंकि यह सर्वर ने जो देखा है उससे अधिक पुराना (छोटा) टोकन भेज रहा है। नये नेता.
प्रत्येक लीज के लिए संबंधित फेंसिंग टोकन को ध्यान में रखते हुए कोर एपीआई सर्वर को संशोधित किए बिना कुबेरनेट्स में बाड़ लगाना मुश्किल होगा। हालाँकि, कई लीडर कंट्रोलर होने का जोखिम k8s API सर्वर द्वारा ही कुछ हद तक कम किया गया है। क्योंकि पुरानी वस्तुओं के अपडेट अस्वीकार कर दिए जाते हैं, केवल ऑब्जेक्ट के सबसे अद्यतित संस्करण वाले नियंत्रक ही इसे संशोधित कर सकते हैं। इसलिए जब हम कई नियंत्रक नेताओं को चला सकते हैं, तो एक संसाधन की स्थिति कभी भी पुराने संस्करणों पर वापस नहीं आएगी यदि कोई नियंत्रक किसी अन्य नेता द्वारा किए गए बदलाव को याद करता है। इसके बजाय, सुलह का समय बढ़ जाएगा क्योंकि दोनों नेताओं को संसाधनों की अपनी आंतरिक स्थिति को ताज़ा करने की ज़रूरत है ताकि यह सुनिश्चित हो सके कि वे नवीनतम संस्करणों पर काम कर रहे हैं।
फिर भी, यदि आप किसी भिन्न डेटा स्टोर का उपयोग करके नेता चुनाव को लागू करने के लिए इस पैकेज का उपयोग कर रहे हैं, तो जागरूक होने के लिए यह एक महत्वपूर्ण चेतावनी है।
नेता का चुनाव और वितरित लॉकिंग वितरित प्रणालियों के महत्वपूर्ण निर्माण खंड हैं। दोष-सहिष्णु और अत्यधिक उपलब्ध एप्लिकेशन बनाने का प्रयास करते समय, आपके पास ऐसे उपकरण होना महत्वपूर्ण है। कुबेरनेट्स मानक लाइब्रेरी हमें एप्लिकेशन डेवलपर्स को आसानी से अपने स्वयं के अनुप्रयोगों में नेता चुनाव बनाने की अनुमति देने के लिए अपने आदिम के चारों ओर एक युद्ध-परीक्षणित आवरण प्रदान करती है।
हालांकि इस विशेष लाइब्रेरी का उपयोग आपको कुबेरनेट्स पर अपने एप्लिकेशन को तैनात करने तक सीमित करता है, ऐसा लगता है कि हाल ही में दुनिया इसी तरह चल रही है। यदि वास्तव में यह एक डीलब्रेकर है, तो आप निश्चित रूप से लाइब्रेरी को फोर्क कर सकते हैं और इसे किसी भी एसीआईडी-अनुपालक और अत्यधिक उपलब्ध डेटास्टोर के खिलाफ काम करने के लिए संशोधित कर सकते हैं।
अधिक k8s स्रोत गहन जानकारी के लिए बने रहें!
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3