在生產中執行kubernetes上的Istio
什麼是Istio ?Istio是一種服務網格技術,為網路添加了一個抽象層。它攔截k8s叢集中的全部或部分流量,並對其執行一組操作。支援哪些操作?例如,設定智慧路由或實施斷路器方法,設定“金絲雀部署”。此外,Istio可以對外部互動施加限制並控制叢集與外部網路之間的所有路由。此外,它還支援設定策略規則,以控制不同微服務之間的活動。最後,我們可以生成一個完整的網路互動圖,並使統一的度量集合對應用程式完全透明。
在這裡,我想介紹基於Istio的微服務互動背後的基本原理,我將嘗試證明Istio是一個解決各種問題的強大工具。在這篇文章中,我將嘗試回答Istio初學者通常擁有的問題。這些是允許您更有效地使用Istio的東西。
但在安裝之前,我想介紹一些中心概念,並看一下Istio的元件和它們之間的互動原理。
工作原理
Istio由兩個主要部分組成 - 控制平面和資料平面。控制平面包含確保其他元件之間正確互動的基本元件。在當前版本1.0中,控制平面有三個主要元件:Pilot,Mixer,Citadel。Citadel將不在這裡討論,因為它需要為服務之間的相互TLS生成證書。讓我們來看看Pilot和Mixer的設計和目的。
Pilot是主要控制組件,它分發有關我們保留在叢集內部的所有資訊 - 服務,端點和路由規則(例如,金絲雀部署規則或斷路器規則)。
Mixer是一個可選的控制平面元件,可以收集指標,日誌和有關網路互動的任何資訊。它還監控政策規則的遵守情況以及對速率限制的遵守情況。
使用邊車Sidecar代理容器實現資料平面元件。預設情況下,邊車Sidecar代理使用的是強大的Envoy。為了確保Istio對應用程式完全透明,有一個自動注射系統。最新的實現支援kubernetes版本1.9和更新(。對於kubernetes版本1.7,1.8,您可以使用初始化程式。
邊車Sidecar容器通過GRPC協議連線到Pilot,優化了叢集內部變化的下推模型。自1.6版以來,GRPC已在Envoy中使用; 在Istio中,它已經從0.8版開始實現,並且是一個試驗代理 - 一個配置啟動引數的Go over envoy的包裝器。
Pilot和Mixer是完全無狀態的元件,所有狀態都儲存在應用程式的記憶體中。它們的配置在儲存在etcd中的kubernetes Custom Resources中指定。Istio-agent獲取Pilot地址並開啟GRPC流。
正如我所說,Istio實現了對應用程式完全透明的所有功能。我們來看看其演算法的工作原理如下:
- 部署了某個微服務的新版本。
- 根據邊車容器注入型別,在配置階段新增istio-init容器和istio-agent容器(envoy),或者可以將它們手動插入kubernetes實體的pod描述中。
- istio-init容器是一個應用pod的iptables規則的指令碼。有兩種方法可以將流量重定向到istio-agent容器:使用重定向iptables規則或TPROXY 。目前預設使用重定向規則。在istio-init中,可以配置哪些流量將被攔截併發送到istio-agent。例如,為了攔截所有傳入和傳出的所有流量,您需要設定的引數-i和-b為*。您可以指定要攔截的特定埠。為避免攔截某個子網,可以使用該-x標誌指定它。
- 初始化執行後,將啟動容器,包括pilot-agent(envoy)。它通過GRPC連線到已部署的Pilot,並獲取有關群集中所有現有服務和路由策略的資訊。根據收到的資料,它配置叢集並將這些對映直接對映到k8s叢集中的應用程式端點。有一個重要時刻:envoy都是在開始偵聽時動態配置偵聽器(IP,埠對)。因此,當請求進入pod並使用iptables規則重定向到邊車時,envoy準備處理這些連線並瞭解轉發代理流量的位置。在此步驟中,資訊將傳送到Mixer,我們將在下面介紹。
最後,我們得到了一個完整的Envoy代理伺服器網路,可以從一個點(Pilot)進行配置。因此,所有入站和出站請求都通過Envoy。此外,只攔截TCP流量。這意味著kubernetes服務IP通過UDP上的kube-dns解析而無需修改。然後,在解析器之後,envoy攔截並處理出站請求,決定請求應該傳送到哪個端點(或者在有訪問策略的情況下或會觸發斷路器演算法)。
現在我們已經熟悉了Pilot,我們將瞭解Mixer的工作原理以及我們需要它的原因。
Mixer有兩個組成部分:istio-telemetry,istio-policy(最高版本0.8,它曾經是一個單獨的元件istio-mixer)。兩者都是Mixer。Istio遙測技術從邊車容器接收GRPC並報告有關服務互動和引數的資訊。Istio-policy接受檢查請求以驗證是否符合策略規則。這些策略檢查快取在客戶端(在邊車上)一段時間。報告檢查以批處理請求傳送。我們將看看如何配置它以及稍後需要設定哪些引數。
Mixer應該是一個高度可用的元件,可以不間斷地組裝和處理遙測資料。該系統是一個多級緩衝區。最初,資料在容器的邊車側緩衝,然後在Mixer側緩衝,最後傳送到所謂的Mixer後端。因此,如果任何系統元件發生故障,緩衝區將會增長,並且在系統恢復後,將重新整理緩衝區。Mixer後端是傳送遙測資料的端點:statsd,newrelic等。編寫自定義後端很容易,稍後我將展示如何。
綜上所述,使用istio-telemetry的工作流程如下:
- 有兩個服務,服務1向服務2傳送請求。
- 當請求離開服務1後,將在其邊車中被重定向。
- 邊車Envoy監控服務處理請求2並準備必要的資訊。
- 然後它使用監控報告Report請求將其傳送到istio-telemetry。
- Istio-telemetry確定是否將此報告發送到後端,傳送請求和請求內容的位置。
使用Pilot和Envoy
現在讓我們看看如何使用Pilot和邊車Envoy這兩個基本元件來設定Istio系統。讓我們回顧一下Pilot讀取的基本配置(網格):
apiVersion: v1 kind: ConfigMap metadata: name: istio namespace: istio-system labels: app: istio service: istio data: mesh: |- # disable tracing mechanism <b>for</b> now enableTracing: false # <b>do</b> not specify mixer endpoints, so that sidecar containers <b>do</b> not send the information #mixerCheckServer: istio-policy.istio-system:15004 #mixerReportServer: istio-telemetry.istio-system:15004 # interval <b>for</b> envoy to check Pilot rdsRefreshDelay: 5s # <b>default</b> config <b>for</b> envoy sidecar defaultConfig: # like rdsRefreshDelay discoveryRefreshDelay: 5s # path to envoy executable configPath: <font>"/etc/istio/proxy"</font><font> binaryPath: </font><font>"/usr/local/bin/envoy"</font><font> # <b>default</b> name <b>for</b> sidecar container serviceCluster: istio-proxy # time <b>for</b> envoy to wait be<b>for</b>e it shuts down all existing connections drainDuration: 45s parentShutdownDuration: 1m0s # by <b>default</b>, REDIRECT rule <b>for</b> iptables is used. TPROXY can be used as well. #interceptionMode: REDIRECT # port <b>for</b> sidecar container admin panel proxyAdminPort: 15000 # address <b>for</b> sending traces using zipkin protocol (not used as turned off in enableTracing option) zipkinAddress: tracing-collector.tracing:9411 # statsd address <b>for</b> 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 </font>
讓我們將所有主要控制組件(控制平面)放在名稱空間istio-system中的kubernetes中。
最低配置僅需要Pilot部署。這裡我們使用以下配置 。我們將手動配置邊車容器的注入。
Init容器配置:
initContainers: - name: istio-init args: - -p - <font>"15001"</font><font> - -u - </font><font>"1337"</font><font> - -m - REDIRECT - -i - '*' - -b - '*' - -d - </font><font>""</font><font> image: istio/proxy_init:1.0.0 imagePullPolicy: IfNotPresent resources: limits: memory: 128Mi securityContext: capabilities: add: - NET_ADMIN </font>
邊車配置:
- name: istio-proxy command: - <font>"bash"</font><font> - </font><font>"-c"</font><font> - | 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 \ </font><font>"15000"</font><font> \ --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: <b>true</b> runAsUser: 1337 volumeMounts: - mountPath: /etc/istio/proxy name: istio-envoy </font>
要成功部署,您需要為Pilot建立ServiceAccount,ClusterRole,ClusterRoleBinding和CRD; 有關這些的更多資訊,請點選此處 。結果,帶有注入的邊車envoy的服務將啟動,從pilot檢索所有發現數據,並處理請求。
關鍵是所有控制平面元件都是無狀態應用程式,並且可以輕鬆地水平擴充套件。所有資料都儲存在etcd中,作為kubernetes資源的自定義描述。
此外,可以在叢集外部執行Istio(實驗性地)並監視和共享幾個kubernetes叢集之間的服務發現。有關此資訊,請訪問此處 。在多叢集安裝中,請考慮以下限制:
- CIDR Pod和服務CIDR在所有群集中必須是唯一的,並且不得重疊。
- 必須可以從群集之間的任何Pod CIDR訪問所有CIDR Pod。
- 所有Kubernetes API伺服器必須可以相互訪問。