Was ist ? Это так называемый Service mesh, технология, которая добавляет уровень абстракции над сетью. Мы перехватываем весь или часть трафика в кластере и производим определенный набор операций с ним. Какой именно? Например, делаем умный роутинг, или реализуем подход circuit breaker, можем организовывать «canary deployment», частично переключая трафик на новую версию сервиса, а можем ограничивать внешние взаимодействия и контролировать все походы из кластера во внешнюю сеть. Есть возможность задавать policy правила для контроля походов между разными микросервисами. Наконец, мы можем получить всю карту взаимодействия по сети и сделать унифицированный сбор метрик полностью прозрачно для приложений.
Über den Mechanismus der Funktionsweise können Sie lesen in . Istio ist wirklich ein leistungsstarkes Werkzeug, das viele Aufgaben und Probleme lösen kann. In diesem Artikel möchte ich die häufigsten Fragen beantworten, die normalerweise zu Beginn der Arbeit mit Istio auftauchen. Das wird Ihnen helfen, schneller mit ihm zurechtzukommen.

Funktionsweise
Istio besteht aus zwei Hauptbereichen – dem Control Plane und dem Data Plane. Das Control Plane enthält die Hauptkomponenten, die den ordnungsgemäßen Betrieb der anderen Teile gewährleisten. In der aktuellen Version (1.0) hat das Control Plane drei Hauptkomponenten: Pilot, Mixer und Citadel. Citadel werden wir nicht behandeln, da es für die Erstellung von Zertifikaten zur Gewährleistung der gegenseitigen TLS-Verschlüsselung zwischen den Diensten benötigt wird. Schauen wir uns die Funktionen und den Zweck von Pilot und Mixer genauer an.

