CoreDNS 和 Apache APISIX 為服務發現開啟新局面?

在 Apache APISIX 中使用 CoreDNS 的指南。

背景資訊

在傳統的實體機器和虛擬機器部署中,各種服務之間的呼叫可以
透過固定的 IP + port 進行。隨著雲原生時代的到來,企業
業務部署更加傾向於雲原生容器化。然而,在容器化的
環境中,服務實例的啟動和銷毀非常頻繁。僅靠操作人員手動維護
不僅工作量大,而且效率低下。
因此,需要一種機制,可以自動偵測服務狀態,並在服務地址發生變化時
動態綁定新的地址。服務發現機制應運而生。

服務發現

服務發現機制可以分為兩個部分

  • 服務註冊表:儲存服務的主機和連接埠資訊。

如果一個容器提供了一個計算平均值的服務,我們使用服務名稱 average
作為唯一識別碼,那麼它將以鍵值對的形式 (average:192.168.1.21)
儲存在服務註冊表中。

  • 服務發現:允許其他使用者發現服務註冊階段儲存的資訊。它分為
    客戶端發現模式和伺服器發現模式。

客戶端服務發現模式

當使用客戶端發現模式時,客戶端透過查詢服務註冊表的儲存資訊,獲取可用的
服務的實際網路地址,透過負載平衡演算法選擇一個可用的服務
實例,並將請求發送到該服務。

優點:架構簡單、擴展靈活、易於實現負載平衡功能。

缺點:客戶端負擔重、耦合性強,存在一定的開發成本。

客戶端發現模式。

客戶端發現模式的實作邏輯如下

  1. 當一個新服務啟動時,它會主動向註冊中心註冊,並且
    服務註冊中心將儲存新服務的服務名稱和地址;
  2. 當客戶端需要此服務時,它將使用服務名稱向
    服務註冊表發起查詢;
  3. 服務註冊表返回可用的地址,客戶端根據特定演算法選擇其中一個
    地址以發起呼叫。

在這個過程中,除了服務註冊之外,服務發現的工作基本上是
由客戶端獨立完成的,並且註冊表和伺服器的地址也是
對客戶端完全可見的。

伺服器服務發現模式

客戶端向負載平衡器發送請求,負載平衡器根據客戶端的請求查詢服務註冊表,
找到可用的服務,並將請求轉發到該
服務。與客戶端服務發現模式一樣,該服務需要在註冊表中註冊和註銷。
在註冊表中。

優點:服務的發現邏輯對客戶端是透明的。

缺點:需要額外部署和維護負載平衡器。

伺服器發現模式。

伺服器發現模式的實作邏輯如下

  1. 當一個新服務啟動時,它會主動向註冊表註冊,並且服務
    註冊表將儲存新服務的服務名稱和地址;
  2. 當客戶端需要服務時,它將使用服務名稱向
    負載平衡器發起查詢;
  3. 根據客戶端請求的服務名稱,負載平衡器代理客戶端
    向服務註冊表發起請求;
  4. 負載平衡器取得返回的地址後,會根據特定演算法選擇其中一個地址
    發起呼叫。

使用 CoreDNS 的優點

與常見的服務發現框架 (Zookeeper 和 Consul) 相比,CoreDNS 實現服務發現有什麼優勢?
CoreDNS 實作服務發現有什麼優點?

服務發現的原理類似於 DNS 網域名稱系統,它是電腦網路中一個重要的
基礎設施。DNS 網域名稱系統將很少變更的網域名稱
與經常變更的伺服器 IP 位址綁定,而服務發現機制是將
很少變更的網域名稱。服務名稱綁定到服務地址。透過這種方式,
我們可以利用 DNS 來實現類似於服務註冊表的功能,只需要轉換
儲存在 DNS 中的網域名稱成為服務名稱。由於許多電腦都內建
DNS 功能,我們只需要修改原始 DNS 系統上的設定,而無需
做太多額外的事情。

CoreDNS 是一個用 Go 編寫的開源 DNS 伺服器,由於其靈活性和可擴展性,通常用於多容器環境中的 DNS 服務
和服務發現。
CoreDNS 建構於 HTTP/2 網頁伺服器 Caddy 之上,並實作了外掛程式鏈
架構,將許多 DNS 相關邏輯抽象成一層層的外掛程式,這些外掛程式更
靈活且易於擴展,並且使用者選擇的外掛程式將被編譯到最終的可執行
檔案中,執行效率也非常高。CoreDNS 是第一個加入 CNCF (雲原生運算基金會) 的雲原生開
源專案,並且已經畢業,它也是
Kubernetes 中的預設 DNS 服務。

作為中介軟體,Apache APISIX 也整合了多種服務發現功能。下面
將向您展示如何在 Apache APISIX 中設定 CoreDNS。

