दूसरे नामस्थान में स्थित सेवा


108

मैं एक नेमस्पेस में एक सेवा को परिभाषित करने का एक तरीका खोजने की कोशिश कर रहा हूं जो कि किसी अन्य नामस्थान में चल रहे पॉड से लिंक करता है। मुझे पता है कि फली में चल रहे कंटेनर को क्लस्टर DNS में इसे संदर्भित करके namespaceAएक्सेस serviceXकिया जा सकता है , लेकिन मेरे पास कंटेनर के अंदर का कोड नहीं होना चाहिए । यही है, मैं चाहता हूं कि कोड केवल लुकअप हो और फिर इसे एक्सेस करने में सक्षम हो।namespaceBserviceX.namespaceB.svc.cluster.localserviceXserviceX

Kubernetes प्रलेखन चलता है कि यह संभव है। यह कहता है कि आप चयनकर्ता के बिना किसी सेवा को परिभाषित करने वाले कारणों में से एक यह है कि आप अपनी सेवा को किसी अन्य नामस्थान या किसी अन्य क्लस्टर पर सेवा में इंगित करना चाहते हैं

इससे मुझे पता चलता है कि मुझे चाहिए:

  1. में एक serviceXसेवा को परिभाषित करें namespaceA, एक चयनकर्ता के बिना (क्योंकि मैं जिस POD का चयन करना चाहता हूं वह नहीं है namespaceA)।
  2. एक सेवा को परिभाषित करें (जिसे मैंने भी बुलाया था serviceX) namespaceBऔर फिर
  3. में एक अंतिम बिंदु वस्तु को परिभाषित namespaceAकरने के लिए बात करने के लिए serviceXमें namespaceB

यह तीसरा चरण है जिसे मैं पूरा नहीं कर पाया हूं।

सबसे पहले, मैंने समापन बिंदु ऑब्जेक्ट को इस तरह परिभाषित करने की कोशिश की:

kind: Endpoints
apiVersion: v1
metadata:
  name: serviceX
  namespace: namespaceA
subsets:
  - addresses:
      - targetRef:
          kind: Service
          namespace: namespaceB
          name: serviceX
          apiVersion: v1
    ports:
      - name: http
        port: 3000

यह तार्किक दृष्टिकोण लग रहा था, और जाहिर है कि इसके targetRefलिए क्या था। लेकिन, इससे यह त्रुटि हुई कि सरणी ipमें फ़ील्ड addressesअनिवार्य था। तो, मेरी अगली कोशिश करने के लिए एक निश्चित ClusterIP पता असाइन करने के लिए था serviceXमें namespaceB, और आईपी क्षेत्र में डाल दिया है कि (ध्यान दें कि service_cluster_ip_rangeके रूप में कॉन्फ़िगर किया गया है 192.168.0.0/16, और 192.168.1.1के लिए ClusterIP के रूप में नियुक्त किया गया था serviceXमें namespaceB, serviceXमें namespaceAऑटो पर एक अलग ClusterIP सौंपा गया था 192.168.0.0/16सबनेट) :

kind: Endpoints
apiVersion: v1
metadata:
  name: serviceX
  namespace: namespaceA
subsets:
  - addresses:
        - ip: 192.168.1.1
          targetRef:
            kind: Service
            namespace: namespaceB
            name: serviceX
            apiVersion: v1
    ports:
      - name: http
        port: 3000

यह स्वीकार कर लिया गया था, लेकिन पॉड को अग्रेषित नहीं किया serviceXगया namespaceAथा namespaceB। Iptables सेटअप को देखते हुए, ऐसा लगता है कि इसे पूरा करने के लिए NAT को दो बार पूर्व-मार्ग करना होगा।

केवल एक चीज जो मैंने पाया है कि काम किया है - लेकिन एक संतोषजनक समाधान नहीं है - पॉड के वास्तविक आईपी पते को प्रदान करना serviceXहै namespaceBऔर उस पते को एंडपॉइंट ऑब्जेक्ट में डालना है namespaceA। यह संतोषजनक नहीं है, निश्चित रूप से, क्योंकि पॉड आईपी पता समय के साथ बदल सकता है। यही समस्या सेवा आईपी को हल करने के लिए है।