Pilot ist die zentrale Steuerkomponente, die alle Informationen über die verfügbaren Ressourcen in unserem Cluster – Dienste, deren Endpunkte und Routing-Regeln (z.B. Regeln für Canary-Deployments oder Circuit-Breaker-Regeln) – verteilt.
Mixer ist eine optionale Komponente des Control Plane, die die Möglichkeit bietet, Metriken, Protokolle und alle Informationen über die Netzwerkinteraktion zu sammeln. Außerdem überwacht er die Einhaltung von Richtlinien und die Einhaltung von Ratenlimits.
Der Datenverkehr wird durch Sidecar-Proxy-Container realisiert. Standardmäßig wird ein leistungsstarker . Dieser kann durch eine andere Implementierung, wie NGINX (nginmesh), ersetzt werden.
Damit Istio für Anwendungen vollständig transparent arbeitet, gibt es ein System für die automatische Einspeisung. Die neueste Implementierung ist für Kubernetes-Versionen 1.9+ geeignet (mutational admission webhook). Für Kubernetes-Versionen 1.7 und 1.8 besteht die Möglichkeit, Initializer zu verwenden.
Sidecar-Container verbinden sich über das GRPC-Protokoll mit Pilot, was die Push-Modellierung von Änderungen im Cluster optimiert. GRPC wird in Envoy seit Version 1.6 verwendet und in Istio seit Version 0.8, dort handelt es sich um den Pilot-Agent – eine Golang-Hülle um Envoy, die die Startparameter konfiguriert.
Pilot und Mixer sind vollständig zustandslose Komponenten, alle Zustände werden im Arbeitsspeicher gehalten. Die Konfiguration für sie wird in Form von Kubernetes Custom Resources angegeben, die in etcd gespeichert werden.
Der Istio-Agent erhält die Adresse von Pilot und öffnet einen GRPC-Stream zu ihm.
Wie bereits erwähnt, implementiert Istio die gesamte Funktionalität vollständig transparent für Anwendungen. Lassen Sie uns klären, wie das funktioniert. Der Algorithmus ist folgendermaßen:
- Wir deployen eine neue Version des Dienstes.
- Je nach Ansatz des Injectings werden der istio-init Container und der istio-agent Container (envoy) während der Anwendung der Konfiguration hinzugefügt, oder sie können bereits manuell in die Beschreibung der Pod-Entität in Kubernetes eingefügt werden.
- Der istio-init Container ist ein Skript, das die iptables-Regeln für den Pod anwendet. Es gibt zwei Optionen zur Konfiguration der Verkehrsumleitung zum istio-agent Container: die Verwendung von Redirect-Regeln für iptables, oder . Zum Zeitpunkt der Erstellung dieses Artikels wird standardmäßig der Ansatz mit Redirect-Regeln verwendet. Im istio-init besteht die Möglichkeit, festzulegen, welcher Verkehr abgefangen und an den istio-agent weitergeleitet werden soll. Zum Beispiel, um gesamten eingehenden und gesamten ausgehenden Verkehr abzufangen, müssen die Parameter
-iund-bauf*. Bestimmte Ports, die abgefangen werden sollen, können angegeben werden. Um einen bestimmten Subnetz nicht abzufangen, kann dies mit einem Flag angegeben werden.-x. - Nach dem Starten der Init-Container werden die Hauptcontainer, einschließlich des Pilot-Agenten (envoy), gestartet. Dieser verbindet sich über gRPC mit dem bereits bereitgestellten Pilot und erhält Informationen über alle vorhandenen Dienste und Routing-Politiken im Cluster. Basierend auf diesen Daten konfiguriert er die Cluster und definiert direkt die Endpunkte unserer Anwendungen im Kubernetes-Cluster. Es ist auch wichtig zu beachten, dass envoy die Listener dynamisch konfiguriert (IP-Port-Paare), die er beginnen soll zuzuhören. Daher werden, wenn Anfragen in den Pod eingehen, diese mithilfe von iptables-Redirect-Regeln an den Sidecar geleitet, wodurch envoy die Verbindungen erfolgreich verarbeiten und verstehen kann, wohin der Traffic weitergeleitet werden muss. In diesem Schritt werden auch Informationen an Mixer gesendet, den wir später betrachten werden, sowie das Senden von Tracing-Spans.
Am Ende erhalten wir ein ganzes Netzwerk von Envoy-Proxy-Servern, die wir von einem einzigen Punkt (Pilot) aus konfigurieren können. Alle eingehenden und ausgehenden Anfragen laufen über Envoy. Dabei wird ausschließlich der TCP-Datenverkehr abgefangen. Das bedeutet, dass die Kubernetes-Service-IP über kube-dns per UDP ohne Änderungen aufgelöst wird. Nach der Auflösung erfolgt die Abfangung der ausgehenden Anfrage und die Verarbeitung durch Envoy, der dann entscheidet, an welchen Endpunkt die Anfrage gesendet werden soll (oder ob sie nicht gesendet werden soll, abhängig von Zugriffsrichtlinien oder dem Circuit-Breaker-Algorithmus).
Jetzt haben wir den Pilot verstanden, und als nächstes müssen wir herausfinden, wie der Mixer funktioniert und wofür er benötigt wird. Die offizielle Dokumentation dazu kann gelesen werden. .
Der Mixer besteht aus zwei Komponenten: istio-telemetry und istio-policy (bis Version 0.8 gab es nur eine Komponente, den istio-mixer). Beide Komponenten bilden den Mixer, wobei jede ihre eigene Aufgabe hat. Istio telemetry empfängt über GRPC von den Sidecar-Containern Report-Informationen darüber, wohin Anfragen gehen und mit welchen Parametern. Istio-policy verarbeitet Check-Anfragen zur Überprüfung der Einhaltung der Policy-Regeln. Policy-Checks werden selbstverständlich nicht für jede Anfrage durchgeführt, sondern auf dem Client (im Sidecar) für eine bestimmte Zeit zwischengespeichert. Report-Checks werden in Batch-Anfragen gesendet. Wie man das konfiguriert und welche genauen Parameter gesendet werden müssen, schauen wir uns etwas später an.
Der Mixer wird als hochverfügbares Element konzipiert, das einen kontinuierlichen Betrieb zur Sammlung und Verarbeitung von Telemetriedaten gewährleistet. Das System funktioniert letztlich als mehrstufiger Puffer. Zunächst werden die Daten in den Sidecar-Containern gepuffert, danach im Mixer selbst und schließlich an die sogenannten Mixer-Backends gesendet. Wenn eines der Systemkomponenten ausfällt, wächst der Puffer, und nach der Wiederherstellung des Systems wird er geleert. Die Mixer-Backends fungieren als Endpunkte für den Versand von Telemetriedaten: statsd, newrelic usw. Es ist möglich, ein eigenes Backend zu schreiben, was relativ einfach ist, und wir werden anschauen, wie das gemacht wird.

