1. 程式人生 > 其它 >Kubernetes之Service服務發現

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. 啟動該資源;
kubectlapply-fnginx-pod.yaml
  1. 進入容器內部,檢視系統的環境變數;
#進入容器內部
kubectlexec-itnginx-deployment--/bin/bash
#檢視環境變數
env|grepNGINX
  1. 通過環境變數訪問服務資訊;
curlhttp://${NGINX_SERVICE_SERVICE_HOST}
DNS方式
  1. 通過DNS解析方式在容器內部訪問;
curlhttp://nginx-service.default.svc.cluster.local

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

#檢查deployment
kubectlgetdeployment--namespace=kube-system
#檢查service
kubectlgetservices--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為案例;
kubectlgetpod-owide
  1. 使用nslookup進行驗證;
kubectlexecbusybox--nslookup10-100-1-103.default.pod.cluster.local

對於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;
kubectldelete-fnginx-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. 建立資源;
kubectlapply-fbusybox-headless-service.yaml
kubectlapply-fbusybox-pod1.yaml
  1. 進入Pod檢查DNS是否寫入,其他Pod就可以通過busybox-1.default-subdomain.default.svc.cluster.local來訪問該Pod;
kubectlexec-itbusybox1--/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列表合併去重;