第八章 Service和Ingress
1 Service資源的基礎應用
1.1 建立Service資源
建立Service物件的常用方法有兩種:一是直接使用"kubectl expose"命令;另一種是使用資源配置檔案,它與此前使用的資源清單檔案配置其他資源的方法類似。
1.1.1 第一種方法:
pod(po),service(svc),replication controller(rc),deployment(deploy),replica set(rs)
Kubectl語法
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]
示例:
為rc的nginx建立一個service,該服務位於埠80上,並連線到埠8000的容器上。
# kubectl expose rc nginx --port=80 --target-port=8000
為deploy建立一個型別為NodePort的,對外暴露埠為80,名稱為myapp的服務
# kubectl expose deployment myapp --type=”NodePort" --port=8O --name=myapp
注意:Service資源的預設型別為ClusterIP,它僅能接收來自於叢集內的Pod物件中的客戶端程式的訪問請求。
1.1.2 第二種方法:
定義Service資源物件時,spec的兩個較為常用的內嵌欄位分別為selector和ports,分別用於定義使用的標籤選擇器和要暴露的埠。
apiVersion: v1 kind: Service metadata: name: myapp-svc spec: selector: app:myapp ports: - protocol: TCP port: 80 targetPort: 80
2 Service會話粘性
Service資源還支援Session affinity(會話粘性)機制,它能將來自同一個客戶端的請求始終轉發至同一個後端的Pod物件,這意味著他會影響排程演算法的流量分發功能,進而降低其負載均衡的效果。
Session affinity的效果僅會在一定時間期限內生效,預設值為10800秒,超出此時長之後,客戶端再次訪問被排程演算法重新排程。另外,Service資源的Session affinity機制僅能基於客戶端IP地址識別客戶端身份,他會把經由同一個NAT伺服器進行源地址轉發的所有客戶端識別為同一個客戶端,排程粒度粗糙且效果不佳,因此,實踐中並不推薦使用此種方法實現粘性會話。
Service資源通過.spec.sessionAffinity和.spec.sessionAffinityConfig兩個欄位配置粘性會話。spec.sessionAffinity欄位用於定義要使用的粘性會話型別,它僅支援使用“None”和“ClientIp”兩種屬性。
- None:不使用sessionAffinity,預設值
- ClientIP:基於客戶端IP地址識別客戶端身份,把來自同一個源IP地址的請求始終排程至同一個Pod物件
在啟用粘性會話機制時,.spec.sessionAffinityConfig用於配置會話保持時長,他是一個巢狀欄位,使用格式如下,可用時長範圍為“1-86400”,預設為10800秒
spec:
sessionAffinity: ClientIp
sessionAffinityConfig:
clientIP:
timeoutSeconds: <integer>
3 服務暴露
Service的IP地址僅在叢集內可達,然而,總會有些服務需要暴露到外部網路中接收各類客戶端的訪問,此時,就需要在叢集邊緣為其新增一層轉發機制,已實現外部請求流量接入到叢集的Service資源之上,這種操作也成為釋出服務到外部網路中。
3.1 Service型別
Kubernetes的Service共有四種類型:ClusterIP、NodePort、LoadBalancer和ExternalName。
- ClusterIP:通過叢集內部IP地址暴露服務,此地址僅在叢集內部可達,而無法被叢集外部的客戶端訪問。此為預設的Service型別
- NodePort:這種型別建立在ClusterIP型別之上,其在每個Node節點的某靜態埠暴露服務,簡單來說,NodePort型別就是在工作節點的IP地址上選擇一個埠用於將叢集外部的使用者請求轉發至目標Service的ClusterIP和Port,因此,這種型別的Service既可如ClusterIP一樣受到叢集內部客戶端Pod的訪問,可會受到叢集外部客戶端通過套接字<NodeIP>:<NodePort>進行請求。
- LoadBalancer:這種型別構建在NodePort型別之上,也就是通過公有云LB將NodePort暴露的<NodeIP>:<NodePort>配置在LB上,實現負載均衡
- ExternalName:目的是讓叢集內的Pod資源能夠訪問外部的Service的一種實現方式
3.2 NodePort型別的Service資源
apiVersion: v1 kind: Service metadata: name: myapp-svc-nodeport spec: type: NodePort selector: app:myapp ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 32223 ============================== port: 80 #表示service埠 targetPort: 80 #表示Pod容器埠 nodePort: 32223 #表示Node節點暴露埠
3.3 LoadBalancer型別的Service資源
NodePort型別的Service資源雖然能夠於叢集外部訪問,但外部客戶端必須得事先得知NodePort和叢集中至少一個節點的IP地址,且選定的節點發生故障時,客戶端還得自行選擇請求訪問其他節點,另外,叢集節點很可能是某IaaS雲環境中使用私有IP地址的VM,或者是IDC中使用的私有地址的物理機,這類地址對網際網路客戶端不可達,因為,一般,還應該在叢集外建立一個具有公網IP地址的負載均衡器,由他接入外部客戶端的請求並排程至叢集節點相應的NodePort之上。
apiVersion: v1 kind: Service metadata: name: myapp-svc-lb spec: type: LoadBalancer selector: app:myapp ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 32223
3.4 ExternalName Service
ExternalName型別的Service資源用於將叢集外部的服務釋出到叢集中以供Pod中的應用程式訪問,因此,它不需要使用標籤選擇器關聯任何的Pod物件,但必須要使用spec.externalName屬性定義一個CNAME記錄用於返回外部真正提供服務的主機的別名,而後通過CNAME記錄值獲取到相關主機的IP地址。
apiVersion: v1 kind: Service metadata : name : external-redis-svc namespace: default spec: type: ExternalName externaIName : redis.ilinux.io ports: - protocol: TCP port: 6379 targetPort: 6379 nodePort: 0 selector: {}
待Service資源external-redis-svc建立完成後,各Pod物件即可通過external-redis-svc或其FQDN格式個名稱external-redis-svc.default.svc.cluster.local訪問相應的服務。