2016-05-14 10 views
15

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

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

जो मुझे करने के लिए पता चलता है कि मैं चाहिए:

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

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

पहले, मैं परिभाषित करने Endpoints इस तरह से आपत्ति की कोशिश की:

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" के लिए किया गया था। लेकिन, इससे एक त्रुटि हुई और कहा कि "पते" सरणी में "आईपी" फ़ील्ड अनिवार्य था। तो, मेरा अगला प्रयास "नेमस्पेस बी" में "सर्विसएक्स" को एक निश्चित क्लस्टरआईपी पता असाइन करना था, और इसे आईपी फ़ील्ड में डालें (ध्यान दें कि service_cluster_ip_range को 1 9 2.168.0.0/16 के रूप में कॉन्फ़िगर किया गया है, और 1 9 2.168.1.1 को असाइन किया गया था ClusterIP "serviceX" "namespaceB" के लिए, "serviceX" "namespaceA" में ऑटो 192.168.0.0/16 सबनेट पर एक अलग ClusterIP सौंपा गया था):

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" "नेमस्पेसए" में "नामस्थान बी" में पॉड को अग्रेषित नहीं किया गया था - वे समय समाप्त हो गए। Iptables सेटअप को देखते हुए, ऐसा लगता है कि इसे पूरा करने के लिए इसे दो बार एनएटी प्री-रूटिंग करना होगा।

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

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

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

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

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

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

+0

आप सेवा के लिए fullqualified डोमेन नाम का उपयोग करके देखें, 'service.namespace.s पसंद आया vc.cluster.local ' – MrE

+0

हां, जैसा कि प्रश्न में उल्लिखित है, यह ठीक काम करता है। लेकिन, लक्ष्य यह है कि कंटेनर में कोड को उस नामस्थान को जानने की आवश्यकता नहीं है जहां सेवा वास्तव में लोड की जाती है। –

+0

नामस्थानों का बिंदु अलग करना है, इसलिए मुझे लगता है कि यदि आपको नामस्थानों पर जाना है तो आपको कम से कम यह पता होना चाहिए कि यह कहां स्थित है! – MrE

उत्तर

25

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

आप (के रूप में आप ने उल्लेख किया) के माध्यम से इसे DNS name है एक सेवा का उपयोग कर सकते हैं: servicename.namespace.svc। cluster.local

आप another namespace via a local service में यह संदर्भित करने के लिए है कि 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 
+1

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

+0

क्या यह काम करता है? मुझे शक है। क्या कोई यह पुष्टि कर सकता है कि यह वास्तव में काम करता है, मेरे लिए काम नहीं करता है। – debianmaster

+0

हां यह करता है। यह किसी अन्य नामस्थान में किसी सेवा से बात करने के लिए एक फली के लिए काम करता है, लेकिन एक लोड लोडबैंसर के लिए नहीं। – Paul

2

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

संबंधित मुद्दे