Sichere und verschlüsselte Kommunikation zwischen Anthos-Clustern mit Anthos Service Mesh

Last reviewed 2021-04-30 UTC

Dieses Dokument zeigt Netzwerk-, Plattform- und Sicherheitstechnikern, die Kubernetes-Cluster verwalten, wie man externe Cluster-zu-Cluster-Kommunikation mithilfe von Gateways für eingehenden (Ingress) und ausgehenden Traffic (Egress) von Anthos Service Mesh verarbeitet. In diesem Dokument wird beschrieben, wie Sie Anthos Service Mesh verwenden, um ausgehenden Traffic von Arbeitslasten, die in einem Kubernetes-Cluster bereitgestellt sind, zu Arbeitslasten, die in einem anderen Kubernetes-Cluster ausgeführt werden, zu verschlüsseln und zu sichern. Die beschriebenen Methoden zeigen, wie separate Zertifikate für die gegenseitige, verschlüsselte Cluster-zu-Cluster-Kommunikation verwendet werden.

Die vorliegende Anleitung bezieht sich auf Kundenanforderungen, eine bestimmte Stammzertifizierungsstelle (Certificate Authority, CA) für die Kommunikation innerhalb von Clustern zu verwenden. Solche Anforderungen können in stark regulierten Märkten wie Finanzdienstleistungen oder dem Gesundheitswesen gelten. Die hier vorgestellten Anleitungen ermöglichen auch die Verwendung von anderen Endpunkten als Kubernetes-Clustern, z. B. Finanzdienstleistern oder einer API-Schnittstelle für vertrauliche Daten. Diese Anleitung ist insbesondere für Organisationen relevant, die strenge Sicherheits- und Prüfrichtlinien befolgen müssen.

Sie können die verschlüsselte Kommunikation ausführen und verarbeiten, ohne die in den Clustern ausgeführten Arbeitslasten zu beeinflussen. Eine Anleitung zum Konfigurieren eigener Cluster finden Sie in der zugehörigen Anleitung.

Einführung

Wenn Unternehmen erstmals Kubernetes verwenden, beginnen sie häufig mit einem einzelnen Cluster, bei dem die meiste Kommunikation innerhalb dieses Clusters verbleibt. Bald wird die namespace-übergreifende Interaktion immer wichtiger. Hier bietet ein Netzwerkrichtlinienanbieter wie Calico oder Cilium Unterstützung. Je umfangreicher die Containerumgebungen werden, desto relevanter wird jedoch die sichere Kommunikation zwischen externen Diensten und Ihren Containern, die in Kubernetes-Clustern ausgeführt werden.

Die Netzwerkrichtlinie ist eine gute Möglichkeit, mit herkömmlichen Sicherheitskonzepten umzugehen, z. B. dem Erstellen clusterinterner Firewallregeln. Sie ist jedoch nur begrenzt außerhalb des Clusters von Nutzen. Es ist möglich, nur eine bestimmte IP-Adresse erreichbar zu machen. Es ist jedoch keine Kontrolle über den Inhalt oder die Identität verfügbar. Daher ist ein vielseitigeres Konzept erforderlich, das auch beim Verschlüsseln des Traffics zu anderen externen Diensten hilft. Das folgende Diagramm zeigt einen Ansatz.

Verschlüsselung des Traffics mit einem privaten (geheimen) Zertifikat mit einem öffentlichen Gegenstück.

In der Welt der Anwendungen erfolgt die Verschlüsselung normalerweise mit TLS (Transport Layer Security). Das bedeutet, dass Sie den Traffic mit einem privaten (geheimen) Zertifikat mit einem öffentlichen Gegenstück verschlüsseln können, wie im obigen Diagramm gezeigt. Die empfangende Partei hält das öffentliche Zertifikat, mit dem überprüft wird, ob die Informationen von einer vertrauenswürdigen Quelle stammen. HTTPS-Webtraffic verwendet TLS, um eine sichere und verschlüsselte Kommunikation zwischen einem Client und einem Webserver zu gewährleisten. In diesem Fall stammt das öffentliche Zertifikat von einem vertrauenswürdigen Aussteller (z. B. Google Trust Services), der auch als CA bezeichnet wird und zur Public-Key-Infrastruktur (PKI) gehört. TLS verifiziert die Identität des Servers, bestätigt jedoch nicht die Identität des Clients.

