歡迎光臨
每天分享高質量文章

在生產環境執行Istio

Istio是什麼?Istio是服務網格技術,在網路上新增一層抽象層。它截獲Kubernetes集群裡的所有或者部分流量,併在之上執行一系列操作。支援哪些操作呢?比如,搭建智慧路由或實現斷路器方案,進行“金絲雀部署”等。另外,Istio還可以限制外部互動並且控制叢集和外部網路的所有路由。而且,Istio支援配置策略規則來控制不同微服務之間的互動。最終,我們可以生成完整的網路互動圖,並且得到對於應用來說完全透明的指標集。
官方檔案[1]裡有Istio的詳細介紹。本文介紹Istio上微服務互動背後的基本原理,展示Istio的確是解決各種問題的相當強大的工具。本文嘗試回答Istio初學者經常會問的各種問題,幫助大家更有效率地使用Istio。
在介紹安裝之前,先介紹一些核心觀點,總體看一下Istio的元件和元件間互動的原理。
工作原理

 

Istio由兩大元件組成——控制面板和資料面板。控制面板包含基礎元件,確保和其他元件之間的正確互動。在當前的1.0版本里,控制面板有三個元件:Pilot,Mixer和Citadel。這裡不討論Citadel,因為在生成證書來進行服務間的雙向TLS通訊時才需要它。我們先瞭解一下Pilot和Mixer的設計和標的。
Pilot是主要的控制元件,它負責分發叢集內的所有資訊——服務,它們的端點以及路由規則(比如,金絲雀釋出規則或者斷流器規則)。
Mixer是可選的控制面板元件,它負責收集指標、日誌以及其他網路互動的資訊。它還監控是否符合策略規則以及是否符合速率限制。
資料面板的元件使用sidecar代理容器來實現。預設使用強大的代理伺服器Envoy[2]。為了確保Istio對於應用來說是徹底透明的,這裡使用了自動註入系統。最新的實現支援Kubernetes 1.9或更新版本(mutational admission webhook)。對於Kubernetes 1.7,1.8版本,可以是用Initializer。
Sidecar容器透過GRPC協議連線Pilot,最佳化叢集內變更的pushdown模型。Envoy從1.6版本就開始使用GRPC;Istio則從0.8版本開始使用,它是pilot-agent——Envoy之上GO的封裝,用來配置啟動引數。
Pilot和Mixer是純粹的無狀態元件,所有的狀態都儲存在應用程式的記憶體裡。它們的配置由Kubernetes的Custom Resource定義,儲存在etcd裡。Istio-agent得到Pilot的地址,並開啟GRPC連線。
正如我所說,Istio在對應用完全透明的前提下實現了所有功能。讓我們一起看看是怎麼實現的。演演算法原理如下:
  1. 我們部署服務的一個新版本。

  2. 取決於sidecar容器的註入型別,在配置階段新增istio-init容器和istio-agent容器(Envoy),或者手動插入到Kubernetes物體的Pod描述裡。

  3. istio-init容器是一些指令碼,為Pod設定iptables規則。有兩種方式配置流量重定向到istio-agent容器裡:使用直接的iptables規則或者TPROXY[2]。撰寫本文時,預設使用的是重定向規則。在istio-init裡,可以配置截獲哪些流量併傳送給istio-agent。比如,為了截獲所有入站和出站流量,使用者需要將引數 -i和 -b設定為 *。使用者也可以指定截獲特定埠的流量。為了避免截獲特定子網的流量,可以使用 -x引數。

  4. 在init執行後,會啟動容器,包括pilot-agent(Envoy)。它透過GRPC連線上已經部署的Pilot,得到叢集內所有已有服務以及路由策略的資訊。根據接收到的資料,它配置叢集,將這些流量直接對映到Kubernetes集群裡的應用程式埠。重要的地方是:Envoy動態配置監聽器(IP,埠對)開始監聽。因此,當請求進入Pod,並且使用iptables規則重定向到sidecar時,Envoy已經準備好處理這些連線,並且知道將這些代理流量轉發到哪裡去。這一步裡,資訊傳送給Mixer,下文會詳細介紹。

