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

Funktionsweise
Istio besteht aus zwei Hauptbereichen – Control Plane und Data Plane. Die Control Plane enthält die wichtigsten Komponenten, die den reibungslosen Betrieb der anderen gewährleisten. In der aktuellen Version (1.0) hat die Control Plane drei Hauptkomponenten: Pilot, Mixer, Citadel. Citadel werden wir nicht näher betrachten, da es für die Generierung von Zertifikaten zum Schutz der gegenseitigen TLS-Authentifizierung zwischen Diensten erforderlich ist. Lassen Sie uns die Struktur und den Zweck von Pilot und Mixer genauer ansehen.

Pilot ist die Hauptsteuerkomponente, die alle Informationen über unsere Ressourcen im Cluster – die Dienste, deren Endpoints und Routing-Regeln (zum Beispiel Regeln für Canary Deployment oder Circuit Breaker-Regeln) – verbreitet.
Mixer ist eine optionale Komponente der Control Plane, die die Möglichkeit bietet, Metriken, Protokolle und jede Art von Informationen über die Netzwerkinteraktion zu sammeln. Außerdem überwacht er die Einhaltung von Policy-Regeln und das Einhalten von Ratenbegrenzungen.
Die Data Plane wird durch Sidecar-Proxy-Container implementiert. Standardmäßig wird der leistungsstarke verwendet. Er kann durch eine andere Implementierung, wie z.B. Nginx (nginmesh), ersetzt werden.
Damit Istio vollständig transparent für Anwendungen funktioniert, gibt es ein automatisches Injektionssystem. Die letzte 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 den GRPC-Protokoll mit Pilot, was es ermöglicht, das Push-Modell von Änderungen im Cluster zu optimieren. GRPC begann ab Version 1.6 in Envoy verwendet zu werden und wird in Istio seit Version 0.8 eingesetzt und stellt die pilot-agent – eine Golang-Hülle über Envoy, die die Startparameter konfiguriert.
Pilot und Mixer sind vollständig stateless Komponenten, alle Zustände werden im Speicher gehalten. Die Konfiguration für sie wird in Form von Kubernetes Custom Resources definiert, die in etcd gespeichert werden.
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 verstehen, wie. Der Algorithmus ist folgender:
- Wir setzen eine neue Version des Dienstes ein.
- Je nach Ansatz des Injecting wird der istio-init Container sowie der istio-agent Container (envoy) während der Konfigurationsanwendung hinzugefügt, oder sie können bereits manuell in die Beschreibung der Kubernetes Pod-Entität eingefügt worden sein.
- Der istio-init Container ist ein Skript, das iptables-Regeln für den Pod anwendet. Es gibt zwei Optionen zur Konfiguration der Umleitung des Traffics zum istio-agent Container: entweder redirect iptables-Regeln verwenden, oder . Zum Zeitpunkt des Schreibens wird standardmäßig der Ansatz mit redirect-Regeln verwendet. Im istio-init gibt es die Möglichkeit festzulegen, welcher Traffic abgefangen und zum istio-agent geleitet werden soll. Zum Beispiel, um gesamten eingehenden und gesamten ausgehenden Traffic abzufangen, müssen die Parameter
-iund-bauf den Wert*. Bestimmte Ports, die abgefangen werden sollen, können angegeben werden. Um ein bestimmtes Subnetz nicht abzufangen, kann dies mit der Option-x. - Nach der Ausführung der Init-Container werden die Hauptcontainer gestartet, einschließlich des pilot-agent (envoy). Dieser verbindet sich über GRPC mit dem bereits bereitgestellten Pilot und erhält Informationen über alle bestehenden Dienste und Routing-Politiken im Cluster. Basierend auf diesen Daten konfiguriert er Cluster und trägt die Endpunkte unserer Anwendungen im Kubernetes-Cluster ein. Ein wichtiger Punkt ist auch, dass envoy dynamisch Listenereinstellungen (IP-Paar, Port) konfiguriert, die er zu lauschen beginnt. Wenn also Anfragen in den Pod gelangen, werden sie durch Umleitung mit iptables-Regeln in den Sidecar geleitet, kann envoy diese Verbindungen erfolgreich verarbeiten und verstehen, wohin der Traffic weitergeleitet werden muss. Zu diesem Zeitpunkt werden auch Informationen an den Mixer gesendet, den wir später betrachten werden, sowie die Übertragung von Tracing-Spans.
Am Ende erhalten wir ein 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 nur TCP-Traffic abgefangen. Das bedeutet, dass die Kubernetes-Service-IP mittels kube-dns über UDP ohne Veränderung aufgelöst wird. Erst nach der Auflösung erfolgt die Abfangung der ausgehenden Anfrage und deren Verarbeitung durch envoy, der dann entscheidet, an welchen Endpunkt die Anfrage gesendet werden soll (oder ob sie nicht gesendet werden soll, im Falle von Zugriffsrichtlinien oder der Aktivierung eines Circuit-Breaker-Algorithmus).
Wir haben uns mit Pilot beschäftigt, jetzt müssen wir verstehen, wie Mixer funktioniert und wofür er gebraucht wird. Die offizielle Dokumentation dazu kann gelesen werden. .
Der Mixer besteht in seiner aktuellen Form aus zwei Komponenten: istio-telemetry und istio-policy (bis zur Version 0.8 war dies eine einzige Komponente, istio-mixer). Beide stellen eine Art Mixer dar, wobei jeder für seine spezifische Aufgabe verantwortlich ist. Istio telemetry empfängt über GRPC von den Sidecar-Containern Berichtsinformationen darüber, wer wohin geht und mit welchen Parametern. Istio-policy erhält Check-Anfragen zur Überprüfung der Einhaltung von Policy-Regeln. Policy-Prüfungen werden natürlich nicht für jede Anfrage durchgeführt, sondern auf dem Client (im Sidecar) für eine bestimmte Zeit zwischengespeichert. Berichtskontrollen werden in Batchanfragen gesendet. Wie man diese konfiguriert und welche Parameter gesendet werden müssen, werden wir gleich sehen.
Der Mixer wird als hochverfügbare Komponente betrachtet, die den kontinuierlichen Betrieb der Sammlung und Verarbeitung von Telemetriedaten sicherstellt. Am Ende ergibt sich ein mehrschichtiger Puffer. Zunächst werden die Daten auf der Seite der Sidecar-Container zwischengespeichert, dann auf der Seite des Mixers und schließlich an die sogenannten Mixer-Backends gesendet. Wenn einer der Systemkomponenten ausfällt, wächst der Puffer, und nach der Wiederherstellung des Systems wird er geleert. Die Mixer-Backends sind Endpunkte für den Versand von Telemetriedaten: statsd, newrelic usw. Man kann ein eigenes Backend schreiben, das ist relativ einfach, und wir werden sehen, wie das geht.