In Fällen, in denen der Client selbst ebenfalls verifiziert werden muss, ist die gegenseitige Authentifizierung (mTLS) erforderlich. mTLS wird verwendet, wenn sowohl der Absender als auch der Empfänger sich selbst gegenüber der anderen Partei identifizieren müssen, wie im folgenden Diagramm dargestellt.

Traffic mit gegenseitiger Authentifizierung (mTLS) verschlüsseln.

Diese Methode wird häufig für Anwendungen verwendet, die eine zusätzliche Sicherheitsebene benötigen. Aufsichtsbehörden verlangen in der Finanzbranche und bei personenidentifizierbaren Informationen häufig mTLS.

Anthos Service Mesh

Anthos Service Mesh ist eine von Google verwaltete Service-Mesh-Lösung, die auf OSS Istio basiert. Das heißt, dass es zu 100% mit der Istio API kompatibel ist. Anthos Service Mesh kann mTLS-Funktionen auf Plattformebene statt im Anwendungscode bereitstellen. Das bedeutet, dass sie auf Dienste angewendet werden können, ohne dass jeder Dienst neu codiert werden muss. Vorgänge wie die Zertifikatsrotation sind auch Teil von Anthos Service Mesh. Dieses Dokument konzentriert sich auf mTLS und die externen Kommunikationsfunktionen von Anthos Service Mesh. Es gibt viele weitere Funktionen wie Fehlerinjektion, erweitertes Load-Balancing und Fehlerbehandlung.

Durch das Routing des gesamten Traffics über Sidecar-Proxys (Envoy) entlasten Service Meshes wie Anthos Service Mesh den Entwickler von einfachen (aber wichtigen) Aufgaben wie Verschlüsselung und der Umgang mit Zertifikaten. Durch die Verwendung eines transparenten Proxys können Service Meshes wichtige L7-Funktionen ermöglichen, beispielsweise das Routing von HTTP- und HTTPS-Aufrufen basierend auf Header-Informationen. Anthos Service Mesh ermöglicht jedoch auch eine Traffic-Kapselung und -Verschlüsselung, die die Sicherheit verbessern kann.

Beispielkonfiguration: MySQL-Kommunikation zwischen Clustern

Sie können dieses Szenario verwenden, wenn Sie eine sichere und vertrauenswürdige Kommunikation zwischen Diensten in verschiedenen Clustern haben möchten. In diesem Beispiel kommuniziert die MySQL-Clientanwendung mit einer MySQL-Server-DB-Arbeitslast, die in einem anderen Kubernetes-Cluster ausgeführt wird, wie das folgende Diagramm zeigt.

MySQL-Clientanwendung, die mit einer MySQL-Server-DB-Arbeitslast kommuniziert, die in einem anderen Kubernetes-Cluster ausgeführt wird.

Obwohl Service Meshes oft mit OSI L7 arbeiten, können Sie einige Funktionen auch zur Steuerung der L4-Kommunikation verwenden.

Damit das Konzept funktioniert, benötigen Sie Folgendes:

  • Die Kommunikation zwischen Anwendungen und Clustern muss verschlüsselt sein.
  • Die Client- und Serverkommunikation muss gegenseitig bestätigt werden (mTLS).
  • Die Client- und Serverarbeitslasten müssen nicht geändert werden.

Sie können die MySQL-Datenbank so einrichten, dass nur verschlüsselte Verbindungen akzeptiert werden. Hierfür muss der Datenbankclient geändert werden, was Sie möglicherweise nicht vollständig kontrollieren können.

Es gibt mehrere Möglichkeiten, diese Anforderungen mit Anthos Service Mesh zu erfüllen. Eine Möglichkeit besteht darin, eine gemeinsame Istio-Steuerungsebene zwischen Clustern zu erstellen und die Dienste miteinander kommunizieren zu lassen, da sie zu einem einzigen logischen Service Mesh gehören. Sie können dies für Anthos-fähige GKE-Cluster tun, indem Sie Anthos Service Mesh entweder in einem einzelnen Projekt oder in mehreren Projekten verwenden.

Da jedoch eine separate Vertrauenskette für die Cluster-zu-Cluster-Kommunikation erforderlich ist, können Sie den Ansatz Egress-Gateway <–> Ingress-Gateway mit mTLS verwenden.

