【Kubernetes詳解】(八)k8s 之 Service 詳解一

一、Service定義詳解

YAML格式的Service定義文件的完整內容如下:
在這裏插入圖片描述
對各屬性的說明如下表所示:
在這裏插入圖片描述
在這裏插入圖片描述

二、Service的基本用法

2.1、創建Service

一般來說,對外提供服務的應用程序需要通過某種機制來實現,對於容器應用最簡便的方式就是通過TCP/IP機制及監聽IP和端口號來實現。
直接通過Pod的IP地址和端口號可以訪問到容器應用內的服務,但是Pod的IP地址是不可靠的,並且Pod的地址只能在K8S集羣內訪問到,例如:當Pod所在的Node發生故障時,Pod將被Kubernetes重新調度到另一個Node,Pod的IP地址將發生變化。更重要的是,如果容器應用本身是分佈式的部署方式,通過多個實例共同提供服務,就需要在這些實例的前端設置一個負載均衡器來實現請求的分發。Kubernetes中的Service就是用於解決這些問題的核心組件。

  • pod ip地址變化問題
  • 多pod負載均衡問題

兩種創建Service的方式:

  • 通過expose 命令創建
# 通過 expose 命令創建,端口默認與Pod端口保持一致
$ kubectl expose <rc> <rc-name>
  • 通過yaml文件創建
    在這裏插入圖片描述
    Service定義中的關鍵字段是ports和selector。上例中ports定義部分指定了Service所需的虛擬端口號爲8081,由於與Pod容器端口號8080不一 樣,所以需要再通過targetPort來指定後端Pod的端口號。selector定義部分設置的是後端Pod所擁有的label:app=webapp。

可以通過如下命令來查看ClusterIp和端口:

$ kubectl get svc -n <namespace>

在這裏插入圖片描述

2.2、負載分發策略

  • RoundRobin:輪詢模式,即輪詢將請求轉發到後端的各個Pod 上。
  • SessionAffinity:基於客戶端IP地址進行會話保持的模式,即第 1次將某個客戶端發起的請求轉發到後端的某個Pod上,之後從相同的客 戶端發起的請求都將被轉發到後端相同的Pod上。

在默認情況下,Kubernetes採用RoundRobin模式對客戶端請求進行負載分發,但我們也可以通過設置service.spec.sessionAffinity=ClientIP來啓用SessionAffinity策略。這樣,同一個客戶端IP發來的請求就會被轉發到後端固定的某個Pod上了。
通過Service的定義,Kubernetes實現了一種分佈式應用統一入口的定義和負載均衡機制。Service還可以進行其他類型的設置,例如:設置多個端口號、直接設置爲集羣外部服務,或實現爲Headless Service(無頭 服務)模式。

2.3、多端口Service

有時一個容器應用也可能提供多個端口的服務,那麼在Service的定 義中也可以相應地設置爲將多個端口對應到多個應用服務。示例:
在這裏插入圖片描述

三、Headless Service

在某些應用場景中,開發人員希望自己控制負載均衡的策略,不使 用Service提供的默認負載均衡的功能,或者應用程序希望知道屬於同組 服務的其他實例。Kubernetes提供了Headless Service來實現這種功能, 即不爲Service設置ClusterIP(入口IP地址),僅通過Label Selector將後 端的Pod列表返回給調用的客戶端。例如:
在這裏插入圖片描述

四、從集羣外部訪問Pod或Service

由於Pod和Service都是Kubernetes集羣範圍內的虛擬概念,所以集羣 外的客戶端系統無法通過Pod的IP地址或者Service的虛擬IP地址和虛擬 端口號訪問它們。爲了讓外部客戶端可以訪問這些服務,可以將Pod或 Service的端口號映射到宿主機,以使客戶端應用能夠通過物理機訪問容器應用。

4.1、將容器應用的端口號映射到物理機

4.1.1、通過設置容器級別的hostPort,將容器應用的端口號映射到物理機上:

在這裏插入圖片描述

4.1.2、通過設置Pod級別的hostNetwork=true

該Pod中所有容器的端 口號都將被直接映射到物理機上。在設置hostNetwork=true時需要注 意,在容器的ports定義部分如果不指定hostPort,則默認hostPort等於 containerPort,如果指定了hostPort,則hostPort必須等於containerPort的值:
在這裏插入圖片描述

4.2、將Service的端口號映射到物理機

4.2.1、通過設置nodePort映射到物理機,同時設置Service的類型爲NodePort

在這裏插入圖片描述

4.2.2、通過設置LoadBalancer映射到雲服務商提供的LoadBalancer地 址。這種用法僅用於在公有云服務提供商的雲平臺上設置Service的場景。

五、DNS服務搭建和配置指南

