# Kubernetes में सेवाओं को उजागर करना {{#include ../../banners/hacktricks-training.md}} Kubernetes में सेवाओं को उजागर करने के **विभिन्न तरीके** हैं ताकि **आंतरिक** एंडपॉइंट और **बाहरी** एंडपॉइंट दोनों उन्हें एक्सेस कर सकें। यह Kubernetes कॉन्फ़िगरेशन काफी महत्वपूर्ण है क्योंकि व्यवस्थापक **हमलावरों को उन सेवाओं तक पहुँच प्रदान कर सकता है जिन तक उन्हें पहुँच नहीं होनी चाहिए**। ### स्वचालित सूचीकरण K8s द्वारा सार्वजनिक रूप से सेवाओं को उजागर करने के तरीकों की सूची बनाने से पहले, जान लें कि यदि आप नामस्थान, सेवाओं और इनग्रेस को सूचीबद्ध कर सकते हैं, तो आप सार्वजनिक रूप से उजागर की गई सभी चीजें पा सकते हैं: ```bash kubectl get namespace -o custom-columns='NAME:.metadata.name' | grep -v NAME | while IFS='' read -r ns; do echo "Namespace: $ns" kubectl get service -n "$ns" kubectl get ingress -n "$ns" echo "==============================================" echo "" echo "" done | grep -v "ClusterIP" # Remove the last '| grep -v "ClusterIP"' to see also type ClusterIP ``` ### ClusterIP एक **ClusterIP** सेवा **डिफ़ॉल्ट** Kubernetes **सेवा** है। यह आपको अपने क्लस्टर के अंदर एक **सेवा** देती है जिसे आपके क्लस्टर के अंदर अन्य ऐप्स एक्सेस कर सकते हैं। यहाँ **कोई बाहरी एक्सेस** नहीं है। हालांकि, इसे Kubernetes प्रॉक्सी का उपयोग करके एक्सेस किया जा सकता है: ```bash kubectl proxy --port=8080 ``` अब, आप इस योजना का उपयोग करके सेवाओं तक पहुँचने के लिए Kubernetes API के माध्यम से नेविगेट कर सकते हैं: `http://localhost:8080/api/v1/proxy/namespaces//services/:/` उदाहरण के लिए, आप निम्नलिखित URL का उपयोग कर सकते हैं: `http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/` इस सेवा तक पहुँचने के लिए: ```yaml apiVersion: v1 kind: Service metadata: name: my-internal-service spec: selector: app: my-app type: ClusterIP ports: - name: http port: 80 targetPort: 80 protocol: TCP ``` _इस विधि के लिए आपको `kubectl` को **प्रमाणित उपयोगकर्ता** के रूप में चलाने की आवश्यकता है।_ सभी ClusterIPs की सूची बनाएं: ```bash kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORT(S):.spec.ports[*].port,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep ClusterIP ``` ### NodePort जब **NodePort** का उपयोग किया जाता है, तो सभी नोड्स (जो वर्चुअल मशीनों का प्रतिनिधित्व करते हैं) पर एक निर्दिष्ट पोर्ट उपलब्ध कराया जाता है। इस विशेष पोर्ट की ओर निर्देशित **Traffic** को फिर व्यवस्थित रूप से **सेवा** की ओर **रूट** किया जाता है। आमतौर पर, इस विधि की कमियों के कारण इसे अनुशंसित नहीं किया जाता है। सभी NodePorts की सूची बनाएं: ```bash kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORT(S):.spec.ports[*].port,NODEPORT(S):.spec.ports[*].nodePort,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep NodePort ``` NodePort विनिर्देशन का एक उदाहरण: ```yaml apiVersion: v1 kind: Service metadata: name: my-nodeport-service spec: selector: app: my-app type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 30036 protocol: TCP ``` यदि आप yaml में **nodePort** निर्दिष्ट नहीं करते हैं (यह वह पोर्ट है जो खोला जाएगा) तो **30000–32767 के रेंज में एक पोर्ट का उपयोग किया जाएगा**। ### LoadBalancer सेवा को बाहरी रूप से **एक क्लाउड प्रदाता के लोड बैलेंसर का उपयोग करके** उजागर करता है। GKE पर, यह एक [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) को चालू करेगा जो आपको एकल IP पता देगा जो आपके सेवा के लिए सभी ट्रैफ़िक को अग्रेषित करेगा। AWS पर यह एक लोड बैलेंसर लॉन्च करेगा। आपको प्रत्येक उजागर सेवा के लिए लोड बैलेंसर के लिए भुगतान करना होगा, जो महंगा हो सकता है। सभी लोड बैलेंसर की सूची बनाएं: ```bash kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,EXTERNAL-IP:.status.loadBalancer.ingress[*],PORT(S):.spec.ports[*].port,NODEPORT(S):.spec.ports[*].nodePort,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep LoadBalancer ``` ### External IPs > [!TIP] > बाहरी IPs को Load Balancers प्रकार की सेवाओं द्वारा उजागर किया जाता है और आमतौर पर इसका उपयोग तब किया जाता है जब एक बाहरी Cloud Provider Load Balancer का उपयोग किया जा रहा हो। > > इन्हें खोजने के लिए, `EXTERNAL-IP` फ़ील्ड में मानों के साथ लोड बैलेंसर्स की जांच करें। क्लस्टर में **बाहरी IP** (जैसे **गंतव्य IP**) के साथ आने वाला ट्रैफ़िक, सेवा पोर्ट पर, **सेवा के एक endpoint** की ओर **रूट किया जाएगा**। `externalIPs` को Kubernetes द्वारा प्रबंधित नहीं किया जाता है और यह क्लस्टर प्रशासक की जिम्मेदारी होती है। सेवा स्पेक में, `externalIPs` को किसी भी `ServiceTypes` के साथ निर्दिष्ट किया जा सकता है। नीचे दिए गए उदाहरण में, "`my-service`" को "`80.11.12.10:80`" (`externalIP:port`) पर क्लाइंट द्वारा एक्सेस किया जा सकता है। ```yaml apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - name: http protocol: TCP port: 80 targetPort: 9376 externalIPs: - 80.11.12.10 ``` ### ExternalName [**From the docs:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) ExternalName प्रकार की सेवाएँ **एक सेवा को DNS नाम से मैप करती हैं**, न कि किसी सामान्य चयनकर्ता जैसे `my-service` या `cassandra` से। आप इन सेवाओं को `spec.externalName` पैरामीटर के साथ निर्दिष्ट करते हैं। यह सेवा परिभाषा, उदाहरण के लिए, `prod` नामस्थान में `my-service` सेवा को `my.database.example.com` से मैप करती है: ```yaml apiVersion: v1 kind: Service metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com ``` जब `my-service.prod.svc.cluster.local` होस्ट को देखा जाता है, तो क्लस्टर DNS सेवा `CNAME` रिकॉर्ड के साथ `my.database.example.com` मान लौटाती है। `my-service` तक पहुंचना अन्य सेवाओं की तरह ही काम करता है लेकिन महत्वपूर्ण अंतर के साथ कि **पुनर्निर्देशन DNS स्तर पर होता है** न कि प्रॉक्सी या फॉरवर्डिंग के माध्यम से। सभी ExternalNames की सूची बनाएं: ```bash kubectl get services --all-namespaces | grep ExternalName ``` ### Ingress ऊपर दिए गए सभी उदाहरणों के विपरीत, **Ingress एक प्रकार की सेवा नहीं है**। इसके बजाय, यह **कई सेवाओं के सामने बैठता है और एक "स्मार्ट राउटर"** या आपके क्लस्टर में प्रवेश बिंदु के रूप में कार्य करता है। आप Ingress के साथ कई अलग-अलग चीजें कर सकते हैं, और **Ingress नियंत्रकों के कई प्रकार हैं जिनकी विभिन्न क्षमताएँ हैं**। डिफ़ॉल्ट GKE ingress नियंत्रक आपके लिए एक [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) चालू करेगा। यह आपको बैकएंड सेवाओं के लिए पथ आधारित और उपडोमेन आधारित रूटिंग दोनों करने की अनुमति देगा। उदाहरण के लिए, आप foo.yourdomain.com पर सब कुछ foo सेवा को भेज सकते हैं, और yourdomain.com/bar/ पथ के अंतर्गत सब कुछ bar सेवा को भेज सकते हैं। GKE पर [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) के साथ Ingress ऑब्जेक्ट के लिए YAML इस तरह दिख सकता है: ```yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-ingress spec: backend: serviceName: other servicePort: 8080 rules: - host: foo.mydomain.com http: paths: - backend: serviceName: foo servicePort: 8080 - host: mydomain.com http: paths: - path: /bar/* backend: serviceName: bar servicePort: 8080 ``` सभी इनग्रेस की सूची बनाएं: ```bash kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status' ``` हालांकि इस मामले में प्रत्येक की जानकारी को एक-एक करके प्राप्त करना बेहतर है ताकि इसे बेहतर तरीके से पढ़ा जा सके: ```bash kubectl get ingresses --all-namespaces -o=yaml ``` ### संदर्भ - [https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0) - [https://kubernetes.io/docs/concepts/services-networking/service/](https://kubernetes.io/docs/concepts/services-networking/service/) {{#include ../../banners/hacktricks-training.md}}