一、概述
為了適應快速的業務需求,微服務架構已經逐漸成為主流,微服務架構的應用需要有非常好的服務編排支持,k8s中的核心要素Service便提供了一套簡化的服務代理和發現機制,天然適應微服務架構,任何應用都可以非常輕易地運行在k8s中而無須對架構進行改動;
k8s分配給Service一個固定IP,這是一個虛擬IP(也稱為ClusterIP),並不是一個真實存在的IP,而是由k8s虛擬出來的。虛擬IP的范圍通過k8s API Server的啟動參數 --service-cluster-ip-range=19.254.0.0/16配置;
虛擬IP屬於k8s內部的虛擬網絡,外部是尋址不到的。在k8s系統中,實際上是由k8s Proxy組件負責實現虛擬IP路由和轉發的,所以k8s Node中都必須運行了k8s Proxy,從而在容器覆蓋網絡之上又實現了k8s層級的虛擬轉發網絡。
服務代理:
在邏輯層面上,Service被認為是真實應用的抽象,每一個Service關聯着一系列的Pod。在物理層面上,Service有事真實應用的代理服務器,對外表現為一個單一訪問入口,通過k8s Proxy轉發請求到Service關聯的Pod。
Service同樣是根據Label Selector來刷選Pod進行關聯的,實際上k8s在Service和Pod之間通過Endpoint銜接,Endpoints同Service關聯的Pod;相對應,可以認為是Service的服務代理后端,k8s會根據Service關聯到Pod的PodIP信息組合成一個Endpoints。
1 #kubectl get service my-nginx 2 #kubectl get pod --selector app=nginx 3 k8s創建Service的同時,會自動創建跟Service同名的Endpoints: 4 #kubectl get endpoints my-nginx -o yaml 5 #kubectl describe service my-nginx
Service不僅可以代理Pod,還可以代理任意其他后端,比如運行在k8s外部的服務。加速現在要使用一個Service代理外部MySQL服務,不用設置Service的Label Selector。
Service的定義文件: mysql-service.yaml:
1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: mysql 5 spec: 6 ports: 7 - port: 3306 8 targetPort: 3306 9 protocol: TCP
同時定義跟Service同名的Endpoints,Endpoints中設置了MySQL的IP:192.168.3.180;
Endpoints的定義文件mysql-endpoints.yaml:
1 apiVersion: v1 2 kind: Endpoints 3 metadata: 4 name: mysql 5 subsets: 6 - addresses: 7 - ip: 192.168.39.175 8 ports: 9 - port: 3306 10 protocol: TCP
#kubectl create -f mysql-service.yaml -f mysql-endpoints.yaml
微服務化應用的每一個組件都以Service進行抽象,組件與組件之間只需要訪問Service即可以互相通信,而無須感知組件的集群變化。
這就是服務發現;
#kubectl exec my-pod -- nslookup my-service.my-ns --namespace=default
#kubectl exec my-pod -- nslookup my-service --namespace=my-ns
二、Service發布
k8s提供了NodePort Service、 LoadBalancer Service和Ingress可以發布Service;
NodePort Service
NodePort Service是類型為NodePort的Service, k8s除了會分配給NodePort Service一個內部的虛擬IP,另外會在每一個Node上暴露端口NodePort,外部網絡可以通過[NodeIP]:[NodePort]訪問到Service。
LoadBalancer Service (需要底層雲平台支持創建負載均衡器,比如GCE)
LoadBalancer Service是類型為LoadBalancer的Service,它是建立在NodePort Service集群基礎上的,k8s會分配給LoadBalancer;Service一個內部的虛擬IP,並且暴露NodePort。除此之外,k8s請求底層雲平台創建一個負載均衡器,將每個Node作為后端,負載均衡器將轉發請求到[NodeIP]:[NodePort]。
1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: my-nginx 5 spec: 6 selector: 7 app: nginx 8 ports: 9 - name: http 10 port: 80 11 targetPort: 80 12 protocol: TCP 13 type: LoadBalancer
負載均衡器由底層雲平台創建提供,會包含一個LoadBalancerIP, 可以認為是LoadBalancer Service的外部IP,查詢LoadBalancer Service:
#kubectl get svc my-nginx
Ingress
k8s提供了一種HTTP方式的路由轉發機制,稱為Ingress。Ingress的實現需要兩個組件支持, Ingress Controller和HTTP代理服務器。HTTP代理服務器將會轉發外部的HTTP請求到Service,而Ingress Controller則需要監控k8s API,實時更新HTTP代理服務器的轉發規則;
1 apiVersion: extensions/v1beta1 2 kind: Ingress 3 metadata: 4 name: my-ingress 5 spec: 6 rules: 7 - host: my.example.com 8 http: 9 paths: 10 - path: /app 11 backend: 12 serviceName: my-app 13 servicePort: 80
Ingress 定義中的.spec.rules 設置了轉發規則,其中配置了一條規則,當HTTP請求的host為my.example.com且path為/app時,轉發到Service my-app的80端口;
#kubectl create -f my-ingress.yaml; kubectl get ingress my-ingress
NAME RULE BACKEND ADDRESS
my-ingress -
my.example.com
/app my-app:80
當Ingress創建成功后,需要Ingress Controller根據Ingress的配置,設置HTTP代理服務器的轉發策略,外部通過HTTP代理服務就
可以訪問到Service;