Egress- und Ingress-Gateways sind Envoy-Proxys, die an den Grenzen des Mesh-Netzwerks liegen.

Sie können sie so konfigurieren, dass sie den Trafficfluss in das und aus dem Service Mesh steuern. Dies funktioniert auch für Nicht-Kubernetes-Endpunkte und ermöglicht die Verwendung unterschiedlicher Zertifikate für die verschlüsselte Kommunikation.

Ausgehenden und eingehenden Traffic von Anthos Service Mesh konfigurieren

Im vorherigen Szenario haben Sie die sichere Cluster-zu-Cluster-Kommunikation mithilfe von Egress- und Ingress-Gateways zwischen den jeweiligen Clustern gehandhabt.

Was ist ein Egress-Gateway?

Egress bezieht sich auf Traffic, der aus Ihrem Service Mesh fließt. Ein Egress-Gateway bietet einen kontrollierten Austrittspunkt für diesen Traffic.

Ohne zusätzliche Konfiguration wird für einen Pod, in den der Sidecar-Proxy eingefügt wurde, Traffic für einen Dienst außerhalb des Mesh-Netzwerks (z. B. einen öffentlichen API-Dienst) vom Pod zum Sidecar-Proxy weitergeleitet. In einem GKE-Cluster (und in den meisten anderen Kubernetes-Clustern) verwendet die Knoten-IP-Adresse eine NAT, um den Sidecar-Proxy-Traffic zu übersetzen, der direkt zur externen Adresse des Dienstes fließt. Das folgende Diagramm zeigt diese Konfiguration.

Der Client ruft die Serverseite auf, die den externen Dienst darstellt.

In diesem Diagramm ruft der Client die Serverseite auf. Diese ist der externe Dienst. Für das Mesh-Netzwerk ist dieser Traffic ausgehender Traffic. Deshalb müssen Sie das Egress-Gateway auf der Clientseite konfigurieren (z. B. den MySQL-Client).

Sie konfigurieren das Egress-Gateway, um den Aufruf an den externen Dienst weiterzuleiten. Nachdem der externe Dienst die Anfrage verarbeitet und die Antwort zurückgegeben hat, geht er wieder über das Egress-Gateway zum Clientproxy und schließlich zum Pod, der den Aufruf sendet (z. B. zum MySQL-Client).

Was ist ein Ingress-Gateway?

Ingress bezieht sich auf Traffic, der in das Service Mesh fließt. Ein Ingress-Gateway macht Dienste für die Außenwelt zugänglich (außerhalb des Service Mesh) und steuert, wie auf diese Dienste zugegriffen werden soll. Es ist mit einem Kubernetes-Ingress-Objekt vergleichbar.

Mit einem Ingress-Gateway können Sie einen einzelnen kontrollierten Einstiegspunkt definieren, an dem der Traffic in das Mesh-Netzwerk gelangt. Anfänglich wird der Traffic über den Load-Balancer geleitet. Dieser wird durch Definition eines Ingress-Gateway-Dienstes erstellt. Von dort wird die Anfrage an den Sidecar-Proxy und vom Proxy an den Pod weitergeleitet. Der Pod kann die Anfrage verarbeiten und die Antwort über dieselbe (umgekehrte) Route zurückgeben. Das folgende Diagramm zeigt diese Konfiguration.

Der Traffic geht über einen Load-Balancer ein und die Anfrage wird an einen Sidecar-Proxy und einen Pod weitergeleitet.

Dieser Traffic ist eingehender Traffic im Mesh-Netzwerk des anderen Clusters (VPC 2). Deshalb müssen Sie das Ingress-Gateway auf der Serverseite für die Verarbeitung dieser Aufrufe konfigurieren.

Die serverseitige Konfiguration des Ingress-Gateways leitet den Aufruf an den internen Dienst weiter. Nachdem der interne Dienst die Anfrage verarbeitet hat, geht die Antwort über das Ingress-Gateway zurück zum Client.

Kombination von Funktionen für ausgehendem und eingehendem Traffic für gegenseitige TLS-Verbindungen

Wie bereits erwähnt, müssen Sie für die Clientseite ein Egress-Gateway definieren, das als kontrollierter Austrittspunkt für das Service Mesh fungiert. Damit der das Mesh-Netzwerk über das Gateway verlassene Traffic mit mTLS verschlüsselt wird, können Sie eine Technik namens TLS Origination verwenden. Konfigurieren Sie ein Egress-Gateway, um TLS Origination für den Traffic zu externen Diensten durchzuführen.

