Kubernetes之Service服務發現


服務發現

Kubernetes提供兩種客戶端以固定方式獲取后端訪問地址的方式:環境變量和DNS方式。

環境變量

該實驗以上文中的nginx-deployment.yaml和nginx-service.yaml為基礎;

  1. 新建一個Pod資源,文件名為nginx-pod.yaml;
apiVersion: v1 kind: Pod metadata:   name: nginx-deployment spec:   containers:   - name: nginx     image: nginx:latest     resources:       limits:         memory: "128Mi"         cpu: "500m"     ports:       - containerPort: 80 
  1. 啟動該資源;
kubectl apply -f nginx-pod.yaml 
  1. 進入容器內部,查看系統的環境變量;
#進入容器內部 kubectl exec -it nginx-deployment -- /bin/bash #查看環境變量 env | grep NGINX 

 

  1. 通過環境變量訪問服務信息;
curl http://${NGINX_SERVICE_SERVICE_HOST} 

 

DNS方式
  1. 通過DNS解析方式在容器內部訪問;
curl http://nginx-service.default.svc.cluster.local 

相比於環境變量來說,DNS域名格式的Service名稱提供的穩定、不變的訪問地址,可以簡化客戶端的應用配置,是Kubernetes推薦的方式。當Service以DNS形式進行訪問的時候,需要在集群中存在一個DNS服務器來完成域名到ClusterIP的地址解析工作,kubeadm在初始化的時候已經完kube-dns的安裝,這個里要注意一個問題,就是使用busybox解析Service時候,最新版本是有問題的,我采用了1.28.3版本,對於服務中心中是否安裝kube-dns可以通過以下方式檢查:

#檢查deployment kubectl get deployment --namespace=kube-system #檢查service kubectl get services --namespace=kube-system 

Service在Kubernetes中遵守DNS命名規范,Service的DNS域名表示方法為servicename.namespace.svc.clusterdomain,其中servicename為服務名稱,namespace為所在的名空間,clusterdomain為Kubernetes中集群設置的域名后綴,此外如果Service定義中設置了名稱,該端口會擁有一個DNS域名,在DNS服務器中保存格式為:_portname._protocol.servicename.namespace.svc.clusterdomain,其值為端口號的數值。

 

Pod的DNS相關特征

Pod作為集群中提供服務的實體,也可以設置DNS域名,Kubernetes為Pod使用的DNS策略提供很多種方式。

Pod的DNS

對於Pod來說,Kubernetes會為其設置一個pod-ip.namespace.pod.cluster-domain格式的DNS域名,其中Pod的IP需要使用-替換.,我們通過nslookup來證明一下;

  1. 查看Pod的IP信息,我們使用niginx-deployment的Pod為案例;
kubectl get pod -o wide 

 

  1. 使用nslookup進行驗證;
kubectl exec busybox -- nslookup 10-100-1-103.default.pod.cluster.local 

image.png

對於Deployment和Daement類型的創建的Pod來說,Kubernetes會為每個Pod設置一個DNS域名,格式為pod-ip.deployment-name/daement-name.namespace.svc.cluster-domain,Pod的IP也需要使用-替換.

為Pod設置hostname和subdomain

當前,創建Pod時其主機名取自Pod的metadata.name,在定義Pod的yaml文件中包含一個可選的 hostname 字段,可以用來指定Pod的主機名。 當這個字段被設置時,它將優先於Pod的名字成為該 Pod 的主機名。此外還有一個字段subdomain 字段,可以用來指定 Pod的子域名。

  1. 刪除所有Pod;
kubectl delete -f nginx-pod.yaml 
  1. 創建busybox-headless-service.yaml文件,這里Headless Service與Pod子域名保持一致,這樣子DNS服務器才會自動創建響應的DNS記錄;
apiVersion: v1 kind: Service metadata:   name: default-subdomain spec:   selector:     name: busybox   clusterIP: None   ports:   - name: foo # 實際上不需要指定端口號     port: 1234     targetPort: 1234 
  1. 創建nginx-pod.yaml文件;
apiVersion: v1 kind: Pod metadata:   name: busybox1   labels:     name: busybox spec:   hostname: busybox-1   subdomain: default-subdomain   containers:   - image: busybox:1.28.3     command:       - sleep       - "3600"     name: busybox 
  1. 創建資源;
kubectl apply -f busybox-headless-service.yaml kubectl apply -f busybox-pod1.yaml 
  1. 進入Pod檢查DNS是否寫入,其他Pod就可以通過busybox-1.default-subdomain.default.svc.cluster.local來訪問該Pod;
kubectl exec -it busybox1 -- /bin/sh cat /etc/hosts 

 

Pod的DNS策略

Kubernetes可以通過Pod中dnsPolicy屬性指定DNS相關策略,目前支持以下四種策略:

  1. Default: 繼承Pod所在的節點的域名解析設置;

  2. ClusterFirst: 優先使用Kubernetes提供的DNS服務(CoreDNS),將無法解析域名轉發到系統配置的DNS服務器;

  3. ClusterFirstWithHostNet:適用於以hostNetWork方式運行的Pod;

  4. None:忽略Kubernetes提供的DNS配置,采用自定義的配置方式;

Pod自定義DNS配置

Kubernetes可以通過Pod的dnsConfig屬性來自定義DNS相關配置,同時必須指定dnsPolicy為None。

自定義DNS可以在dnsConfig指定以下屬性:

nameservers: 用於域名解析DNS服務列表,最多可以設置3個,當 Pod的dnsPolicy設置為none時, 列表必須至少包含一個 IP 地址。配置的nameserver列表與系統自動設置的nameserver自動合並去重;

searches: 用於域名搜索的DNS域名后綴,最多設置6個,也會與系統自動設置的search列表合並去重;

options:配置其他可選的DNS參數,以name或者name/value的形式表示,系統也會自動設置option列表合並去重;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM