This is the multi-page printable view of this section. Click here to print.
सर्विसेज
- 1: एप्लिकेशन को सेवाओं से जोड़ें
- 2: स्रोत आईपी का उपयोग करें
- 3: पॉड्स और उनके एंडपॉइंट्स के लिए समाप्ति व्यवहार का अन्वेषण करें
1 - एप्लिकेशन को सेवाओं से जोड़ें
कंटेनरों को जोड़ने के लिए कुबेरनेट्स मॉडल
अब चूंकि आपके पास लगातार चलने वाला, रेप्लिकेटेड एप्लीकेशन है, तो आप इसे नेटवर्क पर प्रदर्शित कर सकते हैं।
Kubernetes मानता है कि पॉड अन्य पॉड के साथ संवाद कर सकते हैं, चाहे वे किसी भी होस्ट पर उतरें। Kubernetes हर पॉड को अपना क्लस्टर-निजी IP पता देता है, इसलिए आपको पॉड के बीच स्पष्ट रूप से लिंक बनाने या कंटेनर पोर्ट को होस्ट पोर्ट पर मैप करने की आवश्यकता नहीं है। इसका मतलब है कि पॉड के भीतर सभी कंटेनर लोकलहोस्ट पर एक-दूसरे के पोर्ट तक पहुँच सकते हैं, और क्लस्टर में सभी पॉड NAT के बिना एक-दूसरे को देख सकते हैं। इस दस्तावेज़ का बाकी हिस्सा इस बात पर विस्तार से बताता है कि आप इस तरह के नेटवर्किंग मॉडल पर विश्वसनीय सेवाएँ कैसे चला सकते हैं।
यह ट्यूटोरियल अवधारणा को प्रदर्शित करने के लिए एक सरल nginx वेब सर्वर का उपयोग करता है।
पॉड्स को क्लस्टर के सामने लाना
हमने पिछले उदाहरण में ऐसा किया था, लेकिन आइए इसे एक बार फिर से करें और नेटवर्किंग परिप्रेक्ष्य पर ध्यान केंद्रित करें। एक nginx पॉड बनाएँ, और ध्यान दें कि इसमें एक कंटेनर पोर्ट विनिर्देश है:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
इससे यह आपके क्लस्टर के किसी भी नोड से एक्सेस करने योग्य हो जाता है। पॉड जिस नोड पर चल रहा है, उसे जांचें:
kubectl apply -f ./run-my-nginx.yaml
kubectl get pods -l run=my-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m
my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd
अपने पॉड्स के IP की जाँच करें:
kubectl get pods -l run=my-nginx -o custom-columns=POD_IP:.status.podIPs
POD_IP
[map[ip:10.244.3.4]]
[map[ip:10.244.2.5]]
आपको अपने क्लस्टर में किसी भी नोड में ssh करने में सक्षम होना चाहिए और दोनों IP के विरुद्ध क्वेरी बनाने के लिए curl
जैसे टूल का उपयोग करना चाहिए। ध्यान दें कि कंटेनर नोड पर पोर्ट 80 का उपयोग नहीं कर रहे हैं, न ही ट्रैफ़िक को पॉड में रूट करने के लिए कोई विशेष NAT नियम हैं। इसका मतलब है कि आप एक ही नोड पर एक ही containerPort
का उपयोग करके कई nginx पॉड चला सकते हैं, और पॉड के लिए निर्दिष्ट IP पते का उपयोग करके अपने क्लस्टर में किसी भी अन्य पॉड या नोड से उन्हें एक्सेस कर सकते हैं। यदि आप होस्ट नोड पर किसी विशिष्ट पोर्ट को बैकिंग पॉड्स पर अग्रेषित करने की व्यवस्था करना चाहते हैं, तो आप कर सकते हैं - लेकिन नेटवर्किंग मॉडल का मतलब यह होना चाहिए कि आपको ऐसा करने की आवश्यकता नहीं है।
यदि आप उत्सुक हैं तो आप कुबेरनेट्स नेटवर्किंग मॉडल के बारे में अधिक पढ़ सकते हैं।
सेवा बनाना
तो हमारे पास फ्लैट, क्लस्टर वाइड, एड्रेस स्पेस में nginx चलाने वाले पॉड्स हैं। सिद्धांत रूप में, आप इन पॉड्स से सीधे बात कर सकते हैं, लेकिन जब कोई नोड समाप्त हो जाता है तो क्या होता है? पॉड्स इसके साथ समाप्त हो जाते हैं, और डिप्लॉयमेंट के अंदर रेप्लिकासेट अलग-अलग आईपी के साथ नए पॉड्स बनाएगा। यह वह समस्या है जिसे सर्विस हल करती है।
कुबेरनेट्स सेवा एक अमूर्तता है जो आपके क्लस्टर में कहीं चल रहे पॉड्स के तार्किक सेट को परिभाषित करती है, जो सभी एक ही कार्यक्षमता प्रदान करते हैं। बनाए जाने पर, प्रत्येक सेवा को एक अद्वितीय IP पता (जिसे क्लस्टरIP भी कहा जाता है) सौंपा जाता है। यह पता सेवा के जीवनकाल से जुड़ा होता है, और सेवा के जीवित रहने के दौरान इसमें कोई बदलाव नहीं होगा। पॉड्स को सेवा से बात करने के लिए कॉन्फ़िगर किया जा सकता है, और यह जान सकते हैं कि सेवा के लिए संचार स्वचालित रूप से कुछ पॉड पर लोड-बैलेंस हो जाएगा जो सेवा का सदस्य है।
आप kubectl expose
के साथ अपने 2 nginx प्रतिकृतियों के लिए एक सेवा बना सकते हैं:
kubectl expose deployment/my-nginx
service/my-nginx exposed
यह निम्न yaml kubectl apply -f
के समतुल्य है:
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
यह विनिर्देश एक ऐसी सेवा बनाएगा जो run: my-nginx
लेबल वाले किसी भी पॉड पर TCP पोर्ट 80 को लक्षित करेगी, और इसे एक अमूर्त सेवा पोर्ट पर प्रदर्शित करेगी। (targetPort
: वह पोर्ट है जिस पर कंटेनर ट्रैफ़िक स्वीकार करता है, port
: अमूर्त सेवा पोर्ट है, जो कोई भी पोर्ट हो सकता है जिसका उपयोग अन्य पॉड सेवा तक पहुंचने के लिए करते हैं)।
सेवा परिभाषा में समर्थित फ़ील्ड की सूची देखने के लिए ServiceAPI ऑब्जेक्ट देखें।
अपनी सेवा जांचें:
kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.0.162.149 <none> 80/TCP 21s
जैसा कि पहले बताया गया है, एक सेवा पॉड्स के एक समूह द्वारा समर्थित होती है। ये पॉड्स एंडपॉइंट-स्लाइस के माध्यम से उजागर होते हैं। सेवा के चयनकर्ता का लगातार मूल्यांकन किया जाएगा और परिणाम एक एंडपॉइंटस्लाइस पर पोस्ट किए जाएंगे जो लेबल का उपयोग करके सेवा से जुड़ा हुआ है। जब कोई पॉड समाप्त हो जाता है, तो उसे स्वचालित रूप से एंडपॉइंटस्लाइस से हटा दिया जाता है जिसमें इसे एंडपॉइंट के रूप में शामिल किया जाता है। सेवा के चयनकर्ता से मेल खाने वाले नए पॉड स्वचालित रूप से उस सेवा के लिए एंडपॉइंटस्लाइस में जुड़ जाएंगे।
एंडपॉइंट की जाँच करें, और ध्यान दें कि आईपी पहले वेरिएबलरण में बनाए गए पॉड के समान हैं:
kubectl describe svc my-nginx
Name: my-nginx
Namespace: default
Labels: run=my-nginx
Annotations: <none>
Selector: run=my-nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.162.149
IPs: 10.0.162.149
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.5:80,10.244.3.4:80
Session Affinity: None
Events: <none>
kubectl get endpointslices -l kubernetes.io/service-name=my-nginx
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
my-nginx-7vzhx IPv4 80 10.244.2.5,10.244.3.4 21s
अब आप अपने क्लस्टर में किसी भी नोड से <CLUSTER-IP>:<PORT>
पर nginx सेवा को कर्ल करने में सक्षम होंगे।
ध्यान दें कि सेवा IP पूरी तरह से वर्चुअल है, यह कभी भी वायर से नहीं टकराती है। यदि आप इस बारे में उत्सुक हैं कि यह कैसे
काम करता है तो आप सेवा प्रॉक्सी के बारे में अधिक पढ़ सकते हैं।
सेवा तक पहुँचना
Kubernetes सर्विस खोजने के 2 प्राथमिक तरीकों का समर्थन करता है - पर्यावरण वेरिएबल और DNS। पहला तरीका बिना किसी परेशानी के काम करता है जबकि दूसरे के लिए CoreDNS क्लस्टर ऐडऑन की आवश्यकता होती है।
टिप्पणी:
यदि सेवा परिवेश वेरिएबल वांछित नहीं हैं (अपेक्षित प्रोग्राम वेरिएबलरों के साथ संभावित टकराव, प्रक्रिया के लिए बहुत अधिक वेरिएबल, केवल DNS का उपयोग, आदि के कारण) तो आप पॉड स्पेक परenableServiceLinks
ध्वज को false
पर सेट करके इस मोड को अक्षम कर सकते हैं।पर्यावरण वेरिएबल
जब कोई पॉड किसी नोड पर चलता है, तो क्यूबलेट प्रत्येक सक्रिय सेवा के लिए पर्यावरण वेरिएबल का एक सेट जोड़ता है। यह एक क्रम समस्या का परिचय देता है। इसका कारण जानने के लिए, अपने चल रहे nginx पॉड्स के पर्यावरण का निरीक्षण करें (आपका पॉड नाम अलग होगा):
kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
ध्यान दें कि आपकी सेवा का कोई उल्लेख नहीं है। ऐसा इसलिए है क्योंकि आपने सेवा से पहले प्रतिकृतियां बनाई हैं। ऐसा करने का एक और नुकसान यह है कि शेड्यूलर दोनों पॉड को एक ही मशीन पर रख सकता है, जो आपकी पूरी सेवा को बंद कर देगा यदि यह समाप्त हो जाती है। हम 2 पॉड को समाप्त कर और उन्हें फिर से बनाने के लिए परिनियोजन की प्रतीक्षा करके इसे सही तरीके से कर सकते हैं। इस बार सेवा प्रतिकृतियों से पहले मौजूद है। यह आपको अपने पॉड के शेड्यूलर-स्तर की सेवा प्रसार देगा (बशर्ते आपके सभी नोड्स की क्षमता समान हो), साथ ही साथ सही पर्यावरण वेरिएबल:
kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
kubectl get pods -l run=my-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-e9ihh 1/1 Running 0 5s 10.244.2.7 kubernetes-minion-ljyd
my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 kubernetes-minion-905m
आप देखेंगे कि पॉड्स के अलग-अलग नाम हैं, क्योंकि उन्हें समाप्त कर दिया जाता है और फिर से बनाया जाता है।
kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
KUBERNETES_SERVICE_PORT=443
MY_NGINX_SERVICE_HOST=10.0.162.149
KUBERNETES_SERVICE_HOST=10.0.0.1
MY_NGINX_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443
डीएनएस
Kubernetes एक DNS क्लस्टर ऐडऑन सेवा प्रदान करता है जो स्वचालित रूप से अन्य सेवाओं को DNS नाम प्रदान करता है। आप जाँच सकते हैं कि यह आपके क्लस्टर पर चल रहा है या नहीं:
kubectl get services kube-dns --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 8m
इस खंड का बाकी हिस्सा यह मान लेगा कि आपके पास एक लंबे समय तक चलने वाली IP सेवा (my-nginx) है,
और एक DNS सर्वर है जिसने उस IP को एक नाम दिया है। यहाँ हम CoreDNS क्लस्टर ऐडऑन (एप्लिकेशन नाम kube-dns
)
का उपयोग करते हैं, ताकि आप मानक विधियों (जैसे gethostbyname()
) का उपयोग करके अपने क्लस्टर में किसी भी पॉड से सेवा
से बात कर सकें।
यदि CoreDNS नहीं चल रहा है, तो आप इसे CoreDNS README
या CoreDNS इंस्टॉल करने का संदर्भ देकर सक्षम कर सकते हैं।
kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm
Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false
Hit enter for command prompt
फिर, एंटर दबाएं और nslookup my-nginx
चलाएं:
[ root@curl-131556218-9fnch:/ ]$ nslookup my-nginx
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: my-nginx
Address 1: 10.0.162.149
सेवा को सुरक्षित करना
अब तक हमने क्लस्टर के भीतर से ही nginx सर्वर को एक्सेस किया है। सेवा को इंटरनेट पर दिखाने से पहले, आप यह सुनिश्चित करना चाहते हैं कि संचार चैनल सुरक्षित है। इसके लिए, आपको निम्न की आवश्यकता होगी:
- https के लिए स्व-हस्ताक्षरित प्रमाणपत्र (जब तक कि आपके पास पहले से कोई पहचान प्रमाणपत्र न हो)
- प्रमाणपत्रों का उपयोग करने के लिए कॉन्फ़िगर किया गया एक nginx सर्वर
- एक सीक्रेट जो प्रमाणपत्रों को पॉड्स के लिए सुलभ बनाता है
आप ये सब nginx https उदाहरण से प्राप्त कर सकते हैं। इसके लिए go and make tools इंस्टॉल करना आवश्यक है। यदि आप उन्हें इंस्टॉल नहीं करना चाहते हैं, तो बाद में मैन्युअल चरणों का पालन करें। संक्षेप में:
make keys KEY=/tmp/nginx.key CERT=/tmp/nginx.crt
kubectl create secret tls nginxsecret --key /tmp/nginx.key --cert /tmp/nginx.crt
secret/nginxsecret created
kubectl get secrets
NAME TYPE DATA AGE
nginxsecret kubernetes.io/tls 2 1m
और कॉन्फ़िगरेशन मैप भी:
kubectl create configmap nginxconfigmap --from-file=default.conf
आप Kubernetes उदाहरण प्रोजेक्ट रेपो में default.conf
के लिए उदाहरण पा सकते हैं।
configmap/nginxconfigmap created
kubectl get configmaps
NAME DATA AGE
nginxconfigmap 1 114s
आप निम्न कमांड का उपयोग करके nginxconfigmap
ConfigMap का विवरण देख सकते हैं:
kubectl describe configmap nginxconfigmap
इसका आउटपुट कुछ इस प्रकार है:
Name: nginxconfigmap
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
default.conf:
----
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
listen 443 ssl;
root /usr/share/nginx/html;
index index.html;
server_name localhost;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
location / {
try_files $uri $uri/ =404;
}
}
BinaryData
====
Events: <none>
यदि आपको make चलाने में समस्या आती है (उदाहरण के लिए विंडोज़ पर) तो निम्नलिखित मैनुअल चरणों का पालन करें:
# Create a public private key pair
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /d/tmp/nginx.key -out /d/tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"
# Convert the keys to base64 encoding
cat /d/tmp/nginx.crt | base64
cat /d/tmp/nginx.key | base64
पिछले आदेशों से आउटपुट का उपयोग करके yaml फ़ाइल बनाएँ, जैसा कि नीचे दिया गया है। base64 एन्कोडेड मान सभी एक ही पंक्ति में होने चाहिए।
apiVersion: "v1"
kind: "Secret"
metadata:
name: "nginxsecret"
namespace: "default"
type: kubernetes.io/tls
data:
tls.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdlZ0F3SUJBZ0lKQUp5M3lQK0pzMlpJTUEwR0NTcUdTSWIzRFFFQkJRVUFNQ1l4RVRBUEJnTlYKQkFNVENHNW5hVzU0YzNaak1SRXdEd1lEVlFRS0V3aHVaMmx1ZUhOMll6QWVGdzB4TnpFd01qWXdOekEzTVRKYQpGdzB4T0RFd01qWXdOekEzTVRKYU1DWXhFVEFQQmdOVkJBTVRDRzVuYVc1NGMzWmpNUkV3RHdZRFZRUUtFd2h1CloybHVlSE4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSjFxSU1SOVdWM0IKMlZIQlRMRmtobDRONXljMEJxYUhIQktMSnJMcy8vdzZhU3hRS29GbHlJSU94NGUrMlN5ajBFcndCLzlYTnBwbQppeW1CL3JkRldkOXg5UWhBQUxCZkVaTmNiV3NsTVFVcnhBZW50VWt1dk1vLzgvMHRpbGhjc3paenJEYVJ4NEo5Ci82UVRtVVI3a0ZTWUpOWTVQZkR3cGc3dlVvaDZmZ1Voam92VG42eHNVR0M2QURVODBpNXFlZWhNeVI1N2lmU2YKNHZpaXdIY3hnL3lZR1JBRS9mRTRqakxCdmdONjc2SU90S01rZXV3R0ljNDFhd05tNnNTSzRqYUNGeGpYSnZaZQp2by9kTlEybHhHWCtKT2l3SEhXbXNhdGp4WTRaNVk3R1ZoK0QrWnYvcW1mMFgvbVY0Rmo1NzV3ajFMWVBocWtsCmdhSXZYRyt4U1FVQ0F3RUFBYU5RTUU0d0hRWURWUjBPQkJZRUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjcKTUI4R0ExVWRJd1FZTUJhQUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjdNQXdHQTFVZEV3UUZNQU1CQWY4dwpEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRVhTMW9FU0lFaXdyMDhWcVA0K2NwTHI3TW5FMTducDBvMm14alFvCjRGb0RvRjdRZnZqeE04Tzd2TjB0clcxb2pGSW0vWDE4ZnZaL3k4ZzVaWG40Vm8zc3hKVmRBcStNZC9jTStzUGEKNmJjTkNUekZqeFpUV0UrKzE5NS9zb2dmOUZ3VDVDK3U2Q3B5N0M3MTZvUXRUakViV05VdEt4cXI0Nk1OZWNCMApwRFhWZmdWQTRadkR4NFo3S2RiZDY5eXM3OVFHYmg5ZW1PZ05NZFlsSUswSGt0ejF5WU4vbVpmK3FqTkJqbWZjCkNnMnlwbGQ0Wi8rUUNQZjl3SkoybFIrY2FnT0R4elBWcGxNSEcybzgvTHFDdnh6elZPUDUxeXdLZEtxaUMwSVEKQ0I5T2wwWW5scE9UNEh1b2hSUzBPOStlMm9KdFZsNUIyczRpbDlhZ3RTVXFxUlU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
tls.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2RhaURFZlZsZHdkbFIKd1V5eFpJWmVEZWNuTkFhbWh4d1NpeWF5N1AvOE9ta3NVQ3FCWmNpQ0RzZUh2dGtzbzlCSzhBZi9WemFhWm9zcApnZjYzUlZuZmNmVUlRQUN3WHhHVFhHMXJKVEVGSzhRSHA3VkpMcnpLUC9QOUxZcFlYTE0yYzZ3MmtjZUNmZitrCkU1bEVlNUJVbUNUV09UM3c4S1lPNzFLSWVuNEZJWTZMMDUrc2JGQmd1Z0ExUE5JdWFubm9UTWtlZTRuMG4rTDQKb3NCM01ZUDhtQmtRQlAzeE9JNHl3YjREZXUraURyU2pKSHJzQmlIT05Xc0RadXJFaXVJMmdoY1kxeWIyWHI2UAozVFVOcGNSbC9pVG9zQngxcHJHclk4V09HZVdPeGxZZmcvbWIvNnBuOUYvNWxlQlkrZStjSTlTMkQ0YXBKWUdpCkwxeHZzVWtGQWdNQkFBRUNnZ0VBZFhCK0xkbk8ySElOTGo5bWRsb25IUGlHWWVzZ294RGQwci9hQ1Zkank4dlEKTjIwL3FQWkUxek1yall6Ry9kVGhTMmMwc0QxaTBXSjdwR1lGb0xtdXlWTjltY0FXUTM5SjM0VHZaU2FFSWZWNgo5TE1jUHhNTmFsNjRLMFRVbUFQZytGam9QSFlhUUxLOERLOUtnNXNrSE5pOWNzMlY5ckd6VWlVZWtBL0RBUlBTClI3L2ZjUFBacDRuRWVBZmI3WTk1R1llb1p5V21SU3VKdlNyblBESGtUdW1vVlVWdkxMRHRzaG9reUxiTWVtN3oKMmJzVmpwSW1GTHJqbGtmQXlpNHg0WjJrV3YyMFRrdWtsZU1jaVlMbjk4QWxiRi9DSmRLM3QraTRoMTVlR2ZQegpoTnh3bk9QdlVTaDR2Q0o3c2Q5TmtEUGJvS2JneVVHOXBYamZhRGR2UVFLQmdRRFFLM01nUkhkQ1pKNVFqZWFKClFGdXF4cHdnNzhZTjQyL1NwenlUYmtGcVFoQWtyczJxWGx1MDZBRzhrZzIzQkswaHkzaE9zSGgxcXRVK3NHZVAKOWRERHBsUWV0ODZsY2FlR3hoc0V0L1R6cEdtNGFKSm5oNzVVaTVGZk9QTDhPTm1FZ3MxMVRhUldhNzZxelRyMgphRlpjQ2pWV1g0YnRSTHVwSkgrMjZnY0FhUUtCZ1FEQmxVSUUzTnNVOFBBZEYvL25sQVB5VWs1T3lDdWc3dmVyClUycXlrdXFzYnBkSi9hODViT1JhM05IVmpVM25uRGpHVHBWaE9JeXg5TEFrc2RwZEFjVmxvcG9HODhXYk9lMTAKMUdqbnkySmdDK3JVWUZiRGtpUGx1K09IYnRnOXFYcGJMSHBzUVpsMGhucDBYSFNYVm9CMUliQndnMGEyOFVadApCbFBtWmc2d1BRS0JnRHVIUVV2SDZHYTNDVUsxNFdmOFhIcFFnMU16M2VvWTBPQm5iSDRvZUZKZmcraEppSXlnCm9RN3hqWldVR3BIc3AyblRtcHErQWlSNzdyRVhsdlhtOElVU2FsbkNiRGlKY01Pc29RdFBZNS9NczJMRm5LQTQKaENmL0pWb2FtZm1nZEN0ZGtFMXNINE9MR2lJVHdEbTRpb0dWZGIwMllnbzFyb2htNUpLMUI3MkpBb0dBUW01UQpHNDhXOTVhL0w1eSt5dCsyZ3YvUHM2VnBvMjZlTzRNQ3lJazJVem9ZWE9IYnNkODJkaC8xT2sybGdHZlI2K3VuCnc1YytZUXRSTHlhQmd3MUtpbGhFZDBKTWU3cGpUSVpnQWJ0LzVPbnlDak9OVXN2aDJjS2lrQ1Z2dTZsZlBjNkQKckliT2ZIaHhxV0RZK2Q1TGN1YSt2NzJ0RkxhenJsSlBsRzlOZHhrQ2dZRUF5elIzT3UyMDNRVVV6bUlCRkwzZAp4Wm5XZ0JLSEo3TnNxcGFWb2RjL0d5aGVycjFDZzE2MmJaSjJDV2RsZkI0VEdtUjZZdmxTZEFOOFRwUWhFbUtKCnFBLzVzdHdxNWd0WGVLOVJmMWxXK29xNThRNTBxMmk1NVdUTThoSDZhTjlaMTltZ0FGdE5VdGNqQUx2dFYxdEYKWSs4WFJkSHJaRnBIWll2NWkwVW1VbGc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
अब निम्न फ़ाइल का उपयोग करके सीक्रेट्स बनाएं:
kubectl apply -f nginxsecrets.yaml
kubectl get secrets
NAME TYPE DATA AGE
nginxsecret kubernetes.io/tls 2 1m
अब अपने nginx प्रतिकृतियों को संशोधित करें ताकि सीक्रेट् मे प्रमाण पत्र और सेवा का उपयोग करके एक https सर्वर शुरू किया जा सके, ताकि दोनों पोर्ट (80 और 443) उजागर हो सकें:
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
protocol: TCP
name: http
- port: 443
protocol: TCP
name: https
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
- name: configmap-volume
configMap:
name: nginxconfigmap
containers:
- name: nginxhttps
image: bprashanth/nginxhttps:1.0
ports:
- containerPort: 443
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
- mountPath: /etc/nginx/conf.d
name: configmap-volume
Nginx-secure-app मैनिफ़ेस्ट के बारे में उल्लेखनीय बातें:
- इसमें एक ही फ़ाइल में डिप्लॉयमेंट और सेवा विनिर्देश दोनों शामिल हैं।
- nginx सर्वर पोर्ट 80 पर HTTP ट्रैफ़िक और 443 पर HTTPS ट्रैफ़िक प्रदान करता है, और nginx सेवा दोनों पोर्ट को उजागर करती है।
- प्रत्येक कंटेनर को
/etc/nginx/ssl
पर माउंट किए गए वॉल्यूम के माध्यम से कुंजियों तक पहुंच प्राप्त होती है। इसे nginx सर्वर शुरू होने से पहले सेट किया जाता है।
kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml
इस बिंदु पर आप किसी भी नोड से nginx सर्वर तक पहुंच सकते हैं।
kubectl get pods -l run=my-nginx -o custom-columns=POD_IP:.status.podIPs
POD_IP
[map[ip:10.244.3.5]]
node $ curl -k https://10.244.3.5
...
<h1>Welcome to nginx!</h1>
ध्यान दें कि हमने अंतिम चरण में कर्ल को -k
पैरामीटर कैसे दिया, ऐसा इसलिए है क्योंकि हम प्रमाणपत्र निर्माण के समय nginx चलाने वाले पॉड्स के बारे में कुछ नहीं जानते हैं, इसलिए हमें कर्ल को CName बेमेल को अनदेखा करने के लिए कहना होगा। एक सेवा बनाकर हमने प्रमाणपत्र में उपयोग किए गए CName को सेवा लुकअप के दौरान पॉड्स द्वारा उपयोग किए जाने वाले वास्तविक DNS नाम से जोड़ा। आइए इसे पॉड से परखें (सरलता के लिए उसी सीक्रेट का पुनः उपयोग किया जा रहा है, पॉड को सेवा तक पहुँचने के लिए केवल nginx.crt की आवश्यकता है):
apiVersion: apps/v1
kind: Deployment
metadata:
name: curl-deployment
spec:
selector:
matchLabels:
app: curlpod
replicas: 1
template:
metadata:
labels:
app: curlpod
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
containers:
- name: curlpod
command:
- sh
- -c
- while true; do sleep 1; done
image: radial/busyboxplus:curl
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
kubectl apply -f ./curlpod.yaml
kubectl get pods -l app=curlpod
NAME READY STATUS RESTARTS AGE
curl-deployment-1515033274-1410r 1/1 Running 0 1m
kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/tls.crt
...
<title>Welcome to nginx!</title>
...
सेवा को उजागर करना
अपने अनुप्रयोगों के कुछ हिस्सों के लिए आप किसी बाहरी IP पते पर सेवा प्रदर्शित करना चाह सकते हैं।
Kubernetes ऐसा करने के दो तरीकों का समर्थन करता है: NodePorts और LoadBalancers। पिछले अनुभाग में
बनाई गई सेवा पहले से ही NodePort
का उपयोग करती है, इसलिए यदि आपके नोड में सार्वजनिक IP है, तो
आपका nginx HTTPS प्रतिकृति इंटरनेट पर ट्रैफ़िक की सेवा के लिए तैयार है।
kubectl get svc my-nginx -o yaml | grep nodePort -C 5
uid: 07191fb3-f61a-11e5-8ae5-42010af00002
spec:
clusterIP: 10.0.162.149
ports:
- name: http
nodePort: 31704
port: 8080
protocol: TCP
targetPort: 80
- name: https
nodePort: 32453
port: 443
protocol: TCP
targetPort: 443
selector:
run: my-nginx
kubectl get nodes -o yaml | grep ExternalIP -C 1
- address: 104.197.41.11
type: ExternalIP
allocatable:
--
- address: 23.251.152.56
type: ExternalIP
allocatable:
...
$ curl https://<EXTERNAL-IP>:<NODE-PORT> -k
...
<h1>Welcome to nginx!</h1>
आइए अब क्लाउड लोड बैलेंसर का उपयोग करने के लिए सेवा को फिर से बनाएँ।
my-nginx
सेवा के Type
को NodePort
से LoadBalancer
में बदलें:
kubectl edit svc my-nginx
kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx LoadBalancer 10.0.162.149 xx.xxx.xxx.xxx 8080:30163/TCP 21s
curl https://<EXTERNAL-IP> -k
...
<title>Welcome to nginx!</title>
EXTERNAL-IP
कॉलम में IP पता वह है जो सार्वजनिक इंटरनेट पर उपलब्ध है।
CLUSTER-IP
केवल आपके क्लस्टर/निजी क्लाउड नेटवर्क के अंदर उपलब्ध है।
ध्यान दें कि AWS पर, LoadBalancer
टाइप करने पर एक ELB बनता है, जो IP का नहीं, बल्कि एक (लंबे) होस्टनाम का उपयोग करता है। यह मानक kubectl get svc
आउटपुट में फ़िट होने के लिए बहुत लंबा है, इसलिए आपको इसे देखने के लिए kubectl description service my-nginx
करना होगा। आपको कुछ इस तरह दिखाई देगा:
kubectl describe service my-nginx
...
LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com
...
आगे क्या है
- क्लस्टर में किसी एप्लिकेशन तक पहुंचने के लिए सेवा का उपयोग के बारे में अधिक जानें
- सेवा का उपयोग करके फ्रंट एंड को बैक एंड से कनेक्ट करने के बारे में अधिक जानें
- बाहरी लोड बैलेंसर बनाने के बारे में अधिक जानें
2 - स्रोत आईपी का उपयोग करें
Kubernetes क्लस्टर में चलने वाले एप्लिकेशन सर्विस एब्स्ट्रैक्शन के ज़रिए एक-दूसरे और बाहरी दुनिया से संपर्क करते हैं और उनसे संवाद करते हैं। यह दस्तावेज़ बताता है कि अलग-अलग तरह की सेवाओं को भेजे जाने वाले पैकेट के स्रोत IP का क्या होता है और आप अपनी ज़रूरतों के हिसाब से इस व्यवहार को कैसे बदल सकते हैं।
शुरू करने से पहले
शब्दावली
इस दस्तावेज़ में निम्नलिखित शब्दों का प्रयोग किया गया है:
- NAT
- नेटवर्क एड्रेस ट्रांसलेशन
- Source NAT
- पैकेट पर स्रोत आईपी को प्रतिस्थापित करना; इस पृष्ठ पर, इसका अर्थ आमतौर पर नोड के आईपी पते के साथ प्रतिस्थापित करना है।
- Destination NAT
- पैकेट पर गंतव्य आईपी को प्रतिस्थापित करना; इस पृष्ठ पर, इसका मतलब आमतौर पर पॉड के आईपी पते के साथ प्रतिस्थापित करना है
- VIP
- एक वर्चुअल आईपी पता, जैसे कि कुबेरनेट्स में प्रत्येक सेवा को निर्दिष्ट किया गया है
- kube-proxy
- एक नेटवर्क डेमॉन जो प्रत्येक नोड पर सेवा वीआईपी प्रबंधन को व्यवस्थित करता है
Prerequisites
आपको कुबरनेट्स क्लस्टर की ज़रूरत पड़ेगी और क्यूब सीटीएल कमांड लाइन साधन को समनुरूप करना होगा ताकि वो आपके क्लस्टर के साथ संवाद कर सकें। हमारी सलाह है की इस टुटोरिअल को क्लस्टर में रन करने के लिए कम से कम दो नोड का इस्तेमाल करे जो कि कंट्रोल प्लेन होस्ट के तरह ना एक्ट करे। अगर आपके पास पहले से क्लस्टर नही है, आप minikube की मदद से वह बना सकते है या आप नीचे दिए हुए इन दो कुबरनेट्स प्लेग्राउंड का इस्तेमाल कर सकते हैं:
उदाहरणों में एक छोटे nginx वेबसर्वर का उपयोग किया गया है जो HTTP हेडर के माध्यम से प्राप्त अनुरोधों के स्रोत IP को प्रतिध्वनित करता है। आप इसे निम्न प्रकार से बना सकते हैं:
टिप्पणी:
निम्नलिखित कमांड में दी गई छवि केवल AMD64 आर्किटेक्चर पर चलती है।kubectl create deployment source-ip-app --image=registry.k8s.io/echoserver:1.4
आउटपुट है:
deployment.apps/source-ip-app created
उद्देश्य
- विभिन्न प्रकार की सेवाओं के माध्यम से एक सरल अनुप्रयोग को उजागर करें
- समझें कि प्रत्येक सेवा प्रकार स्रोत IP NAT को कैसे संभालता है
- स्रोत IP को संरक्षित करने में शामिल ट्रेडऑफ़ को समझें
Type=ClusterIP
वाली सेवाओं के लिए स्रोत IP
यदि आप kube-proxy को iptables मोड
(डिफ़ॉल्ट) में चला रहे हैं, तो क्लस्टर के भीतर से ClusterIP को भेजे गए पैकेट कभी भी स्रोत NAT'd नहीं होते हैं। आप kube-proxy मोड को उस नोड पर http://localhost:10249/proxyMode
लाकर क्वेरी कर सकते हैं जहाँ kube-proxy चल रहा है।
kubectl get nodes
इसका आउटपुट कुछ इस प्रकार है:
NAME STATUS ROLES AGE VERSION
kubernetes-node-6jst Ready <none> 2h v1.13.0
kubernetes-node-cx31 Ready <none> 2h v1.13.0
kubernetes-node-jj1t Ready <none> 2h v1.13.0
किसी एक नोड पर प्रॉक्सी मोड प्राप्त करें (kube-proxy पोर्ट 10249 पर सुनता है):
# Run this in a shell on the node you want to query.
curl http://localhost:10249/proxyMode
इसका आउटपुट कुछ इस प्रकार है:
iptables
आप स्रोत IP ऐप पर सेवा बनाकर स्रोत IP संरक्षण का परीक्षण कर सकते हैं:
kubectl expose deployment source-ip-app --name=clusterip --port=80 --target-port=8080
इसका आउटपुट कुछ इस प्रकार है:
service/clusterip exposed
kubectl get svc clusterip
इसका आउटपुट कुछ इस प्रकार है:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
clusterip ClusterIP 10.0.170.92 <none> 80/TCP 51s
और उसी क्लस्टर में एक पॉड से ClusterIP
को हिट करना:
kubectl run busybox -it --image=busybox:1.28 --restart=Never --rm
इसका आउटपुट कुछ इस प्रकार है:
Waiting for pod default/busybox to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
फिर आप उस पॉड के अंदर एक कमांड चला सकते हैं:
# Run this inside the terminal from "kubectl run"
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc noqueue
link/ether 0a:58:0a:f4:03:08 brd ff:ff:ff:ff:ff:ff
inet 10.244.3.8/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::188a:84ff:feb0:26a5/64 scope link
valid_lft forever preferred_lft forever
…फिर लोकल वेबसर्वर को क्वेरी करने के लिए wget
का उपयोग करें
# Replace "10.0.170.92" with the IPv4 address of the Service named "clusterip"
wget -qO - 10.0.170.92
CLIENT VALUES:
client_address=10.244.3.8
command=GET
...
client_address
हमेशा क्लाइंट पॉड का IP पता होता है, चाहे क्लाइंट पॉड और सर्वर पॉड एक ही नोड में हों या अलग-अलग नोड्स में हों।
Type=NodePort
वाली सेवाओं के लिए स्रोत IP
Type=NodePort
के साथ सेवाओं को भेजे गए पैकेट
डिफ़ॉल्ट रूप से स्रोत NAT'd होते हैं। आप NodePort
सेवा बनाकर इसका परीक्षण कर सकते हैं:
kubectl expose deployment source-ip-app --name=nodeport --port=80 --target-port=8080 --type=NodePort
इसका आउटपुट कुछ इस प्रकार है:
service/nodeport exposed
NODEPORT=$(kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services nodeport)
NODES=$(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }')
यदि आप क्लाउड प्रोवाइडर पर चल रहे हैं, तो आपको ऊपर बताए गए nodes:nodeport
के लिए फ़ायरवॉल-नियम खोलने की आवश्यकता हो सकती है। अब आप ऊपर आवंटित नोड पोर्ट के माध्यम से क्लस्टर के बाहर से सेवा तक पहुँचने का प्रयास कर सकते हैं।
for node in $NODES; do curl -s $node:$NODEPORT | grep -i client_address; done
इसका आउटपुट कुछ इस प्रकार है:
client_address=10.180.1.1
client_address=10.240.0.5
client_address=10.240.0.3
ध्यान दें कि ये सही क्लाइंट IP नहीं हैं, ये क्लस्टर के आंतरिक IP हैं। यह इस तरह काम करता है:
- क्लाइंट पैकेट को
node2:nodePort
पर भेजता है node2
पैकेट में मौजूद सोर्स IP एड्रेस (SNAT) को अपने IP एड्रेस से बदल देता हैnode2
पैकेट पर मौजूद डेस्टिनेशन IP को पॉड IP से बदल देता है- पैकेट को नोड 1 और फिर एंडपॉइंट पर भेजा जाता है
- पॉड का जवाब वापस नोड 2 पर भेजा जाता है
- पॉड का जवाब वापस क्लाइंट को भेजा जाता है
दृश्यात्मक रूप से:
Figure. Source IP Type=NodePort using SNAT
इससे बचने के लिए, Kubernetes में क्लाइंट स्रोत IP को संरक्षित करने की सुविधा है।
यदि आप service.spec.externalTrafficPolicy
को Local
मान पर सेट करते हैं, तो kube-proxy केवल स्थानीय एंडपॉइंट पर प्रॉक्सी अनुरोधों को प्रॉक्सी करता है, और ट्रैफ़िक को अन्य नोड्स पर अग्रेषित नहीं करता है। यह दृष्टिकोण मूल स्रोत IP पते को संरक्षित करता है। यदि कोई स्थानीय एंडपॉइंट नहीं हैं, तो नोड पर भेजे गए पैकेट ड्रॉप हो जाते हैं, इसलिए आप किसी भी पैकेट प्रोसेसिंग नियम में सही स्रोत-आईपी पर भरोसा कर सकते हैं, आप एक पैकेट लागू कर सकते हैं जो एंडपॉइंट तक पहुंचता है।
service.spec.externalTrafficPolicy
फ़ील्ड को निम्न प्रकार से सेट करें:
kubectl patch svc nodeport -p '{"spec":{"externalTrafficPolicy":"Local"}}'
इसका आउटपुट कुछ इस प्रकार है:
service/nodeport patched
अब, परीक्षण पुनः चलाएँ:
for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; done
आउटपुट इस प्रकार है:
client_address=198.51.100.79
ध्यान दें कि आपको केवल एक उत्तर मिला है, सही क्लाइंट IP के साथ, उस नोड से जिस पर एंडपॉइंट पॉड चल रहा है।
यह कुछ इस तरह काम करता है:
- क्लाइंट पैकेट को
node2:nodePort
पर भेजता है, जिसमें कोई एंडपॉइंट नहीं है - पैकेट को छोड़ दिया जाता है
- क्लाइंट पैकेट को
node1:nodePort
पर भेजता है, जिसमें एंडपॉइंट हैं - node1 पैकेट को सही सोर्स IP वाले एंडपॉइंट पर रूट करता है
दृश्यात्मक रूप से:
Figure. Source IP Type=NodePort preserves client source IP address
Type=LoadBalancer
वाली सेवाओं के लिए स्रोत IP
Type=LoadBalancer
के साथ सेवाओं को भेजे गए पैकेट
डिफ़ॉल्ट रूप से स्रोत NAT'd होते हैं, क्योंकि Ready
स्थिति में सभी शेड्यूल करने योग्य Kubernetes नोड लोड-बैलेंस्ड ट्रैफ़िक के लिए पात्र होते हैं। इसलिए यदि पैकेट बिना किसी एंडपॉइंट के नोड पर पहुंचते हैं, तो सिस्टम इसे एक एंडपॉइंट वाले नोड पर प्रॉक्सी करता है, पैकेट पर स्रोत IP को नोड के IP से बदल देता है (जैसा कि पिछले अनुभाग में वर्णित है)।
आप लोड बैलेंसर के माध्यम से स्रोत-आईपी-ऐप को उजागर करके इसका परीक्षण कर सकते हैं:
kubectl expose deployment source-ip-app --name=loadbalancer --port=80 --target-port=8080 --type=LoadBalancer
आउटपुट इस प्रकार है::
service/loadbalancer exposed
सेवा के आईपी पते का प्रिंट आउट लें:
kubectl get svc loadbalancer
आउटपुट इस प्रकार है:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
loadbalancer LoadBalancer 10.0.65.118 203.0.113.140 80/TCP 5m
इसके बाद, इस सेवा के बाहरी-आईपी को अनुरोध भेजें:
curl 203.0.113.140
आउटपुट इस प्रकार है:
CLIENT VALUES:
client_address=10.240.0.5
...
हालाँकि, यदि आप Google Kubernetes Engine/GCE पर चल रहे हैं, तो उसी service.spec.externalTrafficPolicy
फ़ील्ड को Local
पर सेट करने से सेवा समापन बिंदुओं के बिना नोड्स को जानबूझकर स्वास्थ्य जांच में विफल होने के कारण लोडबैलेंस्ड ट्रैफ़िक के लिए योग्य नोड्स की सूची से खुद को हटाने के लिए मजबूर होना पड़ता है।
दृश्यात्मक रूप से:
आप एनोटेशन सेट करके इसका परीक्षण कर सकते हैं:
kubectl patch svc loadbalancer -p '{"spec":{"externalTrafficPolicy":"Local"}}'
आपको तुरंत Kubernetes द्वारा आवंटित service.spec.healthCheckNodePort
फ़ील्ड दिखाई देगी:
kubectl get svc loadbalancer -o yaml | grep -i healthCheckNodePort
आउटपुट इस प्रकार है:
healthCheckNodePort: 32122
service.spec.healthCheckNodePort
फ़ील्ड /healthz
पर स्वास्थ्य जाँच करने वाले प्रत्येक नोड पर एक पोर्ट की ओर इशारा करता है।
आप इसका परीक्षण कर सकते हैं:
kubectl get pod -o wide -l app=source-ip-app
आउटपुट इस प्रकार है:
NAME READY STATUS RESTARTS AGE IP NODE
source-ip-app-826191075-qehz4 1/1 Running 0 20h 10.180.1.136 kubernetes-node-6jst
विभिन्न नोड्स पर /healthz
एंडपॉइंट लाने के लिए curl
का उपयोग करें:
# Run this locally on a node you choose
curl localhost:32122/healthz
1 Service Endpoints found
किसी भिन्न नोड पर आपको भिन्न परिणाम मिल सकता है:
# Run this locally on a node you choose
curl localhost:32122/healthz
No Service Endpoints Found
कंट्रोल प्लेन पर चलने वाला एक कंट्रोलर क्लाउड लोड बैलेंसर को आवंटित करने के लिए जिम्मेदार होता है। वही कंट्रोलर प्रत्येक नोड पर इस पोर्ट/पथ की ओर इशारा करते हुए HTTP स्वास्थ्य जांच भी आवंटित करता है। स्वास्थ्य जांच में विफल होने के लिए एंडपॉइंट के बिना 2 नोड्स के लिए लगभग 10 सेकंड प्रतीक्षा करें, फिर लोड बैलेंसर के IPv4 पते को क्वेरी करने के लिए curl
का उपयोग करें:
curl 203.0.113.140
आउटपुट इस प्रकार है:
CLIENT VALUES:
client_address=198.51.100.79
...
क्रॉस-प्लेटफ़ॉर्म समर्थन
केवल कुछ क्लाउड प्रदाता ही Type=LoadBalancer
वाली सेवाओं के माध्यम से स्रोत IP संरक्षण के लिए समर्थन प्रदान करते हैं।
आप जिस क्लाउड प्रदाता पर काम कर रहे हैं, वह कुछ अलग-अलग तरीकों से लोडबैलेंसर के लिए अनुरोध को पूरा कर सकता है:
-
एक प्रॉक्सी के साथ जो क्लाइंट कनेक्शन को समाप्त करता है और आपके नोड्स/एंडपॉइंट्स के लिए एक नया कनेक्शन खोलता है। ऐसे मामलों में स्रोत IP हमेशा क्लाउड LB का होगा, क्लाइंट का नहीं।
-
एक पैकेट फ़ॉरवर्डर के साथ, जैसे कि क्लाइंट से लोडबैलेंसर VIP को भेजे गए अनुरोध क्लाइंट के स्रोत IP वाले नोड पर समाप्त होते हैं, न कि किसी मध्यवर्ती प्रॉक्सी पर।
पहली श्रेणी के लोड बैलेंसर को लोडबैलेंसर और बैकएंड के बीच HTTP फॉरवर्डेड या X-FORWARDED-FOR हेडर या
प्रॉक्सी प्रोटोकॉल जैसे वास्तविक क्लाइंट IP को संप्रेषित करने के लिए सहमत प्रोटोकॉल का उपयोग करना चाहिए। दूसरी श्रेणी के लोड बैलेंसर सेवा पर service.spec.healthCheckNodePort
फ़ील्ड में संग्रहीत पोर्ट पर इंगित HTTP स्वास्थ्य जांच बनाकर ऊपर वर्णित सुविधा का लाभ उठा सकते हैं।
सफाई करना
सेवाएँ समाप्त करें:
kubectl delete svc -l app=source-ip-app
डिप्लॉयमेंट, रेप्लिका सेट और पॉड को समाप्त करें:
kubectl delete deployment source-ip-app
आगे क्या है
- सेवाओं के माध्यम से एप्लिकेशन कनेक्ट करने के बारे में अधिक जानें
- बाहरी लोड बैलेंसर बनाने का तरीका पढ़ें
3 - पॉड्स और उनके एंडपॉइंट्स के लिए समाप्ति व्यवहार का अन्वेषण करें
एक बार जब आप अपने एप्लिकेशन को सेवा से कनेक्ट कर लेते हैं, तो एप्लिकेशन को सेवाओं से कनेक्ट करना में बताए गए चरणों का पालन करते हुए, आपके पास एक निरंतर चलने वाला, प्रतिकृति एप्लिकेशन होता है, जो नेटवर्क पर प्रदर्शित होता है। यह ट्यूटोरियल आपको पॉड्स के लिए समाप्ति प्रवाह को देखने और सुंदर कनेक्शन ड्रेनिंग को लागू करने के तरीकों का पता लगाने में मदद करता है।
पॉड्स और उनके एन्डपॉइन्ट्स के लिए समाप्ति प्रक्रिया
अक्सर ऐसे मामले होते हैं जब आपको पॉड को समाप्त करने की आवश्यकता होती है - चाहे वह अपग्रेड के लिए हो या स्केल डाउन के लिए। एप्लिकेशन की उपलब्धता में सुधार करने के लिए, उचित सक्रिय कनेक्शन ड्रेनिंग को लागू करना महत्वपूर्ण हो सकता है। यह ट्यूटोरियल अवधारणा को प्रदर्शित करने के लिए एक सरल nginx वेब सर्वर का उपयोग करके संगत एंडपॉइंट स्थिति और निष्कासन के संबंध में पॉड समाप्ति के प्रवाह की व्याख्या करता है।
Example flow with endpoint termination
निम्नलिखित उदाहरण पॉड्स की समाप्ति दस्तावेज़ में वर्णित प्रवाह है।
मान लीजिए कि आपके पास एक एकल nginx
प्रतिकृति (केवल प्रदर्शन उद्देश्यों के लिए) और एक सेवा युक्त डिप्लॉयमेंट है:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 120 # extra long grace period
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
lifecycle:
preStop:
exec:
# Real life termination may take any time up to terminationGracePeriodSeconds.
# In this example - just hang around for at least the duration of terminationGracePeriodSeconds,
# at 120 seconds container will be forcibly terminated.
# Note, all this time nginx will keep processing requests.
command: [
"/bin/sh", "-c", "sleep 180"
]
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
अब उपरोक्त फ़ाइलों का उपयोग करके डिप्लॉयमेंट पॉड और सेवा बनाएँ:
kubectl apply -f pod-with-graceful-termination.yaml
kubectl apply -f explore-graceful-termination-nginx.yaml
एक बार पॉड और सेवा चलने के बाद, आप किसी भी संबद्ध एंडपॉइंटस्लाइस का नाम प्राप्त कर सकते हैं:
kubectl get endpointslice
इसका आउटपुट कुछ इस प्रकार है:
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
nginx-service-6tjbr IPv4 80 10.12.1.199,10.12.1.201 22m
आप इसकी स्थिति देख सकते हैं, और पुष्टि कर सकते हैं कि एक एंडपॉइन्ट पंजीकृत है:
kubectl get endpointslices -o json -l kubernetes.io/service-name=nginx-service
इसका आउटपुट कुछ इस प्रकार है:
{
"addressType": "IPv4",
"apiVersion": "discovery.k8s.io/v1",
"endpoints": [
{
"addresses": [
"10.12.1.201"
],
"conditions": {
"ready": true,
"serving": true,
"terminating": false
अब आइए पॉड को समाप्त करें और सत्यापित करें कि पॉड को अनुग्रहपूर्ण समाप्ति अवधि (graceful termination period) कॉन्फ़िगरेशन का सम्मान करते हुए समाप्त किया जा रहा है:
kubectl delete pod nginx-deployment-7768647bf9-b4b9s
सभी पॉड्स की जानकारी प्राप्त करें:
kubectl get pods
इसका आउटपुट कुछ इस प्रकार है:
NAME READY STATUS RESTARTS AGE
nginx-deployment-7768647bf9-b4b9s 1/1 Terminating 0 4m1s
nginx-deployment-7768647bf9-rkxlw 1/1 Running 0 8s
आप देख सकते हैं कि नया पॉड शेड्यूल हो गया है।
जब तक नए पॉड के लिए नया एंडपॉइंट बनाया जा रहा है, पुराना एंडपॉइंट अभी भी टर्मिनेटिंग अवस्था में है:
kubectl get endpointslice -o json nginx-service-6tjbr
इसका आउटपुट कुछ इस प्रकार है:
{
"addressType": "IPv4",
"apiVersion": "discovery.k8s.io/v1",
"endpoints": [
{
"addresses": [
"10.12.1.201"
],
"conditions": {
"ready": false,
"serving": true,
"terminating": true
},
"nodeName": "gke-main-default-pool-dca1511c-d17b",
"targetRef": {
"kind": "Pod",
"name": "nginx-deployment-7768647bf9-b4b9s",
"namespace": "default",
"uid": "66fa831c-7eb2-407f-bd2c-f96dfe841478"
},
"zone": "us-central1-c"
},
{
"addresses": [
"10.12.1.202"
],
"conditions": {
"ready": true,
"serving": true,
"terminating": false
},
"nodeName": "gke-main-default-pool-dca1511c-d17b",
"targetRef": {
"kind": "Pod",
"name": "nginx-deployment-7768647bf9-rkxlw",
"namespace": "default",
"uid": "722b1cbe-dcd7-4ed4-8928-4a4d0e2bbe35"
},
"zone": "us-central1-c"
इससे एप्लिकेशन को समाप्ति के दौरान अपनी स्थिति के बारे में बताने की अनुमति मिलती है और क्लाइंट (जैसे लोड बैलेंसर) को कनेक्शन ड्रेनिंग कार्यक्षमता को लागू करने की अनुमति मिलती है। ये क्लाइंट समाप्ति के समापन बिंदुओं का पता लगा सकते हैं और उनके लिए एक विशेष तर्क लागू कर सकते हैं।
Kubernetes में, समाप्त होने वाले एंडपॉइंट की ready
स्थिति हमेशा false
के रूप में सेट होती है।
बैकवर्ड संगतता के लिए ऐसा होना ज़रूरी है, ताकि मौजूदा लोड बैलेंसर इसका इस्तेमाल नियमित ट्रैफ़िक के लिए न करें। अगर समाप्त होने वाले पॉड पर ट्रैफ़िक ड्रेनिंग की ज़रूरत है, तो वास्तविक तत्परता को सर्विंग
की स्थिति के रूप में जाँचा जा सकता है।
जब पॉड समाप्त हो जाता है, तो पुराना एंडपॉइंट भी साथ ही साथ समाप्त हो जाएगा।
आगे क्या है
- जानें कि एप्लिकेशन को सेवाओं से कैसे कनेक्ट करें
- क्लस्टर में किसी एप्लिकेशन तक पहुंचने के लिए सेवा का उपयोग करना के बारे में अधिक जानें
- सेवा का उपयोग करके फ्रंट एंड को बैक एंड से कनेक्ट करना के बारे में अधिक जानें
- बाहरी लोड बैलेंसर बनाने के बारे में अधिक जानें