Wenn der Traffic, der das Service Mesh von der Clientseite verlässt, verschlüsselt wird, müssen Sie dafür sorgen, dass sich die Serverseite für den Client selbst identifizieren und den verschlüsselten Traffic entschlüsseln kann.

Dafür verwenden Sie das Ingress-Gateway als einzelnen Einstiegspunkt in das Mesh-Netzwerk. Konfigurieren Sie das Ingress-Gateway so, dass es gegenseitig verschlüsselten Traffic erwartet.

Mesh-Netzwerk-Architekturübersicht

Im folgenden Diagramm wird beschrieben, was erforderlich ist, um dieses Konzept für das MySQL-Szenario zu implementieren, ohne Änderungen in der Anwendung oder am Server vorzunehmen.

In VPC 1 sehen Sie, dass der Clientcluster, auf dem der MySQL-Client ausgeführt wird, auf den Server zugreift. Der Server befindet sich in VPC 2.

Auf der Clientseite ist die Konfiguration stärker als auf der Serverseite, da Sie mehr Traffic abgleichen und weiterleiten müssen, um sicherzustellen, dass die Anwendung das Egress-Gateway verwendet. Diese Konfiguration muss aber nur einmal erfolgen. Nach der Implementierung ist sie relativ einfach zu verwalten.

Ein Vorteil dieses Konzepts mit Kubernetes besteht darin, dass alle Konfigurationselemente in YAML-Dateien gespeichert werden. Dies bedeutet, dass das gesamte Konstrukt in einem versionierten Repository verwendet werden kann, mit dem Sie Änderungen verfolgen und bei Bedarf einfach zurücksetzen können.

Clientseite

In diesem Unterabschnitt wird die clientseitige Konfiguration untersucht. Jedes Element im Diagramm hat eine eigene Funktion im Mesh-Netzwerk, um zu steuern, wie der Traffic durch das Egress-Gateway geleitet wird, um sein Ziel, den MySQL-Server, zu erreichen.

Traffic-Routing ist nur ein Teil der erforderlichen Funktion. Andere Elemente steuern die Verschlüsselung des Traffics, vollständig transparent, um die sichere Kommunikation zu gewährleisten. In den folgenden Abschnitten werden die Elemente untersucht, um ihre Rolle und Funktion in diesem Szenario besser zu verstehen.

Clientseitige Konfiguration, die zeigt, wie Traffic über das Egress-Gateway an den MySQL-Server weitergeleitet wird.

Diensteintrag

Ein Service Mesh erstellt eine eigene Dienstregistrierung in einem Kubernetes-Cluster. Die Steuerungsebene verwendet diese Registry, um die Sidecar-Proxys als Routingtabelle zu konfigurieren. Die in Kubernetes ausgeführten Dienste werden automatisch erkannt und der Service-Mesh-Registry hinzugefügt. Dienste, die nicht im Kubernetes-Cluster ausgeführt werden, können nicht automatisch ermittelt werden. Sie können aber mithilfe von Diensteinträgen definiert werden. Auf diese Weise kann der Client einen Eintrag als Hostnamen für die Verbindung mit externen Diensten verwenden.

In Anthos Service Mesh werden vollständig qualifizierte Domainnamen (Fully Qualified Domain Names, FQDNs) verwendet, um alle Dienste zu identifizieren. Der FQDN ist der wichtigste Teil dieses Konstrukts, da die Zertifikate auf dem Hostnamen basieren. Der FQDN kann zwar geändert werden, aber auch alle erforderlichen Zertifikate müssen dann neu generiert werden.

Wenn Sie die Kommunikation aktivieren möchten, müssen Sie das Service Mesh so konfigurieren, dass Aufrufe an den externen Dienst überwacht werden, um den Traffic ordnungsgemäß weiterzuleiten. Mit dem Mesh-Netzwerk können Sie einen Diensteintrag definieren, der auf diesen externen Dienst verweist.

