如何在生產環境中使用 Kubernetes 運行 Istio。 第1部分

什麼是 Istio? 這就是所謂的服務網格,一種在網絡上添加抽象層的技術。 我們攔截集群中的全部或部分流量,並對其執行一組特定的操作。 哪一個? 比如我們做智能路由,或者我們實現斷路器的方式,我們可以組織“金絲雀部署”,將流量部分切換到新版本的服務,或者我們可以限制外部交互,控制所有從集群到集群的行程外部網絡。 可以設置策略規則來控制不同微服務之間的行程。 最後,我們可以獲得整個網絡交互圖,並使統一的指標集合對應用程序完全透明。

您可以閱讀有關工作機制的信息 官方文檔. Istio 是一個非常強大的工具,可以讓您解決許多任務和問題。 在這篇文章中,我想回答在開始使用 Istio 時通常會出現的主要問題。 這將幫助您更快地處理它。

如何在生產環境中使用 Kubernetes 運行 Istio。 第1部分

的操作原理

Istio 由兩個主要區域組成——控制平面和數據平面。 控制平麵包含確保其餘部分正確運行的主要組件。 在當前版本 (1.0) 中,控制平面具有三個主要組件:Pilot、Mixer、Citadel。 我們不會考慮 Citadel,它需要生成證書來確保服務之間的相互 TLS。 讓我們仔細看看 Pilot 和 Mixer 的設備和用途。

如何在生產環境中使用 Kubernetes 運行 Istio。 第1部分

Pilot 是主要的控制組件,它分發關於我們在集群中擁有的所有信息——服務、它們的端點和路由規則(例如,金絲雀部署規則或斷路器規則)。

Mixer 是一個可選的控制平面組件,它提供收集指標、日誌和有關網絡交互的任何信息的能力。 他還監控政策規則的遵守情況和速率限制的遵守情況。

數據平面是使用 sidecar 代理容器實現的。 默認使用強大的。 特使代理. 可以換成其他實現,比如nginx(nginmesh)。

為了讓 Istio 對應用程序完全透明地工作,有一個自動注入系統。 最新的實現適用於 Kubernetes 1.9+ 版本(mutational admission webhook)。 對於 Kubernetes 版本 1.7、1.8,可以使用 Initializer。

Sidecar 容器使用 GRPC 協議連接到 Pilot,這允許您針對集群中發生的更改優化推送模型。 GRPC 從 1.6 版開始就在 Envoy 中使用,在 Istio 中,它從 0.8 版開始使用,並且是一個 pilot-agent - 一個配置啟動選項的 envoy 的 golang 包裝器。

Pilot 和 Mixer 是完全無狀態的組件,所有狀態都保存在內存中。 它們的配置以 Kubernetes 自定義資源的形式設置,存儲在 etcd 中。
Istio-agent 獲取 Pilot 的地址並向其打開 GRPC 流。

正如我所說,Istio 實現了對應用程序完全透明的所有功能。 讓我們看看如何。 算法是這樣的:

  1. 部署新版本的服務。
  2. 根據 sidecar 容器注入方式,istio-init 容器和 istio-agent 容器(envoy)是在應用配置階段添加的,或者它們可以已經手動插入到 Kubernetes Pod 實體的描述中。
  3. istio-init 容器是一個將 iptables 規則應用於 pod 的腳本。 有兩個選項可以將流量配置為包裝在 istio-agent 容器中:使用 iptables 重定向規則,或者 代理服務器. 在撰寫本文時,默認方法是使用重定向規則。 在 istio-init 中,可以配置應該攔截哪些流量並將其發送到 istio-agent。 例如,為了攔截所有傳入和所有傳出流量,您需要設置參數 -i и -b 進入意義 *. 您可以指定要攔截的特定端口。 為了不攔截特定的子網,您可以使用標誌指定它 -x.
  4. init 容器執行後,啟動主要容器,包括 pilot-agent(envoy)。 它通過 GRPC 連接到已經部署的 Pilot,並接收有關集群中所有現有服務和路由策略的信息。 根據收到的數據,他配置集群並將它們直接分配給 Kubernetes 集群中我們應用程序的端點。 還需要注意一個重點:envoy動態配置它開始監聽的監聽器(IP、端口對)。 因此,當請求進入 pod 時,使用 sidecar 中的重定向 iptables 規則進行重定向,envoy 已經可以成功處理這些連接並了解進一步代理流量的位置。 同樣在這個階段,信息被發送到 Mixer,我們稍後會看到它,並發送 tracing span。