तो, क्या वहाँ एक तरीका है जो दस्तावेज के वादे को पूरा करने के लिए लगता है कि मैं एक नाम स्थान में एक सेवा को एक अलग नामस्थान में चल रही सेवा को इंगित कर सकता हूं ?

एक टिप्पणीकार ने सवाल किया कि आप ऐसा क्यों करना चाहते हैं - यहाँ एक उपयोग मामला है जो मुझे समझ में आता है, कम से कम:

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

प्रत्येक किरायेदार की पॉड अपने स्वयं के नामस्थानों में चलती हैं, लेकिन प्रत्येक को इन सामान्य डेटा-एक्सेस सेवाओं में से एक का उपयोग करने की आवश्यकता होती है, जो आवश्यक रूप से दूसरे नामस्थान (क्योंकि यह कई किरायेदारों द्वारा एक्सेस की जाती है) में होगी। लेकिन, आप नहीं चाहेंगे कि किरायेदार को अपना कोड बदलना पड़े, अगर उनकी सदस्यता उच्च प्रदर्शन वाली सेवा तक पहुंचने के लिए बदल जाती है।

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


नामस्थानों को अलग करना है, इसलिए मुझे लगता है कि यदि आपको नामस्थानों के पार जाने की आवश्यकता है तो आपको कम से कम यह जानने की आवश्यकता है कि यह कहाँ स्थित है!
श्रीमती

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

मुझे यकीन नहीं है, क्षमा करें मुझे पता है कि मैं अपने नाम का उपयोग करके कई नामस्थानों में सेवाओं का उपयोग करता हूं। मैं विशेष रूप से वीपीएन के साथ ऐसा करता हूं, क्योंकि मेरे पास 1 वीपीएन पॉड है और मैं इससे सभी सेवाओं के माध्यम से जुड़ता हूं। हालाँकि आपको नाम स्थान जानने और fqdn प्रदान करने की आवश्यकता है। मैं आपको सुझाव दूंगा कि आप सुस्त चैनल पर पूछें।
मि

Fqdn का उपयोग करना वह समाधान है जिसका मैं वर्तमान में उपयोग कर रहा हूं। यदि आवश्यक नहीं था, तो मेरा उपयोग मामला बेहतर होगा, हालांकि, (अब प्रश्न में जोड़ा गया)।
डेविड मैकिनले

मुझे यह भी आश्चर्य है कि दस्तावेज़ीकरण का क्या जिक्र है, हालांकि मैं अपने उपयोग के मामले के लिए fqdn को एक संतोषजनक समाधान के रूप में उपयोग कर सकता हूं।
विन्सेन्ट डे स्मेट

जवाबों:


222

मैंने एक ही मुद्दे पर ठोकर खाई और एक अच्छा समाधान पाया, जिसे किसी स्थिर आईपी कॉन्फ़िगरेशन की आवश्यकता नहीं है:

आप इसके माध्यम से डीएनएस नाम (जैसा कि आपके द्वारा बताया गया है): servicename.namespace.svc.cluster.local के माध्यम से एक सेवा का उपयोग कर सकते हैं।

आप उस DNS नाम का उपयोग स्थानीय सेवा के माध्यम से किसी अन्य नामस्थान में संदर्भित करने के लिए कर सकते हैं :

kind: Service
apiVersion: v1
metadata:
  name: service-y
  namespace: namespace-a
spec:
  type: ExternalName
  externalName: service-x.namespace-b.svc.cluster.local
  ports:
  - port: 80

2
यह एक महान उपाय है! मुझे यकीन नहीं है कि "बाह्य नाम" प्रकार सेवाओं के लिए उपलब्ध था जब मैंने मूल रूप से सवाल पूछा था, लेकिन यह अब समर्थित है, और बड़े करीने से समस्या हल करता है। धन्यवाद, पॉल।
डेविड मैककिनले