原理架構

  1. 客戶端向 APISIX 發起呼叫服務的請求。
  2. APISIX 根據設定的路由(具體設定如下所示)存取上游服務節點。在 APISIX 中,您可以設定透過 DNS 取得上游資訊。只要
    設定正確的 DNS 伺服器 IP 位址,APISIX 將自動向此位址發起請求
    ,以取得 DNS 中對應服務的位址。
    ,以取得 DNS 中對應服務的位址。
  3. CoreDNS 根據請求的服務名稱傳回可用地址列表。
  4. APISIX 選擇一個可用的地址和設定的演算法來發起呼叫。

整體結構如下

原理架構。

如何使用

先決條件

本文基於以下環境。

步驟

  1. 使用 Node.js 的 Koa 框架在連接埠 3005 上啟動一個簡單的測試服務。

存取此服務將返回字串 Hello World,稍後我們將透過 CoreDNS 取得此
服務的位址。

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3005);
  1. 設定 CoreDNS。

預設情況下,CoreDNS 會監聽連接埠 53,並讀取
同一目錄下的 Corefile 設定檔。在初始條件下,同一目錄中沒有 Corefile 檔案,
因此我們需要建立並完成設定。

Corefile 主要透過設定外掛程式來實現功能,因此我們需要設定三個外掛程式

  • hosts:您可以使用此參數綁定服務名稱和 IP 位址。fallthrough
    表示當目前外掛程式無法傳回正常資料時,可以將請求轉發到
    下一個外掛程式進行處理(如果存在)。
  • forward:表示將請求代理到指定的位址,通常是權威
    DNS 伺服器位址。
  • log:不設定任何參數,將記錄資訊列印到主控台介面以進行偵錯。
.:1053 {                           # Listen on port 1053
    hosts {                        
        10.10.10.10 hello    
           # Bind the service name "coredns" to the IP address
        fallthrough
    }
    forward . 114.114.114.114:53  
    log
}
  1. 設定 Apache APISIX。

conf/config.yaml 檔案中新增相關設定並重新載入 Apache APISIX。

# config.yml
# ...other config
discovery:   
   dns:     
     servers:       
        - "127.0.0.1:1053"  # Use the real address of the DNS server,
                            # here is the 1053 port of the local machine.
  1. 在 Apache APISIX 中設定路由資訊。

接下來,我們透過請求 Admin API 來設定相關路由資訊。

curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "uri": "/core/*",
    "upstream": {
        "service_name": "hello:3005",   
                    # Name the service as coredns, consistent with 
                    # the configuration of the hosts plugin in CoreDNS
        "type": "roundrobin",
        "discovery_type": "dns" # Set service discovery type to DNS
    }
}'
  1. 驗證。

a. 在本機上驗證

curl 127.0.0.1:9080/core/hello -i

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
Date: Wed, 16 Feb 2022 08:44:08 GMT
Server: APISIX/2.12.1

Hello World

b. 在其他主機上驗證

curl 10.10.10.10:9080/core/hello -i

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
Date: Wed, 16 Feb 2022 08:43:32 GMT
Server: APISIX/2.12.0

Hello World

從以上結果可以看出,服務正常運作。

  1. 模擬容器的 IP 位址已變更,因為容器由於各種原因無法
    提供服務。

我們需要在另一台伺服器上設定相同的服務,也在連接埠 3005 上執行,
但 IP 位址已變更,且返回的字串已變更為 Hello, Apache APISIX

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.body = 'Hello, Apache APISIX';
});

app.listen(3005);

修改 Corefile 設定並重新啟動 Core DNS。保持其他設定
不變。設定範例如下

.:1053 {                           # Listen on port 1053
    hosts {                        
        10.10.10.10 hello    
           # Bind the service name "coredns" to the IP address
        fallthrough
    }
    forward . 114.114.114.114:53  
    log
}

DNS 具有快取機制。當我們使用 dig 命令請求解析新的
網域名稱時,我們將在傳回的 DNS 記錄 中看到一個數字欄位,即 TTL
欄位,通常為 3600,即一個小時。在 TTL 期間向網域名稱發送的請求
將不再請求 DNS 伺服器解析位址,
而是直接取得本機快取中對應於網域名稱的位址。

透過驗證,我們可以發現請求已重新導向到新的位址。驗證
如下

curl 127.0.0.1:9080/core/hello -i

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
Date: Wed, 16 Feb 2022 08:44:08 GMT
Server: APISIX/2.12.0

Hello, Apache APISIX

總結

本文主要介紹了服務發現的類型以及如何在
Apache APISIX 中使用 CoreDNS。您可以根據您的業務需求使用 Apache APISIX 和 CoreDNS
和過去的技術架構。


發布時間:,標籤為 Apache APISIXAPI 閘道服務發現服務,共 1640 個字。