Dieses Konstrukt heißt MESH_EXTERNAL und ist für diese Anwendungsfälle ideal geeignet. Sie können auch angeben, was Sie suchen. Da dies ein L4-Anwendungsfall ist und Sie nur die IP-Adresse und den Port steuern können, müssen Sie dem Mesh-Netzwerk das Protokoll und die spezifischen Ports mitteilen – in diesem Fall TCP und Port 3306 (Standard-MySQL-Protokollport). Außerdem überwacht das serverseitige Gegenstück (wie im vorherigen Diagramm dargestellt) Port 13306 (das Egress-Gateway des Serverclusters). Schließlich müssen Sie Ihren Diensteintrag anweisen, Traffic mit diesem Port-Tag zu erfassen.

Der folgende YAML-Diensteintrag aus dem Beispiel veranschaulicht diese Konfiguration:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
 name: mysql-external
spec:
 hosts:
   - mysql.fqdn.example
 location: MESH_EXTERNAL
 ports:
   - number: 3306
     name: tcp
     protocol: TCP
   - number: 13306
     name: tls
     protocol: TLS
 resolution: DNS
 endpoints:
   - address: mysql.fqdn.example
     ports:
       tls: 13306

Mit dem Feld hosts können Sie den FQDN des externen Dienstes festlegen oder das Feld location auf MESH_EXTERNAL setzen. Sie müssen auch die vom externen Dienst verwendeten ports-Werte angeben, in diesem Fall 13306 und 3306. 13306 ist der bereitgestellte Port des serverseitigen Ingress-Gateways. Es ist wichtig, beides in diesem Diensteintrag anzugeben. Für das Protokoll müssen Sie TLS angeben, da diese Verbindung eine L4-basierte TLS-Kommunikation ermöglicht.

Wenn Sie den Diensteintrag definiert haben, kann das Mesh-Netzwerk Aufrufe überwachen und das Routing anhand dieser Regeln ändern.

Diensteinträge müssen auf vorhandenen DNS- oder IP-Adresseinträgen basieren. Das bedeutet, dass der DNS-Name bereits von einem DNS-Server aufgelöst werden kann. Sie können beispielsweise einen zentralen DNS-Dienst in Kubernetes verwenden und Einträge hinzufügen, die noch nicht in kube-dns vorhanden sind. Mit dem Diensteintrag können Sie keinen DNS-Eintrag erstellen.

Virtueller Dienst

Der virtuelle Dienst ist eine Definition, die sich auf Traffic-Routingmuster auswirkt. Sorgen Sie mithilfe des virtuellen Dienstes dafür, dass Aufrufe vom MySQL-Client an den Diensteintrag an das Egress-Gateway weitergeleitet werden. Sie können einen virtuellen Dienst einrichten, um den Traffic anhand stark unterschiedlicher Faktoren weiterzuleiten. Bei einem L7-Anwendungsfall gehen diese Faktoren über das Traffic-Routing hinaus. Sie können dem virtuellen Dienst beispielsweise mitteilen, wie er reagieren soll, wenn ein Ziel nicht erreichbar ist. In diesem Beispiel wird ein Teil dieser Funktion verwendet, um übereinstimmenden Traffic zur weiteren Verarbeitung an das Egress-Gateway weiterzuleiten.

Virtuellen Dienst verwenden, um Traffic vom Pod über den Proxy an das Egress-Gateway und vom Egress-Gateway an den externen Dienst weiterzuleiten.

Das obige Diagramm zeigt, wie Sie mit dem virtuellen Dienst Traffic vom Pod über den Proxy zum Egress-Gateway und vom Egress-Gateway an den externen Dienst weiterleiten.

Sie müssen auch den Port Ihres Egress-Gateways (extern) angeben, der standardmäßig 15443 ist. Dieser Port wird auf dem Egress-Gateway festgelegt, sobald Sie es erstellen. Sie können einen beliebigen anderen freien Port auswählen, müssen jedoch das Gateway patchen, um den ausgewählten Port zu öffnen.

Das folgende Code-Snippet zeigt, wie eine solche virtuelle Dienstdefinition aussehen könnte:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: direct-mysql-through-egress-gateway
spec:
 hosts:
   - mysql.fqdn.example
 gateways:
   - istio-egressgateway-mysql
   - mesh
 tcp:
   - match:
       - gateways:
           - mesh
         port: 3306
     route:
       - destination:
           host: istio-egressgateway.istio-system.svc.cluster.local
           subset: mysql
           port:
             number: 15443
         weight: 100
   - match:
       - gateways:
           - istio-egressgateway-mysql
         port: 15443
     route:
       - destination:
           host: mysql.fqdn.example
           port:
             number: 13306
         weight: 100

