原文:https://wenda.swoole.com/detail/108785
前言
在傳統架構下,我們需要使用服務發現、服務註冊等技術實現微服務架構。通常我們需要將服務提供方(Service Provider
)的節點(IP:PORT
)儲存在 ZooKeeper
、ETCD
、Consul
、Nacos
等服務管理元件,服務呼叫方(Service Customer
)可以讀取到節點列表,發起 RPC
呼叫,建立連線併傳送請求、接收響應。
通常我們需要依賴特定框架的實現,比如 Spring Cloud
、Dubble
、Hyperf
等框架。在雲原生時代實現微服務不再需要這樣,我們可以直接使用 K8s 提供的 Service 來實現微服務架構,將服務註冊發現下沉到系統底層。可靠性更高,穩定性更好,而且是天然跨語言的,Java、PHP、Golang 都可以使用,開發框架也會變得更簡單,不需要做任何事情,只需要實現服務的邏輯,監聽本機埠即可。
K8s Service 介紹
Service 是 K8s 提供的發現後端 Pod 的一種機制,為一組具有屬於同一個 Deployment 的所有 Pod 提供了統一的入口地址,將請求進行負載分發到各個 Pod 。
在 K8s 中 Pod 就相當於是 Linux 系統的程式,是執行應用程式的容器組。如何訪問 Pod 中的服務呢?直接去連線 Pod 的 IP:Port
肯定是不行的,因為它是不穩定的,隨時可能會發生排程而重啟,Pod 的生命週期是非常短暫的。而 Pod 重啟之後 IP 埠會發生變化。一個服務或應用通常會有 1-N 個 Pod,請求 Service 的 IP:PORT
時會自動負載均衡並轉發到其中一個 Pod,Service 一般是使用 kube-proxy
和 Linux 核心提供的 IPVS
技術實現。也可以理解為 Service 其實就是一個4層代理,後端是應用的 Pod,在 Service 之前我們可以設定 Ingress 接入閘道器,允許從叢集外部訪問,一般對外服務的 HTTP 介面就是這個方式。也可以直接使用,只允許內部訪問,這就是微服務模式。
在 Code-Galaxy 平臺上使用 Service
K8s 為每個Service
分配了一個 Name
,這個 Name 已經註冊到了 CoreDNS
中,可直接使用 gethostbyname
或其他 DNS 解析方法,將 Server Name
解析成 Service 的 IP 地址。 一個 Service 需要設定對外埠,也就是訪問此 Service 對外暴露的埠,另外一個是內部埠,也就是 Pod 的埠。Pod 相關的資訊會被儲存在 K8s 的 ETCD
分散式儲存中。
例如使用 Hyperf 框架,預設會監聽 9501 埠,對外希望服務呼叫方直接通過 80 埠訪問,那 Service 的內:外分別就是 9501:80
。這時就在其他服務中就可以使用 HTTP 客戶端訪問 http://ServiceName:80/
來請求此服務了。
不同的名稱空間互相訪問時,需要在Server Name
之後追加.{$namespace}