VCL Socket 介面

注意

VCL socket 介面擴充功能為實驗性質,目前正在積極開發中。

注意

這些功能在 Windows 上不受支援,詳細資訊請參閱VPP 支援的架構

此 socket 介面擴充功能透過 VPP 的 Comms 程式庫 (VCL) 與 fd.io VPP 整合,為 Envoy 提供高速 L2-L7 使用者空間網路。

VCL socket 介面僅包含在contrib 映像檔

組態範例

bootstrap_extensions:
  - name: envoy.extensions.vcl.vcl_socket_interface
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.vcl.v3alpha.VclSocketInterface
default_socket_interface: "envoy.extensions.vcl.vcl_socket_interface"

運作方式

如果啟用,此擴充功能會在 Envoy 啟動時,透過 VCL 介面 ( vcl_interface.h) 連接到 VCL,並因此連接到外部 VPP 程序。這會註冊一個主要的 VCL 工作執行緒,而後續的 Envoy 工作執行緒會在 socket 介面擴充功能偵測到其程式碼是由尚未向 VCL 註冊的 pthread 執行時註冊。

由於 libevent 和 VCL 都想處理非同步輪詢和 IoHandles 的分派,因此 VCL 介面會將控制權委派給 libevent,方法是針對每個 Envoy 工作執行緒,向其註冊與 VCL 工作執行緒的 VPP 訊息佇列相關聯的 eventfd。這些共用記憶體訊息佇列由 VPP 用於將 io/ctrl 事件傳達至 VCL,而 eventfd 用於發出訊息佇列從空狀態轉換為非空狀態的訊號。這最終意味著 VPP 產生的事件會強制 libevent 將控制權交給 VCL 介面,而 VCL 介面針對每個 Envoy 工作執行緒,使用內部維護的 epoll fd 從 VCL 輪詢/提取事件,然後分派這些事件。為了支援所有這些間接互動,socket 介面會使用自訂的 IoHandleFileEvent 實作,以便在 Envoy 和 VCL API 呼叫之間進行轉換。

安裝及執行 VPP/VCL

如需如何建置和/或安裝 VPP 的相關資訊,請參閱此處的入門指南。假設使用 DPDK 介面,一個也設定主機堆疊的最小 startup.conf 檔案會包含

unix {
  # Run in interactive mode and not as a daemon
  nodaemon
  interactive

  # Cli socket to be used by vppctl
  cli-listen /run/vpp/cli.sock

  # Group id is an example
  gid vpp
}

cpu {
  # Avoid using core 0 and run vpp's main thread on core 1
  skip-cores 0
  main-core 1

  # Set logical CPU core(s) where worker threads are running. For performance testing make
  # sure the cores are on the same numa as the NIC(s). Use lscpu to determine the numa of
  # a cpu and "sh hardware" in vpp cli to determine the numa of a NIC. To configure multiple
  # workers lists are also possible, e.g., corelist-workers 2-4,6
  corelist-workers 2
}

buffers {
  # Default is 16384 (8192 if running unpriviledged)
  buffers-per-numa 16384
}

dpdk {
  # Notes:
  # - Assuming only one NIC is used
  # - The PCI address is an example, the actual one should be found using something like dpdk_devbind
  #    https://github.com/DPDK/dpdk/blob/main/usertools/dpdk-devbind.py
  # - Number of rx queues (num-rx-queus) should be number of workers
  dev 0000:18:00.0 {
    num-tx-desc 256
    num-rx-desc 256
    num-rx-queues 1
  }
}

session {
  # Use session layer socket api for VCL attachments
  use-app-socket-api

  # Enable VPP session layer
  enable

  # VPP worker's message queues lengths
  event-queue-length 100000
}

取得二進位檔後,手動啟動 VPP:./vpp -c startup.conf

可以透過將組態檔新增至 /etc/vpp/vcl.conf 或將 VCL_CONFIG 環境變數指向組態檔來設定 VCL。以下提供一個可用於 RPS 負載測試的最小範例

vcl {
  # Max rx/tx session buffers sizes in bytes. Increase for high throughput traffic.
  rx-fifo-size 400000
  tx-fifo-size 400000

  # Size of shared memory segments between VPP and VCL in bytes
  segment-size 1000000000

  # App has access to global routing table
  app-scope-global

  # Allow inter-app shared-memory cut-through sessions
  app-scope-local

  # Pointer to session layer's socket api socket
  app-socket-api /var/run/vpp/app_ns_sockets/default

  # Message queues use eventfds for notifications
  use-mq-eventfd

  # VCL worker incoming message queue size
  event-queue-size 40000
}