[譯] 在Kubernetes生產環境中運行Istio


本文翻譯自 https://www.tigera.io/blog/running-istio-on-kubernetes-in-production-part-i/,作者 Alexander Lukyanchenko,發表於2019年5月。

什么是Istio Istio是一種服務網格(service mesh)技術,它為網絡添加了一個抽象層。它攔截K8S集群中的全部或部分流量,並對其進行處理。它支持哪些操作呢? 例如,設置智能路由(smart routing)或實現斷路器(circuit breaker)或金絲雀部署(Canary deployment)。此外,Istio還可以限制外部交互,並控制群集和外部網絡之間的所有路由。此外,它支持設置策略規則以控制不同微服務之間的交互。最后,我們可生成一個完整的網絡交互圖,采用統一度量,並對應用程序完全透明。

Istion的詳細介紹可以訪問其官方文檔https://istio.io/docs/concepts/。本文中,我會介紹基於Istio的微服務之間交互的基本原理,你將會看到Istio是一個非常強大的能解決很多問題的工具。我還會嘗試着回答一些初學者經常問到的問題。我相信這些能幫助你高效地使用Istio

在安裝Istio之前,我想介紹一些基本概念、主要組件和組件之間交互的基本原理。

1. 運行原理

Istio包括兩個主要組件:控制平面和數據平面。控制平面包括若干基礎組件,用於控制其它組件之間能正確地交互。在當前1.0版本中,控制平面有三個主要組件:PilotMixerCitadel。文中不會介紹Citadel,它主要用於產生服務間通信所使用的TLS證書。我們現在來看下PolitMixer組件的用途和設計。

 

 Pilot是主要的控制組件,它分發集群中的有關信息,包括服務、端點和路由規則等。Mixer是一個可選控制平面組件,用於收集性能數據、日志和其它有關網絡交互的信息。它還負責監視策略規則(policy rule)的合法性。 

數據平面使用邊車代理容器(sidecar proxy container)實現,默認使用Envoy。為了確保Istio對應用完全透明,還實現了自動插入機制。最新的實現支持K8S 1.9和更新版本。對於老K8S版本,可以使用初始化器(Initializer)。 

邊車容器通過GRPC協議連接到Pilot,該協議優化了對集群變化的推送實現機制。從Envoy 1.6版本就開始使用GPRC了。Istio0.8版本起就實現了一個 pilot-agent,它是一個用Go語言實現的Envoy的封裝,用於配置啟動參數。 

PilotMixer是完全無狀態組件,所有狀態都保存在內存中。它們的配置保存在K8S CRD 中。Istio-agent獲取Pilot地址,然后打開GPRC流。

 如上述介紹的,Istio實現了一種對應用完全透明的機制。過程如下:

  1. 部署一個服務的新版本。
  2. 根據不同的邊車容器插入方式,在配置階段,一個istio-init容器和istio-agent容器(envoy)被自動或手動插入服務pod。
  3. Istio-init容器是一個腳本,用於設置podiptables規則。有兩種方式可配置將網絡流量導入istio-agent容器:使用redirect iptables規則或TPROXY。本文寫作時默認采用redirect iptables規則。在istio-init中,可配置哪些網絡流量會被截取並發送到istio-agent。比如,為了截取所有進出的流量,你需要添加參數 –i-b *。你可以配置只截取特定端口的流量。要避免截取特定子網的流量,可以使用-x標志。
  4. Istio-init容器執行完畢后,包括pilot-agent和業務容器在內的所有容器都會被啟動。Pilot-agent通過GRPC連接到Pilot,獲取集群的有關信息。根據所收到的數據,它進行相關配置,其中,envoy會動態配置監聽器,並開始監聽。因此,當請求進入pod后,它會被redirect iptables規則導給邊車容器,envoy處理這些流量並進行轉發。本步中,會有數據被發給Mixer,下文會進行介紹。

到此為止,我們了解了envoy代理所組成的完整網絡,它能被從一個中心點(Pilot)上進行配置。現在,所有進出的請求都會經過Envoy。而且,只有TCP流量會被截取。這意味着K8S服務的DNS請求不會受到影響。當出去的流量被截取后,Envoy會處理它,並決定發往哪里。 