結果,我們得到了一個完整的特使代理服務器網絡,我們可以從一個點(Pilot)進行配置。 所有入站和出站請求都通過特使。 此外,僅攔截 TCP 流量。 這意味著 Kubernetes 服務 IP 是使用 kube-dns over UDP 解析的,無需更改。 然後,在 resolve 之後,傳出請求被 envoy 攔截和處理,envoy 已經決定了請求應該發送到哪個端點(或者不發送,在訪問策略或算法的斷路器的情況下)。

我們弄清楚了 Pilot,現在我們需要了解 Mixer 的工作原理以及為什麼需要它。 你可以閱讀它的官方文檔 這裡.

當前形式的 Mixer 由兩個組件組成:istio-telemetry、istio-policy(在 0.8 版本之前它是一個 istio-mixer 組件)。 兩者都是混音器,各自負責自己的任務。 Istio 遙測通過 GRPC 從 sidecar Report 容器接收有關誰去了哪里以及使用什麼參數的信息。 Istio-policy 接受 Check 請求以驗證是否滿足 Policy 規則。 當然,並不是對每個請求都進行策略檢查,而是在客戶端(在 sidecar 中)緩存一段時間。 報告檢查作為批量請求發送。 讓我們稍後看看如何配置以及應發送哪些參數。

Mixer 應該是一個高度可用的組件,可確保不間斷地組裝和處理遙測數據。 結果該系統作為多級緩衝器獲得。 最初,數據在容器的邊車端緩衝,然後在混合器端緩衝,然後發送到所謂的混合器​​後端。 因此,如果任何系統組件出現故障,緩衝區就會增長並在系統恢復後被刷新。 Mixer 後端是發送遙測數據的端點:statsd、newrelic 等。 您可以編寫自己的後端,這很簡單,我們將看看如何去做。

如何在生產環境中使用 Kubernetes 運行 Istio。 第1部分

總而言之,使用 istio-telemetry 的方案如下。

  1. 服務 1 向服務 2 發送請求。
  2. 當離開服務 1 時,請求被包裝在它自己的 sidecar 中。
  3. Sidecar envoy 監控請求如何到達服務 2 並準備必要的信息。
  4. 然後使用 Report 請求將其發送到 istio-telemetry。
  5. Istio-telemetry 確定此報告是否應該發送到後端,應該發送到哪個後端以及應該發送什麼數據。
  6. 如果需要,Istio-telemetry 將報告數據發送到後端。

現在讓我們看看如何在系統中部署 Istio,僅由主要組件(Pilot 和 sidecar envoy)組成。

首先我們看一下Pilot讀取的主要配置(mesh):

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
  labels:
    app: istio
    service: istio
data:
  mesh: |-

    # пока что не включаем отправку tracing информации (pilot настроит envoy’и таким образом, что отправка не будет происходить)
    enableTracing: false

    # пока что не указываем mixer endpoint’ы, чтобы sidecar контейнеры не отправляли информацию туда
    #mixerCheckServer: istio-policy.istio-system:15004
    #mixerReportServer: istio-telemetry.istio-system:15004

    # ставим временной промежуток, с которым будет envoy переспрашивать Pilot (это для старой версии envoy proxy)
    rdsRefreshDelay: 5s

    # default конфигурация для envoy sidecar
    defaultConfig:
      # аналогично как rdsRefreshDelay
      discoveryRefreshDelay: 5s

      # оставляем по умолчанию (путь к конфигурации и бинарю envoy)
      configPath: "/etc/istio/proxy"
      binaryPath: "/usr/local/bin/envoy"

      # дефолтное имя запущенного sidecar контейнера (используется, например, в именах сервиса при отправке tracing span’ов)
      serviceCluster: istio-proxy

      # время, которое будет ждать envoy до того, как он принудительно завершит все установленные соединения
      drainDuration: 45s
      parentShutdownDuration: 1m0s

      # по умолчанию используются REDIRECT правила iptables. Можно изменить на TPROXY.
      #interceptionMode: REDIRECT

      # Порт, на котором будет запущена admin панель каждого sidecar контейнера (envoy)
      proxyAdminPort: 15000

      # адрес, по которому будут отправляться trace’ы по zipkin протоколу (в начале мы отключили саму отправку, поэтому это поле сейчас не будет использоваться)
      zipkinAddress: tracing-collector.tracing:9411

      # statsd адрес для отправки метрик envoy контейнеров (отключаем)
      # statsdUdpAddress: aggregator:8126

      # выключаем поддержку опции Mutual TLS
      controlPlaneAuthPolicy: NONE

      # адрес, на котором будет слушать istio-pilot для того, чтобы сообщать информацию о service discovery всем sidecar контейнерам
      discoveryAddress: istio-pilot.istio-system:15007