最終,我們得到Envoy代理伺服器的所有網路,可以從一點(Pilot)完成配置。最終,所有inbound和outbound請求都會透過Envoy。更為重要的是,只截獲TCP流量。這意味著仍舊是使用UDP上的kube-dns來解析Kubernetes服務IP,這點沒有變化。然後,在resolver之後,outbound請求被envoy截獲並處理,它決定請求傳送到哪個端點(或者不傳送,當訪問策略禁止或者觸發了斷流演演算法時)。
現在我們已經熟悉了Pilot,接下來研究Mixer是怎麼工作的,以及為什麼我們需要Mixer。Mixer的官方檔案在這裡[3]。
Mixer有兩個元件:istio-telemetry,isito-policy(0.8版本之前使用單個元件istio-mixer)。它們都是Mixer。Istio telemetry接收sidecar容器的GPRC,並且彙報服務互動和引數資訊。Istio-policy接收到檢查請求,確保滿足Policy規則。這些策略檢查在客戶端(sidecar裡)快取一段時間。報告檢查是批次傳送的。這裡介紹怎麼配置以及需要設定哪些引數。
Mixer應該是高可用元件,提供telemetry資料的不間斷收集和處理。整個系統是一個多層快取器。最初,資料快取在容器的sidecar裡,然後在Mixer,最終傳送到Mixer後臺。因此,如果任意系統元件發生故障,buffer會增長,之後當系統恢復時,會flush。Mixer後臺是傳送telemetry資料的端點:statsd,newrelic等等。編寫自定義後臺很簡單,之後我會給大家介紹。
總結一下,使用istio-telemetry的工作流如下:
  1. 服務1傳送請求給服務2

  2. 在已有的服務1裡,請求重定向到sidecar

  3. Sidecar Envoy監控到給服務2的請求,並準備所需資訊

  4. 然後它使用Report請求傳送給istio-telemetry。

  5. Istio-telemetry決定是否將Report傳送給後臺,這裡也負責傳送請求以及請求內容。

現在看看如何搭建包含兩大基礎元件Pilot和sidecar envoy的Istio系統。如下是Pilot讀取的基礎配置(Mesh):
  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: istio
  5. namespace: istio-system
  6. labels:
  7. app: istio
  8. service: istio
  9. data:
  10. mesh: |-
  11. # disable tracing mechanism for now
  12. enableTracing: false
  13. # do not specify mixer endpoints, so that sidecar containers do not send the information
  14. #mixerCheckServer: istio-policy.istio-system:15004
  15. #mixerReportServer: istio-telemetry.istio-system:15004
  16. # interval for envoy to check Pilot
  17. rdsRefreshDelay: 5s
  18. # default config for envoy sidecar
  19. defaultConfig:
  20. # like rdsRefreshDelay
  21. discoveryRefreshDelay: 5s
  22. # path to envoy executable
  23. configPath: "/etc/istio/proxy"
  24. binaryPath: "/usr/local/bin/envoy"
  25. # default name for sidecar container
  26. serviceCluster: istio-proxy
  27. # time for envoy to wait before it shuts down all existing connections
  28. drainDuration: 45s
  29. parentShutdownDuration: 1m0s
  30. # by default, REDIRECT rule for iptables is used. TPROXY can be used as well.
  31. #interceptionMode: REDIRECT
  32. # port for sidecar container admin panel
  33. proxyAdminPort: 15000
  34. # address for sending traces using zipkin protocol (not used as turned off in enableTracing option)
  35. zipkinAddress: tracing-collector.tracing:9411
  36. # statsd address for envoy containers metrics
  37. # statsdUdpAddress: aggregator:8126
  38. # turn off Mutual TLS
  39. controlPlaneAuthPolicy: NONE
  40. # istio-pilot listen port to report service discovery information to sidecars
  41. discoveryAddress: istio-pilot.istio-system:15007
讓我們將所有主要控制元件(控制面板)放到Kubernetes的istio-system名稱空間裡。
最小的配置僅僅要求Pilot的部署。我們使用如下配置[4]。並且手動配置sidecar容器的註入。
Init容器配置:
  1. initContainers:
  2. - name: istio-init
  3. args:
  4. - -p
  5. - "15001"
  6. - -u
  7. - "1337"
  8. - -m
  9. - REDIRECT
  10. - -i
  11. - '*'
  12. - -b
  13. - '*'
  14. - -d
  15. - ""
  16. image: istio/proxy_init:1.0.0
  17. imagePullPolicy: IfNotPresent
  18. resources:
  19. limits:
  20. memory: 128Mi
  21. securityContext:
  22. capabilities:
  23. add:
  24. - NET_ADMIN