2. Mixer組件 

下面我們會介紹Mixer的原理及用途。官方文檔在https://istio.io/docs/concepts/policies-and-telemetry/overview/Mixer有兩個組件:istio-telemetryistio-policy0.8版本之前,只有一個組件istio-mixer)。istio-telemetry通過GRPC從邊車容器收取有關服務交互的計量信息,istio-policy收取並處理策略校驗請求,並超檢查策略規則的合法性。這些策略會在邊車容器中被緩存一段時間。Mixer是一個高可用組件,采用多級緩存。一開始數據被緩存在邊車容器中,然后在mixer側,最后被發到所謂的mixer后端。結果,如果有某個組件故障,緩存會一直增長;如果組件重啟,則緩存會被刷新。Mixer后端是一些發送計量數據的端點,比如statsdnewrelic之類。寫這種后端也很容器,后文會做介紹。

總結一下,istio-telemetry的工作流如下:

  1. 服務1給服務2發一個請求。
  2. 在服務1中,請求會被邊車容器截取。它監控發給服務2的請求,會准備一些信息,封裝成報告請求(Report reques)發給istio-telemetry
  3. istio-telemetry決定是否向其后端發送這些請求。

3. 使用Pilot和Envoy搭建Istio系統

我們來看看如何使用PilotEnvoy組件搭建Istio系統。首先來看下Pilot所用到的配置:

apiVersion: v1

kind: ConfigMap

metadata:

  name: istio

  namespace: istio-system

  labels:

    app: istio

    service: istio

data:

  mesh: |-

# disable tracing mechanism for now

    enableTracing: false

# do not specify mixer endpoints, so that sidecar containers do not send the information

    #mixerCheckServer: istio-policy.istio-system:15004

    #mixerReportServer: istio-telemetry.istio-system:15004

# interval for envoy to check Pilot

    rdsRefreshDelay: 5s

# default config for envoy sidecar

    defaultConfig:

      # like rdsRefreshDelay

      discoveryRefreshDelay: 5s

# path to envoy executable

      configPath: "/etc/istio/proxy"

      binaryPath: "/usr/local/bin/envoy"

# default name for sidecar container

      serviceCluster: istio-proxy

# time for envoy to wait before it shuts down all existing connections

      drainDuration: 45s

      parentShutdownDuration: 1m0s

# by default, REDIRECT rule for iptables is used. TPROXY can be used as well.

      #interceptionMode: REDIRECT

# port for sidecar container admin panel

      proxyAdminPort: 15000

# address for sending traces using zipkin protocol (not used as turned off in enableTracing option)

      zipkinAddress: tracing-collector.tracing:9411

# statsd address for envoy containers metrics

      # statsdUdpAddress: aggregator:8126

# turn off Mutual TLS

      controlPlaneAuthPolicy: NONE

# istio-pilot listen port to report service discovery information to sidecars

      discoveryAddress: istio-pilot.istio-system:15007

我們把Istio所有組件都放到istio-sytem命名空間中。最小配置只需要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

         command:

         - "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

一個完整的安裝還需要創建服務賬戶、集群角色、集群角色綁定和CRD。更多信息請閱讀https://github.com/istio/istio/tree/release-1.0/install/kubernetes/helm/istio/charts/pilot/templates。安裝好以后,邊車容器會被注入服務pod,Envoy會被啟動起來,從Pilot接受數據並開始處理請求。

這里關鍵的一點是,所有控制平面組件都是無狀態的,因此很容器水平擴展。所有數據都以CRD被保存在etcd中。

而且,還可以將Istio安裝在集群之外,並用於多個K8S集群。更多信息可閱讀https://istio.io/docs/setup/kubernetes/multicluster-install/。在多集群部署中,需要考慮以下限制:

  • CIDR Pod和服務CIDR必須是集群間唯一,而且不能重疊。
  • 所有CIDR Pod都能在集群內被訪問。
  • 所有K8S API 服務器都能被互訪。 

感謝您的閱讀,歡迎關注我的微信公眾號:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM