Exposing Services in Kubernetes

HackTricks का समर्थन करें

Kubernetes में सेवाओं को उजागर करने के विभिन्न तरीके हैं ताकि आंतरिक एंडपॉइंट और बाहरी एंडपॉइंट दोनों उन्हें एक्सेस कर सकें। यह Kubernetes कॉन्फ़िगरेशन काफी महत्वपूर्ण है क्योंकि व्यवस्थापक हमलावरों को उन सेवाओं तक पहुँच दे सकता है जिन तक उन्हें पहुँच नहीं होनी चाहिए

स्वचालित सूचीकरण

K8s द्वारा सार्वजनिक रूप से सेवाओं को उजागर करने के तरीकों की सूची बनाने से पहले, जान लें कि यदि आप नामस्थान, सेवाओं और इनग्रेस को सूचीबद्ध कर सकते हैं, तो आप सार्वजनिक रूप से उजागर की गई सभी चीज़ें पा सकते हैं:

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

A ClusterIP सेवा डिफ़ॉल्ट Kubernetes सेवा है। यह आपको अपने क्लस्टर के अंदर एक सेवा देती है जिसे आपके क्लस्टर के अंदर अन्य ऐप्स एक्सेस कर सकते हैं। यहाँ कोई बाहरी एक्सेस नहीं है।

हालांकि, इसे Kubernetes प्रॉक्सी का उपयोग करके एक्सेस किया जा सकता है:

kubectl proxy --port=8080

अब, आप इस योजना का उपयोग करके सेवाओं तक पहुँचने के लिए Kubernetes API के माध्यम से नेविगेट कर सकते हैं:

http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/

उदाहरण के लिए, आप निम्नलिखित URL का उपयोग कर सकते हैं:

http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/

इस सेवा तक पहुँचने के लिए:

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 की सूची बनाएं:

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 की सूची बनाएं:

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 विनिर्देशन का एक उदाहरण:

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 पर, यह एक नेटवर्क लोड बैलेंसर चालू करेगा जो आपको एकल IP पता देगा जो आपके सेवा के लिए सभी ट्रैफ़िक को अग्रेषित करेगा। AWS पर यह एक लोड बैलेंसर लॉन्च करेगा।

आपको प्रत्येक उजागर सेवा के लिए LoadBalancer के लिए भुगतान करना होगा, जो महंगा हो सकता है।

सभी LoadBalancers की सूची बनाएं:

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

बाहरी IPs को लोड बैलेंसर प्रकार की सेवाओं द्वारा उजागर किया जाता है और जब एक बाहरी क्लाउड प्रदाता लोड बैलेंसर का उपयोग किया जा रहा होता है, तो आमतौर पर इसका उपयोग किया जाता है।

इन्हें खोजने के लिए, EXTERNAL-IP फ़ील्ड में मानों के साथ लोड बैलेंसर की जांच करें।

क्लस्टर में बाहरी IP (जैसे गंतव्य IP) के साथ आने वाला ट्रैफ़िक, सेवा पोर्ट पर, सेवा के एक अंत बिंदु की ओर रूट किया जाएगाexternalIPs को Kubernetes द्वारा प्रबंधित नहीं किया जाता है और यह क्लस्टर प्रशासक की जिम्मेदारी होती है।

सेवा स्पेक में, externalIPs को किसी भी ServiceTypes के साथ निर्दिष्ट किया जा सकता है। नीचे दिए गए उदाहरण में, "my-service" को क्लाइंट्स द्वारा "80.11.12.10:80" (externalIP:port) पर एक्सेस किया जा सकता है।

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: ExternalName प्रकार की सेवाएँ एक सेवा को DNS नाम से मैप करती हैं, न कि किसी सामान्य चयनकर्ता जैसे my-service या cassandra के लिए। आप इन सेवाओं को spec.externalName पैरामीटर के साथ निर्दिष्ट करते हैं।

यह सेवा परिभाषा, उदाहरण के लिए, prod नामस्थान में my-service सेवा को my.database.example.com से मैप करती है:

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 की सूची बनाएं:

kubectl get services --all-namespaces | grep ExternalName

Ingress

ऊपर दिए गए सभी उदाहरणों के विपरीत, Ingress एक प्रकार की सेवा नहीं है। इसके बजाय, यह कई सेवाओं के सामने बैठता है और एक "स्मार्ट राउटर" या आपके क्लस्टर में प्रवेश बिंदु के रूप में कार्य करता है।

आप Ingress के साथ कई अलग-अलग चीजें कर सकते हैं, और Ingress नियंत्रकों के कई प्रकार हैं जिनकी विभिन्न क्षमताएँ हैं

डिफ़ॉल्ट GKE ingress नियंत्रक आपके लिए एक HTTP(S) लोड बैलेंसर चालू करेगा। यह आपको बैकएंड सेवाओं के लिए पथ आधारित और उपडोमेन आधारित रूटिंग दोनों करने की अनुमति देगा। उदाहरण के लिए, आप foo.yourdomain.com पर सब कुछ foo सेवा पर भेज सकते हैं, और yourdomain.com/bar/ पथ के अंतर्गत सब कुछ bar सेवा पर भेज सकते हैं।

GKE पर L7 HTTP लोड बैलेंसर के साथ Ingress ऑब्जेक्ट के लिए 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

सभी इनग्रेस की सूची बनाएं:

kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status'

हालांकि इस मामले में, इसे बेहतर पढ़ने के लिए प्रत्येक की जानकारी एक-एक करके प्राप्त करना बेहतर है:

kubectl get ingresses --all-namespaces -o=yaml

संदर्भ

HackTricks का समर्थन करें

Last updated