所有主要控制組件(控制平面)都將位於 Kubernetes 的命名空間 istio-system 中。

至少,我們只需要部署 Pilot。 為此,我們將使用 這樣的配置。

我們將手動配置容器的注入邊車。

初始化容器:

initContainers:
 - name: istio-init
   args:
   - -p
   - "15001"
   - -u
   - "1337"
   - -m
   - REDIRECT
   - -i
   - '*'
   - -b
   - '*'
   - -d
   - ""
   image: istio/proxy_init:1.0.0
   imagePullPolicy: IfNotPresent
   resources:
     limits:
       memory: 128Mi
   securityContext:
     capabilities:
       add:
       - NET_ADMIN

和邊車:

       name: istio-proxy
       args:
         - "bash"
         - "-c"
         - |
           exec /usr/local/bin/pilot-agent proxy sidecar 
           --configPath 
           /etc/istio/proxy 
           --binaryPath 
           /usr/local/bin/envoy 
           --serviceCluster 
           service-name 
           --drainDuration 
           45s 
           --parentShutdownDuration 
           1m0s 
           --discoveryAddress 
           istio-pilot.istio-system:15007 
           --discoveryRefreshDelay 
           1s 
           --connectTimeout 
           10s 
           --proxyAdminPort 
           "15000" 
           --controlPlaneAuthPolicy 
           NONE
         env:
         - name: POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: POD_NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
         - name: INSTANCE_IP
           valueFrom:
             fieldRef:
               fieldPath: status.podIP
         - name: ISTIO_META_POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: ISTIO_META_INTERCEPTION_MODE
           value: REDIRECT
         image: istio/proxyv2:1.0.0
         imagePullPolicy: IfNotPresent
         resources:
           requests:
             cpu: 100m
             memory: 128Mi
           limits:
             memory: 2048Mi
         securityContext:
           privileged: false
           readOnlyRootFilesystem: true
           runAsUser: 1337
         volumeMounts:
         - mountPath: /etc/istio/proxy
           name: istio-envoy

為了讓一切順利啟動,需要為Pilot創建ServiceAccount、ClusterRole、ClusterRoleBinding、CRD,具體說明見 這裡.

因此,我們使用 envoy 注入 sidecar 的服務應該成功啟動,接收來自 pilot 的所有發現並處理請求。

重要的是要了解所有控制平面組件都是無狀態應用程序,並且可以毫無問題地進行水平擴展。 所有數據都以 Kubernetes 資源的自定義描述的形式存儲在 etcd 中。

此外,Istio(仍處於實驗階段)具有在集群外運行的能力,以及在多個 Kubernetes 集群之間觀察和摸索服務發現的能力。 你可以閱讀更多關於這個 這裡.

對於多集群安裝,請注意以下限制:

  1. Pod CIDR 和服務 CIDR 在所有集群中必須是唯一的並且不能重疊。
  2. 所有 CIDR Pod 都必須可以從集群之間的任何 CIDR Pod 訪問。
  3. 所有 Kubernetes API 服務器必須可以相互訪問。

這是幫助您開始使用 Istio 的初始信息。 但是,仍然存在許多陷阱。 例如,路由外部流量(集群外)的特性、調試 sidecar 的方法、分析、設置混合器和編寫自定義混合器後端、設置跟踪機制及其使用 envoy 的操作。
我們將在以下出版物中考慮所有這些。 問你的問題,我會盡力解決。

來源: www.habr.com

添加評論