Zusammengefasst ist das Schema der Arbeit mit istio-telemetry wie folgt.
- Dienst 1 sendet eine Anfrage an Dienst 2.
- Beim Verlassen von Dienst 1 wird die Anfrage in seinen eigenen Sidecar gewickelt.
- Der Sidecar Envoy überwacht, wie die Anfrage zu Dienst 2 verläuft und bereitet die benötigten Informationen vor.
- Dann sendet er diese Informationen an istio-telemetry mit Hilfe einer Berichtsanfrage.
- Istio-telemetry bestimmt, ob dieser Bericht an die Backends gesendet werden muss, an welche genau und welche Daten gesendet werden müssen.
- Istio-telemetry sendet Berichtsdaten an das Backend, wenn dies erforderlich ist.
Nun schauen wir uns an, wie man ein Istio-System bereitstellt, das nur aus den Hauptkomponenten (Pilot und Sidecar Envoy) besteht.
Zunächst betrachten wir die grundlegende Konfiguration (Mesh), die der Pilot liest:
apiVersion: v1
kind: ConfigMap
metadata:
name: istio
namespace: istio-system
labels:
app: istio
service: istio
data:
mesh: |-
# Derzeit aktivieren wir das Senden von Tracing-Informationen nicht (Pilot konfiguriert die Envoys so, dass das Senden nicht erfolgt)
enableTracing: false
# Momentan 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 ein zeitliches Intervall, in dem der Envoy den Pilot erneut abfragt (das gilt für die alte Version des Envoy-Proxys)
rdsRefreshDelay: 5s
# Standardkonfiguration für den Envoy Sidecar
defaultConfig:
# ähnlich wie rdsRefreshDelay
discoveryRefreshDelay: 5s
# Beibehalten der Standardeinstellungen (Pfad zur Konfiguration und zum Envoy-Binärdatei)
configPath: "/etc/istio/proxy"
binaryPath: "/usr/local/bin/envoy"
# Standardname des gestarteten Sidecar-Containers (wird z.B. in Dienstnamen beim Senden von Tracing-Spans verwendet)
serviceCluster: istio-proxy
# Zeit, die der Envoy wartet, bevor er alle bestehenden Verbindungen zwangsweise schließt
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) ausgeführt wird
proxyAdminPort: 15000
# Adresse, an die die Traces über das Zipkin-Protokoll gesendet werden (anfangs haben wir das Senden selbst deaktiviert, daher wird dieses Feld derzeit nicht verwendet)
zipkinAddress: tracing-collector.tracing:9411
# statsd-Adresse zum Senden von Metriken der Envoy-Container (deaktiviert)
# statsdUdpAddress: aggregator:8126
# Unterstützung für Mutual TLS wird deaktiviert
controlPlaneAuthPolicy: NONE
# Adresse, an der der istio-pilot lauscht, um Informationen über die Service-Entdeckung an alle Sidecar-Container zu übertragen
discoveryAddress: istio-pilot.istio-system:15007
Alle wichtigen Steuerungskomponenten (Control Plane) platzieren wir im Namespace istio-system in Kubernetes.
Mindestens müssen wir nur den Pilot bereitstellen. Dafür verwenden wir
Und konfigurieren manuell das Injizieren des Sidecar-Containers.
Init-Container:
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 alles erfolgreich zu starten, muss ein ServiceAccount, ClusterRole, ClusterRoleBinding und CRD für Pilot eingerichtet werden, deren Beschreibungen zu finden sind. .
Schließlich muss der Dienst, in den wir den Sidecar mit envoy injizieren, erfolgreich gestartet werden, um alle Entdeckungen von Pilot zu erhalten und Anfragen zu bearbeiten.
Es ist wichtig zu verstehen, dass alle Komponenten des Control Plane zustandslose Anwendungen sind und problemlos horizontal skaliert werden können. Alle Daten liegen in etcd in Form von benutzerdefinierten Kubernetes-Ressourcebeschreibungen vor.
Außerdem hat Istio (noch experimentell) die Möglichkeit, außerhalb des Clusters zu laufen und Service Discovery zwischen mehreren Kubernetes-Clustern zu betrachten und zu teilen. Mehr dazu kann man lesen. .
Bei der Multicluster-Installation sind die folgenden Einschränkungen zu beachten:
- Pod CIDR und Service CIDR müssen über alle Cluster einzigartig sein und dürfen sich nicht überschneiden.
- Alle Pod CIDR müssen von allen Pod CIDR zwischen den Clustern erreichbar sein.
- Alle Kubernetes API-Server müssen einander erreichbar sein.
Dies sind die grundlegenden Informationen, die Ihnen den Einstieg in Istio erleichtern. Allerdings gibt es noch viele weitere Fallstricke. Zum Beispiel die Besonderheiten des Routings von externem Verkehr (außerhalb des Clusters), Ansätze zur Fehlersuche bei Sidecars, Profiling, Konfiguration des Mixers und die Erstellung einer benutzerdefinierten Mixer-Backend, Konfiguration von Tracing-Mechanismen und deren Funktion mit envoy.
All dies werden wir in den nächsten Veröffentlichungen behandeln. Stellen Sie Ihre Fragen, ich werde versuchen, sie zu beantworten.
Quelle: habr.com