Sidecar配置:
  1. - name: istio-proxy
  2. command:
  3. - "bash"
  4. - "-c"
  5. - |
  6. exec /usr/local/bin/pilot-agent proxy sidecar \
  7. --configPath \
  8. /etc/istio/proxy \
  9. --binaryPath \
  10. /usr/local/bin/envoy \
  11. --serviceCluster \
  12. service-name \
  13. --drainDuration \
  14. 45s \
  15. --parentShutdownDuration \
  16. 1m0s \
  17. --discoveryAddress \
  18. istio-pilot.istio-system:15007 \
  19. --discoveryRefreshDelay \
  20. 1s \
  21. --connectTimeout \
  22. 10s \
  23. --proxyAdminPort \
  24. "15000" \
  25. --controlPlaneAuthPolicy \
  26. NONE
  27. env:
  28. - name: POD_NAME
  29. valueFrom:
  30. fieldRef:
  31. fieldPath: metadata.name
  32. - name: POD_NAMESPACE
  33. valueFrom:
  34. fieldRef:
  35. fieldPath: metadata.namespace
  36. - name: INSTANCE_IP
  37. valueFrom:
  38. fieldRef:
  39. fieldPath: status.podIP
  40. - name: ISTIO_META_POD_NAME
  41. valueFrom:
  42. fieldRef:
  43. fieldPath: metadata.name
  44. - name: ISTIO_META_INTERCEPTION_MODE
  45. value: REDIRECT
  46. image: istio/proxyv2:1.0.0
  47. imagePullPolicy: IfNotPresent
  48. resources:
  49. requests:
  50. cpu: 100m
  51. memory: 128Mi
  52. limits:
  53. memory: 2048Mi
  54. securityContext:
  55. privileged: false
  56. readOnlyRootFilesystem: true
  57. runAsUser: 1337
  58. volumeMounts:
  59. - mountPath: /etc/istio/proxy
  60. name: istio-envoy
為了成功部署,需要為Pilot建立ServiceAccount,ClusterRole,ClusterRoleBinding,CRD;更多詳細資訊在這裡[6]。之後,帶有註入的sidecar和Envoy的服務就啟動了,會從Pilot獲取所有資料並且處理請求。
最重要的一點是所有控制面板元件都是無狀態的應用程式,都可以輕鬆地水平擴充套件。所有資料都以Kubernetes資源的自定義描述儲存在etcd裡。
此外,也可以在叢集外執行Istio(實驗用途),並且在幾個Kubernetes叢集之間監控並共享服務發現。更多的相關資訊在這裡[7]。在多叢集安裝裡,要考慮到如下限制:
  1. CIDR Pod和Service CIDR必須在所有集群裡都是唯一的,不能重疊。

  2. 叢集間的任意Pod CIDR必須能夠訪問所有CIDR Pod。

  3. 所有Kubernetes API server都必須能夠相互訪問。

本文讓你開始瞭解Istio。但是,後續文章會接著討論現有的問題。我們會討論外部流量路由的特性,探討最常見的sidecar debug和Profile的方法。最終,我們會建立跟蹤系統並且仔細介紹它和Envoy是如何互動的。
相關連結:
  1. https://istio.io/docs/concepts/

  2. https://www.envoyproxy.io/

  3. https://github.com/kristrev/tproxy-example/blob/master/tproxy_example.c

  4. https://istio.io/docs/concepts/policies-and-telemetry/overview/

  5. https://github.com/istio/istio/blob/release-1.0/install/kubernetes/helm/istio/charts/pilot/templates/deployment.yaml

  6. https://github.com/istio/istio/tree/release-1.0/install/kubernetes/helm/istio/charts/pilot/templates

  7. https://istio.io/docs/setup/kubernetes/multicluster-install/

原文連結:https://medium.com/avitotech/running-istio-on-kubernetes-in-production-part-i-a8bbf7fec18e

已同步到看一看
贊(0)

分享創造快樂