Zusammenfassend lässt sich sagen, dass das Schema für die Arbeit mit istio-telemetry folgendermaßen aussieht.
- Service 1 sendet eine Anfrage an Service 2.
- Beim Verlassen von Service 1 wird die Anfrage in seinen eigenen Sidecar verpackt.
- Der Sidecar-Envoy überwacht, wie die Anfrage an Service 2 erfolgt, und bereitet die erforderlichen Informationen vor.
- Diese werden dann über die Report-Anfrage an istio-telemetry gesendet.
- Istio-telemetry bestimmt, ob dieser Report an die Backends gesendet werden muss, an welche genau und welche Daten gesendet werden sollen.
- Istio-telemetry sendet die Reportdaten an die Backends, wenn dies erforderlich ist.
Lassen Sie uns jetzt betrachten, wie man in einem Istio-System, das nur aus den grundlegenden Komponenten (Pilot und Sidecar Envoy) besteht, bereitstellt.
Zunächst werfen wir einen Blick auf die Hauptkonfiguration (Mesh), die der Pilot liest:
apiVersion: v1
kind: ConfigMap
metadata:
name: istio
namespace: istio-system
labels:
app: istio
service: istio
data:
mesh: |-
# derzeit senden wir noch keine Tracing-Informationen (Pilot konfiguriert die Envoys so, dass keine Sendung erfolgt)
enableTracing: false
# derzeit geben wir keine Mixer-Endpunkte an, damit die Sidecar-Container keine Informationen dorthin senden
#mixerCheckServer: istio-policy.istio-system:15004
#mixerReportServer: istio-telemetry.istio-system:15004
# wir setzen den Zeitintervall, in dem Envoy Pilot erneut anfragt (das ist für die alte Version des Envoy-Proxys)
rdsRefreshDelay: 5s
# Standardkonfiguration für den Envoy-Sidecar
defaultConfig:
# analog zu rdsRefreshDelay
discoveryRefreshDelay: 5s
# bleibt standardmäßig (Pfad zur Konfiguration und Binary des Envoy)
configPath: "/etc/istio/proxy"
binaryPath: "/usr/local/bin/envoy"
# Standardname des gestarteten Sidecar-Containers (wird z. B. in Servicenamen bei der Übertragung von Tracing-Spans verwendet)
serviceCluster: istio-proxy
# Zeit, die Envoy wartet, bevor alle eingehenden Verbindungen zwangsweise beendet werden
drainDuration: 45s
parentShutdownDuration: 1m0s
# standardmäßig werden REDIRECT-Regeln von iptables verwendet. Kann auf TPROXY geändert werden.
#interceptionMode: REDIRECT
# Port, an dem das Admin-Panel jedes Sidecar-Containers (Envoy) gestartet wird
proxyAdminPort: 15000
# Adresse, an die die Traces über das Zipkin-Protokoll gesendet werden (zu Beginn haben wir das Senden selbst deaktiviert, daher wird dieses Feld derzeit nicht verwendet)
zipkinAddress: tracing-collector.tracing:9411
# statsd-Adresse zum Senden der Metriken der Envoy-Container (deaktivieren)
# statsdUdpAddress: aggregator:8126
# Unterstützung der Option Mutual TLS deaktivieren
controlPlaneAuthPolicy: NONE
# Adresse, an der istio-pilot lauscht, um Informationen über Service Discovery an alle Sidecar-Container zu kommunizieren
discoveryAddress: istio-pilot.istio-system:15007
Alle zentralen Steuerungskomponenten (Control Plane) werden im Namespace istio-system in Kubernetes platziert.
Wir müssen mindestens nur den Pilot bereitstellen. Dazu verwenden wir
Und konfigurieren manuell das Injecting-Container-Proxy.
Initialisierungscontainer:
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
Und Sidecar:
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
Um sicherzustellen, dass alles erfolgreich gestartet wird, müssen ein ServiceAccount, ClusterRole, ClusterRoleBinding sowie CRD für Pilot eingerichtet werden, deren Beschreibungen zu finden sind. .
Letztendlich muss der Dienst, in den wir den Sidecar mit Envoy injizieren, erfolgreich starten, alle Discovery-Daten vom Pilot zu erhalten und Anfragen verarbeiten.
Es ist wichtig zu verstehen, dass alle Komponenten der Steuerungsebene zustandslose Anwendungen sind und problemlos horizontal skaliert werden können. Alle Daten befinden sich in etcd in Form von benutzerdefinierten Kubernetes-Ressourcendefinitionen.
Zudem bietet Istio (momentan experimentell) die Möglichkeit, außerhalb des Clusters zu laufen sowie Service-Discovery zwischen mehreren Kubernetes-Clustern zu betrachten und zu teilen. Mehr dazu erfahren Sie .
Bei der Multicluster-Installation sollten folgende Einschränkungen berücksichtigt werden:
- Pod CIDR und Service CIDR müssen in allen Clustern einzigartig sein und dürfen sich nicht überschneiden.
- Alle Pod CIDR sollten von allen Pod CIDR zwischen den Clustern erreichbar sein.
- Alle Kubernetes API-Server müssen füreinander erreichbar sein.
Dies sind grundlegende Informationen, die Ihnen helfen, mit Istio zu beginnen. Es gibt jedoch viele Fallstricke. Dazu gehören beispielsweise die Besonderheiten des Routings von externem Traffic (nach außen ins Cluster), die Ansätze zur Debugging von Sidecars, Profilierung, die Konfiguration des Mixers und das Schreiben eines benutzerdefinierten Mixer-Backends, die Einstellung des Tracing-Mechanismus und dessen Funktionsweise mit Envoy.
All dies werden wir in den kommenden Beiträgen behandeln. Stellen Sie Ihre Fragen, ich werde mein Bestes tun, um sie zu beantworten.
Quelle: habr.com