Das Feld hosts mit der FQDN-URL wird zum Anwenden der Abgleichsregeln speziell für die angegebene URL verwendet. Die erste match-Klausel wird im Mesh-Netzwerk definiert. Dabei handelt es sich um ein reserviertes Keyword, das für alle Gateways innerhalb des Mesh-Netzwerks gilt. Der erste route-Block wird definiert, um dem Mesh-Netzwerk mitzuteilen, was zu tun ist, wenn die Übereinstimmung wahr ist. In diesem Fall senden Sie den übereinstimmenden Traffic an das Egress-Gateway. Hier wird der Port für den Egress-Port zusätzlich zur Gewichtung der Route definiert. Der Block erwähnt auch einen subset-Wert, den Sie später definieren.

Die zweite match-Klausel wird auf das Egress-Gateway angewendet. Der zweite route-Block, der an die zweite match-Klausel angehängt ist, konfiguriert das Mesh-Netzwerk so, dass der Traffic an den Servercluster-Ingress gesendet wird. Dazu wird das Feld host mit dem FQDN für eingehenden Traffic verwendet und Port 13306 angegeben.

Für den nächsten Schritt müssen Sie die Zertifikatinjektion in das Gateway programmieren, damit die mTLS-Kommunikation funktioniert.

Zielregeln

Nachdem Sie den Traffic korrekt identifiziert (Diensteintrag) und vom Pod über den Proxy an das Gateway (virtueller Dienst) weitergeleitet haben, wird der Traffic im nächsten Schritt verschlüsselt. Verwenden Sie Zielregeln, um den Traffic zu verschlüsseln. Solche Regeln in einem Service Mesh werden auf den Traffic nach dem Routing angewendet. Sie werden verwendet, um Load-Balancing und andere Trafficverwaltungsfunktionen einzuführen.

Zielregeln auf Traffic nach dem Routing anwenden.

In diesem Fall verwenden Sie Zielregeln, um ein Standard-Load-Balancing-Muster zu definieren und Zertifikate hinzuzufügen, um Endpunkte mit mTLS-Kommunikation zu aktivieren. Dieser Schritt wird durch den Abgleich des FQDN des MySQL-Servers, der über das Ingress-Gateway des Serverclusters bereitgestellt wird, und durch die Definition einer mTLS-Regel durchgeführt.

Die folgende Definition ist ein Beispiel für eine solche Zielregel:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-mysql
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
    - name: mysql
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN
        portLevelSettings:
          - port:
              number: 15443
            tls:
              mode: ISTIO_MUTUAL
              sni: mysql.fqdn.example

Das Feld host ist auf den Cluster-FQDN des Egress-Gateways festgelegt. Die erste Zielregel führt die interne Mesh-Netzwerk-Verschlüsselung des Traffics mit dem Modus ISTIO_MUTUAL aus. Verwenden Sie dazu den FQDN des Egress-Gateways. Im Code-Snippet definieren Sie ein subset, das verwendet wird, um ein Round-Robin-Load-Balancing zu erstellen und den Port auf 15443 zu setzen (überschreiben). Das Egress-Gateway verwendet diesen Port, um den Traffic zu senden.

Es ist wichtig, dass Sie das Feld tls korrekt festlegen, da es die Richtlinie für das innere Mesh-Netzwerk definiert (ISTIO_MUTUAL). Im Feld sni (Service Name Indication) fügen Sie den FQDN des Ingress-Gateways aus dem Servercluster hinzu.

Die zweite Zielregel verschlüsselt den Traffic mit den bereitgestellten benutzerdefinierten Root-CA-Zertifikaten, bevor sie über das Egress-Gateway gesendet werden:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: originate-mtls-for-mysql
spec:
 host: mysql.fqdn.example
 trafficPolicy:
   loadBalancer:
     simple: ROUND_ROBIN
   portLevelSettings:
   - port:
       number: 13306
     tls:
       mode: MUTUAL
       credentialName: client-credential
       sni: mysql.fqdn.example

