Dieser Artikel wurde von der Huawei Cloud Community geteilt: „ Lernen Sie Schritt für Schritt, wie man Kubernetes Sidecar schreibt “, Autor: Zhang Jian.
Was ist ein Beiwagen?
Beiwagen, wörtlich übersetzt als Beiwagen. Wie im Bild oben gezeigt, wird ein Beiwagen neben einem Motorrad installiert, um dessen Funktionen zu erweitern. Beispielsweise ist das Fahrzeug stabiler, es können mehr Personen und Güter transportiert werden und die Person, die auf dem Beiwagen sitzt, kann dem Fahrer Anweisungen geben , usw. Das Sidecar-Modell erreicht die Trennung von Steuerung und Logik , indem es dem Anwendungsdienst einen „Sidecar“ hinzufügt .
Für Microservices können wir das Sidecar-Modell verwenden, um Control Panel-Funktionen auszuführen, die keine Implementierung von Geschäftsdiensten erfordern, wie z. B. Protokollerfassung, Dienstregistrierung, Diensterkennung, Strombegrenzung und Authentifizierung. Im Vergleich zum Sidecar-Modell handelt es sich normalerweise um ein SDK-Modell wie Spring-Cloud . Die oben genannten Funktionen werden alle über SDK implementiert.
Beide Implementierungsmodi haben ihre eigenen Vor- und Nachteile. Der Sidecar-Modus führt zu zusätzlichen Leistungseinbußen und Verzögerungen, der herkömmliche SDK-Modus führt jedoch zu einem aufgeblähten Code und macht Upgrades kompliziert. Die Funktionen der Steuerungsebene und der Funktionen der Geschäftsebene können nicht separat aktualisiert werden.
Der Code dieses Artikels wurde auf gitee hochgeladen
Sidecar-Implementierungsprinzip
Viele Funktionen von Sidecar wurden eingeführt, aber wie erreicht Sidecar diese Fähigkeiten?
Es stellt sich heraus, dass in Kubernetes ein Pod die kleinste Bereitstellungseinheit ist, aber innerhalb eines Pods können mehrere Container ausgeführt werden und Speichervolumes und Netzwerkstacks werden von mehreren Containern gemeinsam genutzt. Auf diese Weise können wir mehrere Container als Beiwagen oder Init-Container (den Container initialisieren) verwenden, um die Berechtigungen des bereitgestellten Volumes anzupassen.
Beiwagen zur Protokollsammlung
Das Prinzip der Protokollsammlung im Sidecar wird durch die Verwendung des Prinzips realisiert, dass mehrere Container bereitgestellte Volumes gemeinsam nutzen können. Die Protokollsammlung wird erreicht, indem der Protokollpfad der Anwendung ausgehängt und ein anderes Programm verwendet wird, um auf die Protokolle im Pfad zuzugreifen. Hier wird cat verwendet Stattdessen stellen Sie für die Protokollerfassung die Yaml-Vorlage wie folgt bereit
APIVersion: v1 Art: Pod Metadaten: Name: Webserver Spezifikation: Bände: - Name: Shared-Logs emptyDir: {} Behälter: - Name: Nginx Bild: ttbb/nginx:mate volumeMounts: - Name: Shared-Logs mountPath: /opt/sh/openresty/nginx/logs - Name: Beiwagen-Container Bild: ttbb/base Befehl: [„sh“, „-c“, „while true; do cat /opt/sh/openresty/nginx/logs/nginx.pid; sleep 30; done“] volumeMounts: - Name: Shared-Logs mountPath: /opt/sh/openresty/nginx/logs
Verwenden Sie kubectl create -f, um einen Pod zu erstellen, und verwenden Sie den Befehl kubectl logs, um die von sidecar-container gedruckte Protokollausgabe anzuzeigen.
kubectl protokolliert den Sidecar-Container des Webservers
Anfrage-Sidecar weiterleiten
In diesem Abschnitt implementieren wir einen Sidecar, der Anfragen an die Anwendung weiterleitet. Der Anwendungscode lautet wie folgt
use std::io::prelude::*; use std::net::{TcpListener, TcpStream}; fn main() { let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); für Stream in listener.incoming() { let stream = stream.unwrap(); handle_connection(stream); } println!("Hallo Welt!"); } fn handle_connection(mut stream: TcpStream) { let mut buffer = [0; 1024]; stream.read(&mut buffer).unwrap(); let content = "Hallo"; let Response = format!( „HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}“, content.len(), Inhalt ); println!("eine Anfrage erhalten!"); stream.write(response.as_bytes()).unwrap(); stream.flush().unwrap(); }
Schreiben wir einen weiteren Sidecar, der alle 15 Sekunden Anfragen an die Anwendung sendet
benutze std::thread; verwenden Sie std::time::Duration; fn main() { Schleife { thread::sleep(Duration::from_secs(15)); let Response = reqwest::blocking::get("http://localhost:7878").unwrap(); println!("{}", Response.text().unwrap()) } }
Erstellen Sie das Image über das Skript unter dem Warehouse intput/build.sh
und führen Sie das Yaml wie folgt aus
APIVersion: v1 Art: Pod Metadaten: Name: Webserver Spezifikation: Behälter: - Name: Eingabeserver Bild: sidecar-examples:input-http-server - Name: Eingabe-Sidecar Bild: sidecar-examples:sidecar-input
Wenn Sie sich die Kubectl-Protokolle Input Input-http-server ansehen, können Sie sehen, dass Input-http-server die Anfrage erhalten hat
eine Anfrage erhalten! eine Anfrage erhalten!
Abfanganfrage-Sidecar
Anwendungscode, der alle 15 Sekunden localhost
eine Anfrage stellt
Paket com.shoothzj.sidecar akka.actor.typed.ActorSystem importieren Importieren Sie akka.actor.typed.scaladsl.Behaviors akka.http.scaladsl.Http importieren akka.http.scaladsl.model._ importieren import scala.concurrent.{ExecutionContextExecutor, Future} import scala.util.{Fehler, Erfolg} Objekt HttpClient { def main(args: Array[String]): Unit = { while (wahr) { Thread.sleep(15_000L) implizites Val-System: ActorSystem[Nothing] = ActorSystem(Behaviors.empty, "SingleRequest") // Wird am Ende für die Zukunft flatMap/onComplete benötigt impliziter Wert „executionContext“: ExecutionContextExecutor = system.executionContext val ResponseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://localhost:7979/hello")) AntwortZukunft .onComplete { case Success(res) => println(res) case Failure(_) => sys.error("etwas stimmt nicht") } } } }
Schreiben wir einen weiteren Sidecar, der http-Anfragen abfängt und Protokolle druckt
Paket com.shoothzj.sidecar akka.actor.typed.ActorSystem importieren Importieren Sie akka.actor.typed.scaladsl.Behaviors akka.http.scaladsl.Http importieren akka.http.scaladsl.model._ importieren import akka.http.scaladsl.server.Directives._ Importieren Sie scala.concurrent.ExecutionContextExecutor scala.io.StdIn importieren Objekt HttpServer { def main(args: Array[String]): Unit = { implizites Wertsystem: ActorSystem[Nothing] = ActorSystem(Behaviors.empty, "my-system") // Wird am Ende für die Zukunft flatMap/onComplete benötigt impliziter Wert „executionContext“: ExecutionContextExecutor = system.executionContext val route = path("Hallo") { erhalten { println("eine Anfrage erhalten") Complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, „<h1>Sag Hallo zu akka-http</h1>“)) } } val bindingFuture = Http().newServerAt("localhost", 7979).bind(route) while (wahr) { Thread.sleep(15_000L) } } }
Erstellen Sie das Image über das Skript unter dem Warehouse output/build.sh
und führen Sie das Yaml wie folgt aus
APIVersion: v1 Art: Pod Metadaten: Name: Ausgabe Spezifikation: Bände: - Name: Shared-Logs emptyDir: {} Behälter: - Name: Ausgabe-Workload Bild: sidecar-examples:output-workload imagePullPolicy: Niemals - Name: Sidecar-Ausgabe Bild: Sidecar-Beispiele: Sidecar-Ausgabe imagePullPolicy: Niemals
Wenn Sie sich die Ausgabe von kubectl logs „output-workload“ ansehen, können Sie sehen, dass „output-sidecar“ die Anfrage erhalten hat
HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:15:47 GMT),HttpEntity.Strict(text/html; charset=UTF-8,31 Bytes insgesamt) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:16:02 GMT),HttpEntity.Strict(text/html; charset=UTF-8,31 Bytes insgesamt) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:16:17 GMT),HttpEntity.Strict(text/html; charset=UTF-8,31 Bytes insgesamt) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:16:32 GMT),HttpEntity.Strict(text/html; charset=UTF-8,31 Bytes insgesamt) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:16:47 GMT),HttpEntity.Strict(text/html; charset=UTF-8,31 Bytes insgesamt) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:17:02 GMT),HttpEntity.Strict(text/html; charset=UTF-8,31 Bytes insgesamt) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:17:17 GMT),HttpEntity.Strict(text/html; charset=UTF-8,31 Bytes insgesamt) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(Server: akka-http/10.2.9, Datum: Di, 29. März 2022 00:17:32 GMT),HttpEntity.Strict(text/html; charset=
Broadcom kündigte die Beendigung des bestehenden VMware-Partnerprogramms Deepin-IDE-Versionsupdate, ein neues Erscheinungsbild, an. WAVE SUMMIT feiert seine 10. Ausgabe. Wen Xinyiyan wird die neueste Enthüllung haben! Zhou Hongyi: Der gebürtige Hongmeng wird auf jeden Fall Erfolg haben. Der komplette Quellcode von GTA 5 wurde öffentlich durchgesickert. Linus: Ich werde den Code an Heiligabend nicht lesen. Ich werde eine neue Version des Java-Tool-Sets Hutool-5.8.24 veröffentlichen nächstes Jahr. Lasst uns gemeinsam über Furion klagen. Kommerzielle Erkundung: Das Boot ist vorbei. Wan Zhongshan, v4.9.1.15 Apple veröffentlicht Open-Source-Multimodal-Großsprachenmodell Ferret Yakult Company bestätigt, dass 95 G-Daten durchgesickert sind