作爲服務發現機制的基本功能,在集羣內需要能夠通過服務名對服 務進行訪問,這就需要一個集羣範圍內的DNS服務來完成從服務名到 ClusterIP的解析。
DNS服務在Kubernetes的發展過程中經歷了3個階段:
SkyDNS -> KubeDNS -> CoreDNS
Kubernetes集羣的DNS服務由CoreDNS 提供。CoreDNS是CNCF基金會的一個項目,是用Go語言實現的高性能、插件式、易擴展的DNS服務端。CoreDNS解決了KubeDNS的一些問題,例如dnsmasq的安全漏洞、externalName不能使用stubDomains設置,等等。
CoreDNS支持自定義DNS記錄及配置upstream DNS Server,可以統一管理Kubernetes基於服務的內部DNS和數據中心的物理DNS。
CoreDNS沒有使用多個容器的架構,只用一個容器便實現了 KubeDNS內3個容器的全部功能。

在這裏插入圖片描述

下面以CoreDNS爲例說明Kubernetes集羣DNS服務的搭建過程:

5.1、在創建DNS服務之前修改每個Node上 kubelet 的啓動參數

修改每個Node上kubelet的啓動參數,加上以下兩個參數。

--cluster-dns=169.169.0.100:爲DNS服務的ClusterIP地址。 
--cluster-domain=cluster.local:爲在DNS服務中設置的域名。

然後重啓kubelet服務。

5.2、創建CoreDNS應用

在部署CoreDNS應用前,至少需要創建一個ConfigMap、一個 Deployment和一個Service共3個資源對象。在啓用了RBAC的集羣中,還 可以設置ServiceAccount、ClusterRole、ClusterRoleBinding對CoreDNS容器進行權限設置。

  • ConfigMap “coredns”主要設置CoreDNS的主配置文件Corefile的內容,其中可以定義各種域名的解析方式和使用的插件;
  • Deployment “coredns”主要設置CoreDNS容器應用的內容;其中,replicas副本的數量通常應該根據集羣的規模和服務數量確定,如果單個CoreDNS進程不足以支撐整個集羣的DNS查詢,則可以通過水平擴展提高查詢能力。由於DNS服務是Kubernetes集羣的關鍵核心服務,所以建議爲其Deployment設置自動擴縮容控制器,自動管理其副本數量;另外,對資源限制部分(CPU限制和內存限制)的設置也應根據實際環境進行調整;
  • Service “coredns”是DNS服務的配置,這個服務需要設置固定的ClusterIP,也需要將所有Node上的kubelet 啓動參數–cluster-dns設置爲這個ClusterIP;

5.3、CoreDNS的配置說明

CoreDNS的主要功能是通過插件系統實現的。CoreDNS實現了一種 鏈式插件結構,將DNS的邏輯抽象成了一個個插件,能夠靈活組合使用。
常用的插件如下:

  • loadbalance:提供基於DNS的負載均衡功能。
  • loop:檢測在DNS解析過程中出現的簡單循環問題。
  • cache:提供前端緩存功能。
  • health:對Endpoint進行健康檢查。
  • kubernetes:從Kubernetes中讀取zone數據。
  • etcd:從etcd讀取zone數據,可以用於自定義域名記錄。
  • file:從RFC1035格式文件中讀取zone數據。
  • hosts:使用/etc/hosts文件或者其他文件讀取zone數據,可以用 於自定義域名記錄。
  • auto:從磁盤中自動加載區域文件。
  • reload:定時自動重新加載Corefile配置文件的內容。
  • forward:轉發域名查詢到上游DNS服務器。
  • proxy:轉發特定的域名查詢到多個其他DNS服務器,同時提 供到多個DNS服務器的負載均衡功能。
  • prometheus:爲Prometheus系統提供採集性能指標數據的 URL。
  • pprof:在URL路徑/debug/pprof下提供運行時的性能數據。 ◎ log:對DNS查詢進行日誌記錄。
  • errors:對錯誤信息進行日誌記錄。

在下面的示例中爲域名“cluster.local”設置了一系列插件,包括 errors、health、kubernetes、prometheus、forward、cache、loop、reload 和loadbalance,在進行域名解析時,這些插件將以從上到下的順序依次執行:
在這裏插入圖片描述

5.4、Pod級別的DNS配置說明

除了使用集羣範圍的DNS服務(如CoreDNS),在Pod級別也能設置DNS的相關策略和配置。
在Pod的Y AML配置文件中通過spec.dnsPolicy字段設置DNS策略。
目前可以設置的DNS策略如下:

  • Default:繼承Pod所在宿主機的DNS設置。
  • ClusterFirst:優先使用Kubernetes環境的DNS服務(如 CoreDNS提供的域名解析服務),將無法解析的域名轉發到從宿主機繼 承的DNS服務器。
  • ClusterFirstWithHostNet:與ClusterFirst相同,對於以 hostNetwork模式運行的Pod,應明確指定使用該策略。
  • None:忽略Kubernetes環境的DNS配置,通過spec.dnsConfig自定義DNS配置。這個選項從Kubernetes 1.9版本開始引入,到Kubernetes 1.10版本升級爲Beta版,到Kubernetes 1.14版本升級爲穩定版。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章