Das Feld host wird wieder auf den externen FQDN gesetzt. Das Feld trafficPolicy legt den Load-Balancer-Modus auf ROUND_ROBIN fest. Außerdem wird der Port auf 13306 und der tls-Modus auf MUTUAL gesetzt, da Sie jetzt die benutzerdefinierten Stamm-CA-Zertifikate verwenden und das Pendant – das Ingress-Gateway, das ebenfalls tls MUTUAL verwendet – sich mit den gleichen signierten Stamm-CA-Zertifikaten identifizieren muss. Über diesen Port kann der Traffic über sein Ingress-Gateway durch den Servercluster geleitet werden, um die MySQL-Datenbank zu erreichen.

Die Verschlüsselung mit den benutzerdefinierten Stamm-CA-Zertifikaten erfolgt in der Regel über den Envoy-Secret Discovery Service (SDS). Dazu wird in Kubernetes ein Secret verwendet, das die Zertifikate enthält. Den Secret-Namen fügen Sie in der Zielregel mithilfe des Felds credentialName ein.

Kurz gesagt gilt für Traffic Folgendes:

  • Er wird von MySQL transparent für einen externen FQDN ausgegeben. Dieser FQDN ist in der Mesh-Registrierung vorhanden.
  • Er wird durch eine Zielregel mit internen Mesh-Netzwerk-Zertifikaten verschlüsselt.
  • Es wird von einem virtuellen Dienst zum Gateway weitergeleitet.
  • Er wird mit einer benutzerdefinierten Stamm-CA durch eine Zielregel verschlüsselt. Dies unterscheidet sich von der Mesh-Netzwerk-CA, die für Mesh-Netzwerk-Zertifikate verwendet wird.
  • Er wird über das Egress-Gateway im mTLS-Modus weitergeleitet.

Serverseite

In diesem Szenario ist die Serverseite einfacher zu konfigurieren als die Clientseite. Dafür benötigen Sie lediglich ein Ingress-Gateway und einen virtuellen Diensteintrag für die Weiterleitung des Traffics zum MySQL-DB-Server, wie im folgenden Diagramm dargestellt.

Serverseitige Konfiguration mit einem Ingress-Gateway und einem virtuellen Diensteintrag, über den Traffic an den MySQL-Server weitergeleitet wird.

Ingress-Gateway des Serverclusters

Das Ingress-Gateway stellt Port 13306 bereit. Dieser kann ein beliebiger Port sein. In diesem Fall wird jedoch zur einfacheren Identifizierung eine "1" vor dem MySQL-Standardport eingefügt. Aus Sicherheitsgründen empfehlen wir nicht, den Standard-MySQL-Port (3306) direkt über das Internet freizugeben.

Da das standardmäßige Istio-Gateway Port 13306 nicht überwacht, müssen Sie diese Funktion hinzufügen. Mit dem folgenden Beispiel-Code-Snippet wird Port 13306 an das Gateway gepatcht:

[{
  "op": "add",
  "path": "/spec/ports/0",
  "value": {
    "name": "tls-mysql",
    "protocol": "TCP",
    "targetPort": 13306,
    "port": 13306
  }
}]

Sie können diesen Code in einer JSON-Datei speichern und mit dem kubectl-Patch-Befehl verwenden, um ihn auf den Ingress-Gateway-Dienst anzuwenden.

Für eine ordnungsgemäße Verarbeitung des Traffics muss das Ingress-Gateway im Modus MUTUAL eingerichtet sein.

An diesem Punkt entschlüsselt das Ingress-Gateway den eingehenden Traffic mit dem Zertifikat aus seinem Anmeldedatenspeicher und sendet den Traffic an das Mesh-Netzwerk, wo die internen Zertifikate des Mesh-Netzwerks verwendet werden, um den Traffic neu zu verschlüsseln. Das folgende Beispielcode-Snippet zeigt, wie dies konfiguriert werden kann:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: gateway-mysql
spec:
 selector:
   istio: ingressgateway # Istio default gateway implementation
 servers:
 - port:
     number: 13306
     name: tls-mysql
     protocol: TLS
   tls:
     mode: MUTUAL
     credentialName: mysql-credential
   hosts:
   - "mysql.fqdn.example"

In diesem Beispiel wird das standardmäßige Istio-Ingress-Gateway unter dem Feld selector verwendet. Mit dem Feld servers können Sie die Ports number (13306) und protocol (TLS) festlegen, die vom eingehenden Traffic erwartet werden. Es ist wichtig, dem Port einen eindeutigen Namen zu geben.