1
क्या यह काम करता है? मुझे शक है। किसी को भी पुष्टि कर सकते हैं अगर यह वास्तव में काम किया, मेरे लिए काम नहीं करता है।
डेबियनमास्टर

2
हाँ यह करता है। यह एक पॉड के लिए दूसरे नामस्थान में एक सेवा से बात करने के लिए काम करता है, लेकिन एक इंग्रेस लोडबलर के लिए नहीं।
पॉल

इन-क्लस्टर CNAME लुकअप कुबेरनेट्स को ठीक करने के कारण , पुराना संस्करण काम नहीं कर सकता है।
赵浩翔

1
क्या यह कार्य क्यूब-सिस्टम नामस्थान में सेवाओं के लिए भी होना चाहिए?
नबेट

10

यह करना इतना सरल है

यदि आप इसे मेजबान के रूप में उपयोग करना चाहते हैं और इसे हल करना चाहते हैं

यदि आप किसी अन्य नाम स्थान पर स्थित सेवा के लिए किसी अन्य एपीआई गेटवे पर राजदूत का उपयोग कर रहे हैं, तो यह हमेशा उपयोग करने का सुझाव दिया जाता है:

            Use : <service name>
            Use : <service.name>.<namespace name>
            Not : <service.name>.<namespace name>.svc.cluster.local

यह इस तरह होगा: servicename.namespacename.svc.cluster.local

यह आपके द्वारा उल्लेखित नाम स्थान के अंदर एक विशेष सेवा के लिए अनुरोध भेजेगा।

उदाहरण:

kind: Service
apiVersion: v1
metadata:
  name: service
spec:
  type: ExternalName
  externalName: <servicename>.<namespace>.svc.cluster.local

यहां <servicename>और <namespace>उचित मूल्य के साथ बदलें ।

कुबेरनेट्स में, वर्चुअल वातावरण बनाने के लिए नेमस्पेस का उपयोग किया जाता है लेकिन सभी एक-दूसरे से जुड़े होते हैं।


6
क्या आप बता सकते हैं कि लगभग 2 साल पहले दिए गए पॉल से यह उत्तर कैसे अलग है?
ऑलिवर

2
@ कोई फर्क नहीं पड़ता है, लेकिन मैंने निर्दिष्ट किया है कि किस स्थान पर सेवा का नाम और नाम स्थान को बदलना है। जबकि उसने नाम-स्थान का उपयोग किया है, इसलिए मुझे भ्रमित करता है।
हर्ष मनवर

7
एसओ पर एक आसान चाल जवाब पर एक टिप्पणी जोड़ने और आवश्यक स्पष्टीकरण करने के लिए है।
ओलिवर

4
मैं इसे सबसे अच्छा समाधान कहूंगा क्योंकि .svc.cluster.localआंतरिक रूप से सेवा को हल करने के लिए डिफ़ॉल्ट रूप से समर्थित है।
डॉ। के। एन

1
मेरे लिए भी जगाया। थैंक्यू
विमल प्रकाश

0

आप इसे सेवा लोडबलकैंसर की तरह नामांकित सेवाओं की तुलना में एक उच्च परत पर तैनात करके प्राप्त कर सकते हैं https://github.com/kubernetes/contrib/tree/master/service-loadbalancer । यदि आप इसे किसी एकल नामस्थान पर प्रतिबंधित करना चाहते हैं, तो "--namespace = ns" तर्क का उपयोग करें (यह सभी नामस्थानों में चूक करता है: https://github.com/kubernetes/contrib/blob/master/ervice-loadbalancer/service_loadbalancer.go) # L715 )। यह L7 के लिए अच्छा काम करता है, लेकिन L4 के लिए थोड़ा गड़बड़ है।


3
यह परियोजना अब (अगस्त 2018) निकाली गई है
निकोला बेन

1
@Prashanth B: क्या आप अपने उत्तर को तदनुसार अपडेट कर सकते हैं!
चोसगुरु
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.