Consul中文文檔—Consul打通k8s內外服務發現

Consul中文文檔
轉載請註明🙂,喜歡請一鍵三連哦 😊

系列文章目錄

Consul專欄—Consul工作原理及落地實踐

Consul中文文檔1.9


前言

爲了提高生產的可用性,減少手動運維成本,目前來看使用k8s編排部署已成爲趨勢。 當我們逐漸K8s向遷移時, 如何解決當前過渡架構中服務發現的問題呢?

( 打通服務發現可能只是第一步, 後續我們可能會基於服務發現去做跨平臺的服務治理, 這種情況我們後續再分析)

本篇主要分享基於Consul的解決方案, 來實現 非K8s Service(運行在K8s外) 與 原生 K8s Service 間的服務發現互通性

簡單來說,就是實現 K8s集羣外的應用可以發現調用K8s Service , 同時K8s內的應用又可以像調用集羣內native service一樣調用集羣外的服務。

Consul基於此場景, 提供的了Consul-Sync組件, 來實現Consul和Kubernetes服務互相同步的方案。

一、同步Kubernetes和Consul服務

同步功能由consul-k8s project提供, 可以通過Consul Helm Chart 自動安裝和配置。

1.1 同步Kubernetes services到Consul

Consul Sync組件可自動同步Kubernetes Service 註冊到Consul Catalog中。

同步的K8s services, 使得用戶可通過Consul原生服務發現的方式進行服務發現和連接K8s內服務, 如DNS或 HTTP。

(跨K8s集羣的服務發現,也可以這樣完)

同步的服務將被註冊到 k8s-sync節點上,它這並不是一個真正的Consul節點, 不像Consul Client節點一樣去註冊和監控服務。 相對的, k8s-sync節點監控的是K8s,並且同步服務到Consul。

同步的Service類型、同步的命名空間、同步的Service都可以通過配置、註解進行設置,後續我將寫一篇單獨的文章講解相關配置。

1.1.1 同步支持的Kubernetes Services類型

PS: 值得大家注意的一點是, 默認情況下K8s內使用的虛IP, 因此並不是所有的Services 類型都可以被集羣外部訪問到。

目前支持四種情況的K8s services同步: NodePort、LoadBalancer、External IPs、Cluster IP, 如果服務類型不屬於這四種, 將不會被同步。各類型同步情況如下,我列了一個表格。

服務類型 NodePort LoadBalancer External IPs Cluster IP
服務名稱 service name + namespace service name + namespace service name + namespace service name + namespace
服務實例數 Pod數 External IP數 External IP 數 Pod數
服務實例地址(Address) Node External IP LB External IP External IP Pod IP
服務實例端口 (Port) Node port first port first port first target port

PS: 關於服務名稱、服務端口、服務標籤、服務元數據 都其實都可以通過Consul註解或配置進行自定義, 放到下節我們統一介紹。

1.1.2 同步情況預覽

我準備了三個例子, 我一個Nginx Deployment , 三副本的,同事創建了三種類型的Service , 分別爲 ClusterIP、NodePort、LoadBalancer, 我們來分別看下他們的同步效果。
Nginx Service
來看下Consul集羣中,同步後的服務情況。
Consul同步K8s服務


- Cluster-IP
產生三個服務實例。
在這裏插入圖片描述

- NodePort
產生三個服務實例,每個服務實例IP對應Node公網IP
NodePort

- LoadBalancer(External IP)
LoadBalancer 類型,官網說之後產生一個服務實例, 但是經過我實測, 當我的LB有綁定兩個Ip時(比如一個內網,一個公網),這種情況產生兩個服務實例, 這就和External Ip情況有點相似了。
lb類型

1.1.3 注意事項

1.1.3.1 關於External IPs

External IP並不是K8s Service類型,而是一種指定了外部Ip的情況,如果一個服務指定了External Ip, 那麼這種服務也可以被同步。

針對這種情況, External Ip 可能是被其他系統設置的, 但是 External Ips 一定要是可以配其他服務發現系統解析的, 不要是虛IP。

1.1.3.2 關於ClusterIP

但是大家注意這個類型, 正常情況下, Pod Ip 是虛Ip,是無法被集羣外部訪問的。如果不想要同步這種ClusterIP類型,可以通過 Helm中的配置進行關掉 syncClusterIPServices=false

其實公有云情況下,一般K8s內的IP會直接使用 VPC IP, 所以集羣內、集羣外的網絡是打平的,可以互通。

1.2 同步Consul service到Kubernetes

對於Consul中每一個Service都將會在K8s創建一個ExternalName Serviceexternal name 爲Consul DNS名稱。 例如Consul中存在一個名爲foo的Service ,那麼創建的K8s Service將如下所示

apiVersion: v1
kind: Service
metadata:
  name: foo
  annotations:
    consul.hashicorp.com/service-sync: "false"
  labels:
    consul: "true"
  ...
spec:
  externalName: foo.service.consul
  type: ExternalName

注意: foo.service.consul 需要使用Consul DNS 纔可以解析到哦。

// 127.0.0.1 可以替換爲Consul Service, 如果Consul是部署在K8s中的。 
dig @127.0.0.1 -p 8600 redis.service.dc1.consul. ANY

補充: 被同步的服務都會帶着 consul: "true" ,因此很容易篩選出來。

1.2.1 同步效果預覽

帶大家看個例子,在Consul集羣中,會有個Consul服務的, 我們以它爲例看下同步後的情況。

Consul 服務

來看下Kubernetes同步後的Consul服務。
Consul 服務同步至k8s

1.2.2 非同步方案

其實從Consul向Kubernetes同步是非必須的,可以基於目前正使用的Kubernetes的DNS方案,配置Consul DNS。 比如如果你正在使用KubeDNS見 stub-domain configuration, 如果正在使用CoreDNS, 可參考proxy configuration

一旦配置了Consul DNS, 當以<consul-service-name>.service.consul格式發起請求時,Consul DNS將解析成Consul裏的Service, 全部的K8s明明空間都可以生效。

當然,如果你近想通過 service-name 格式進行訪問,那還是要同步。😀

關於Consul DNS 在K8s中應用可參考: Consul DNS on Kubernetes

二、Consul Sync安裝

限於文章篇幅,我們統一放到下一篇文章中介紹Consul Sync的配置和相關安裝。

三、總結

3.1 爲什麼同步Kubernetes services到Consul?

將Kubernetes Service同步到Consul Catalog,可以使Consul集羣中的所有節點都可以獲取到這些服務。 而且此方案可作爲不同多K8s集羣的服務發現方案。對於非K8s節點(集羣外)可以通過Consul DNS 或者 HTTP API 獲取到服務信息。

3.2 爲什麼同步Consul services到Kubernetes?

同步之後,K8s內的服務就可以像調用K8s內服務一樣,調用外部服務。這也似的像一些數據庫之類的外部變的自動化。

四、參考文檔

  1. Syncing Kubernetes and Consul Services
  2. Announcing First-Class Kubernetes Support for HashiCorp Products
  3. Announcing HashiCorp Consul + Kubernetes
  4. Consul DNS on Kubernetes
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章