Definieren Sie tls und geben Sie über das Feld credentialName ein Secret mit dem Zertifikat an, das von der Stammzertifizierungsstelle signiert wurde, die für das Egress-Gateway verwendet wird. Das Zertifikat muss in einem Kubernetes-Secret gespeichert sein.

Abschließend möchten Sie den Traffic abgleichen, der den MySQL DB-FQDN weiterleitet. Die Namensauflösung für diesen FQDN, der unter hosts festgelegt ist, muss auf die öffentliche IP-Adresse des Ingress-Gateways festgelegt werden.

Virtueller Dienst des Serverclusters

Nachdem der Traffic über Port 13306 vom Egress-Gateway des Clientclusters (Ursprung) zum Mesh-Netzwerk gelangt ist, müssen Sie diesen Traffic identifizieren und dafür sorgen, dass er den MySQL-DB-Server erreicht. Definieren Sie dazu einen virtuellen Dienst:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: mysql-virtual-service
spec:
 hosts:
   - "mysql.fqdn.example"
 gateways:
   - gateway-mysql
 tcp:
   - route:
     - destination:
         port:
           number: 3306
         host: mysql.default.svc.cluster.local

Um den Traffic an den MySQL-DB-Dienst zu senden, müssen Sie den FQDN-Host mit dem Feld hosts noch einmal prüfen. Außerdem müssen Sie das Feld gateways konfigurieren, um festzulegen, wo diese virtuelle Dienstdefinition angewendet werden soll. Dies ist das Gateway-Objekt, das Sie in der vorherigen YAML-Datei definiert haben. Legen Sie das Feld tcp fest, da es sich um L4-Traffic handelt, und legen Sie das Feld route so fest, dass es auf den MySQL-DB-Kubernetes-Dienst verweist. Sie müssen den Dienstnamen unter dem Feld host mithilfe des internen FQDN des Kubernetes-Clusters angeben.

Die MySQL-DB erhält Anfragen vom Client an Port "3306". Der Traffic durchläuft den Sidecar-Proxy des MySQL-DB-Servers.

Die MySQL-DB kann Anfragen vom Client an Port 3306 erhalten. Der Traffic durchläuft den Sidecar-Proxy des MySQL-DB-Servers. Für den MySQL-DB-Server wirkt es wie eine lokale, unverschlüsselte Anfrage für den Zugriff auf die Datenbank.

Nachdem der Server den Aufruf beantwortet hat, wird der Traffic mit derselben Route zurück zum Client geleitet und für den Client sieht es aus, als ob eine lokale Datenbank den Aufruf gerade beantwortet hat.

Der Traffic wird dreimal mit verschiedenen Zertifikaten verschlüsselt, die vom Client zum Server übertragen werden. Dadurch wird die Kommunikation zwischen dem Client und dem Server gesichert.

Der Traffic wird zum ersten Mal auf der Clientseite im Mesh-Netzwerk ver- oder entschlüsselt, und zwar mit Zertifikaten, die die Mesh-Netzwerk-Zertifizierungsstelle verwenden.

Das zweite Mal wird der Traffic verschlüsselt, wenn er das Mesh-Netzwerk am Egress-Gateway verlässt, wobei ein Zertifikat von einer benutzerdefinierten Stamm-CA verwendet wird. Anschließend wird der Traffic auf dem Ingress-Gateway mit einem Zertifikat authentifiziert und entschlüsselt, das von derselben benutzerdefinierten Stamm-CA signiert wurde.

Das letzte (dritte) Mal wird der Traffic im Mesh-Netzwerk auf der Serverseite verschlüsselt oder entschlüsselt wird, wenn er vom Ingress-Gateway zum MySQL-Server geleitet wird. Auch hier werden (da es sich um ein internes Mesh-Netzwerk handelt) die Zertifikate der Mesh-Netzwerk-Zertifizierungsstelle verwendet.

In diesem Szenario muss die Kommunikation zwischen den beiden Clustern mit der genannten Stamm-CA verschlüsselt werden. Durch Anwendung dieser Konfiguration ist es möglich, diesen Teil separat und unabhängig von den internen Mesh-Netzwerk-Zertifikaten und der Anwendung selbst zu verarbeiten.

Durch diesen zusätzlichen Schritt können Sie diese Zertifikate auch leicht regelmäßig rotieren, ohne die Mesh-Netzwerk-Zertifizierungsstelle der jeweiligen Kubernetes-Cluster ändern zu müssen.

Nächste Schritte