この記事は、Huawei Cloud Community「Kubernetes サイドカーの書き方をステップごとに教えます」(著者: Zhang Jian) から共有されたものです。
サイドカーとは何ですか?
サイドカー、直訳するとサイドカー。上の写真のようにサイドカーをバイクの横に設置することで、走行が安定したり、より多くの人や荷物を牽引したり、サイドカーに座った人がドライバーに指示を出したりするなど、機能を拡張することができます。 、など。サイドカー モデルは、アプリケーション サービスに「サイドカー」を追加することで、制御とロジックの分離を実現します。
マイクロサービスの場合、サイドカー モデルを使用して、ログ収集、サービス登録、サービス検出、電流制限、認証などのビジネス サービスの実装を必要としないコントロール パネル機能を実行できます。通常、サイドカー モデルと比較されるのは、spring-cloudのような SDK モデルであり、上記の機能はすべて SDK を通じて実装されます。
どちらの実装モードにも独自の長所と短所があります。サイドカー モードでは追加のパフォーマンス損失と遅延が発生しますが、従来の SDK モードではコードが肥大化し、アップグレードが複雑になります。コントロール プレーン機能とビジネス プレーン機能を個別にアップグレードすることはできません。
この記事のコードはgiteeにアップロードされました
サイドカーの実装原理
サイドカーのさまざまな機能が紹介されていますが、サイドカーはどのようにしてこれらの機能を実現しているのでしょうか。
Kubernetes では、ポッドがデプロイメントの最小単位ですが、ポッド内では複数のコンテナーの実行が許可され、ストレージ ボリュームとネットワーク スタックが複数のコンテナー間で共有されることがわかりました。このようにして、複数のコンテナをサイドカーとして使用したり、init-container (コンテナの初期化) を使用して、マウントされたボリュームのアクセス許可を調整したりできます。
ログ収集サイドカー
ログ収集サイドカーの原理は、複数のコンテナがマウントされたボリュームを共有できる原理を利用して実現されます。ログ収集は、アプリケーションのログ パスを張り出し、別のプログラムを使用してパス内のログにアクセスすることで実現されます。ここでは cat を使用しますログを収集するには、次のように yaml テンプレートをデプロイします。
apiVersion: v1 種類: ポッド メタデータ: 名前: Web サーバー 仕様: ボリューム: - 名前: 共有ログの emptyDir: {} コンテナー: - 名前: nginx イメージ: ttbb/nginx:mate volumeMounts: - 名前: 共有ログの マウントパス: /opt /sh/openresty/nginx/logs - 名前: サイドカーコンテナ イメージ: ttbb/base コマンド: ["sh","-c","while true; do cat /opt/sh/openresty/nginx/logs/nginx. pid; スリープ 30; 完了"] ボリュームマウント: - 名前: 共有ログ マウントパス: /opt/sh/openresty/nginx/logs
kubectl create -f を使用してポッドを作成し、kubectl logs コマンドを使用して、sidecar-container によって出力されたログ出力を確認します。
kubectl ログ Web サーバー サイドカー コンテナー
転送リクエストサイドカー
このセクションでは、リクエストをアプリケーションに転送するサイドカーを実装します。アプリケーションのコードは次のとおりです。
std::io::prelude::* を使用します。 std::net::{TcpListener、TcpStream} を使用します。 fn main() { letlistener = TcpListener::bind("127.0.0.1:7878").unwrap(); ストリームの場合、listener.incoming() { let stream = stream.unwrap(); ハンドル接続(ストリーム); println !("こんにちは、世界!"); } fn handle_connection(mut stream: TcpStream) { mut バッファ = [0; 1024]; stream.read(&mut バッファ).unwrap(); let content = "こんにちは"; let response = format!( "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", content.len(), content ); println!("リクエストを受け取ります!"); stream.write(response.as_bytes()).unwrap(); stream.flush().unwrap(); }
15 秒ごとにアプリケーションにリクエストを行う別のサイドカーを作成しましょう
std::thread を使用します。 std::time::Duration を使用します。 fn main() { ループ { thread::sleep(Duration::from_secs(15)); let 応答 = reqwest::blocking::get("http://localhost:7878").unwrap(); println!("{}"、response.text().unwrap()) } }
ウェアハウスの下のスクリプトを通じてイメージを構築しintput/build.sh
、次のように yaml を実行します。
apiVersion: v1 種類: ポッド メタデータ: 名前: Webサーバー 仕様: コンテナー: - 名前: 入力サーバー イメージ: Sidecar-examples:input-http-server - 名前: 入力サイドカー イメージ: Sidecar-examples:sidecar-input
kubectl ログ input input-http-serverを見ると、input-http-server がリクエストを受信したことがわかります。
リクエストを受けてください! リクエストを受けてください!
リクエストのサイドカーをインターセプトする
アプリケーション コード。15秒ごとにlocalhost
リクエストを行います。
パッケージ com.shoothzj.sidecar import akka.actor.typed.ActorSystem import akka.actor.typed.scaladsl.Behaviors import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import scala.concurrent.{ExecutionContextExecutor, Future} import scala.util.{Failure, Success} object HttpClient { def main(args: Array[String]): Unit = { while (true) { Thread.sleep(15_000L) implicit val system: ActorSystem[Nothing] = ActorSystem (Behaviors.empty, "SingleRequest") // 最終的には将来の flatMap/onComplete に必要です implicit val executionContext: ExecutionContextExecutor = system.executionContext val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http : //localhost:7979/hello")) responseFuture .onComplete { case Success(res) => println(res) case Failure(_) => sys.error("何か間違っている") } } } }
http リクエストをインターセプトしてログを出力する別のサイドカーを作成しましょう
パッケージ com.shoothzj.sidecar import akka.actor.typed.ActorSystem import akka.actor.typed.scaladsl.Behaviors import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import akka.http.scaladsl.server .Directives._ import scala.concurrent.ExecutionContextExecutor import scala.io.StdIn object HttpServer { def main(args: Array[String]): Unit = { implicit val system: ActorSystem[Nothing] = ActorSystem(Behaviors.empty, "my -system") // 最終的には将来の flatMap/onComplete に必要になります implicit val executionContext: ExecutionContextExecutor = system.executionContext val Route = path("hello") { get { println("receive a request") complete(HttpEntity(ContentTypes) .`text/html(UTF-8)`, "<h1>akka-http に挨拶</h1>")) } } val bindingFuture = Http().newServerAt("localhost", 7979).bind(route ) while (true) { Thread.sleep(15_000L) } } }
ウェアハウスの下のスクリプトを通じてイメージを構築しoutput/build.sh
、次のように yaml を実行します。
apiVersion: v1 種類: ポッド メタデータ: 名前: 出力 仕様: ボリューム: - 名前: 共有ログの emptyDir: {} コンテナー: - 名前: 出力ワークロード イメージ: サイドカー-例: 出力ワークロード イメージプルポリシー: なし - 名前: サイドカー-出力 画像: サイドカー-例: サイドカー-出力 画像プルポリシー: なし
kubectl ログの出力 Output-workloadを見ると、output-sidecar がリクエストを受信したことがわかります。
HttpResponse(200 OK,List(サーバー: akka-http/10.2.9、日付: 火曜日、2022 年 3 月 29 日 00:15:47 GMT)、HttpEntity.Strict(text/html; charset=UTF-8、合計 31 バイト) ,HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(サーバー: akka-http/10.2.9、日付: 火曜日、2022 年 3 月 29 日 00:16:02 GMT),HttpEntity.Strict(text/html; charset= UTF-8、合計 31 バイト)、HttpProtocol(HTTP/1.1)) HttpResponse(200 OK、List(サーバー: akka-http/10.2.9、日付: 火曜日、2022 年 3 月 29 日 00:16:17 GMT)、HttpEntity。 Strict(text/html; charset=UTF-8, 合計 31 バイト),HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(サーバー: akka-http/10.2.9、日付: 火曜日、2022 年 3 月 29 日 00: 16:32 GMT),HttpEntity.Strict(text/html; charset=UTF-8, 合計 31 バイト),HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(サーバー: akka-http/10.2.9, Date) : 火曜日、2022 年 3 月 29 日 00:16:47 GMT),HttpEntity.Strict(text/html; charset=UTF-8, 合計 31 バイト),HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(サーバー: akka) -http/10.2.9、日付: 2022 年 3 月 29 日火曜日 00:17:02 GMT),HttpEntity.Strict(text/html; charset=UTF-8, 合計 31 バイト),HttpProtocol(HTTP/1.1)) HttpResponse( 200 OK,List(サーバー: akka-http/10.2.9、日付: 火曜日、2022 年 3 月 29 日 00:17:17 GMT)、HttpEntity.Strict(text/html; charset=UTF-8,合計31バイト),HttpProtocol(HTTP/1.1)) HttpResponse(200 OK,List(サーバー: akka-http/10.2.9, 日付: 火曜日, 29 3月 2022 00:17:32 GMT), HttpEntity.Strict(テキスト/html; charset=
クリックしてフォローし、できるだけ早くHuawei Cloudの新しいテクノロジーについて学びましょう~
Broadcom は、既存の VMware パートナー プログラム Deepin-IDE バージョン アップデートの終了を発表し 、新しい外観に なりました。WAVE SUMMIT は第 10 回を迎えます。Wen Xinyiyan が最新の情報を公開します。 周宏儀: 紅夢ネイティブは間違いなく成功するだろう GTA 5 の完全なソースコードが公開された ライナス: クリスマスイブにはコードを読まないつもりだ Java ツールセットの新バージョン Hutool-5.8.24をリリースする来年。一緒 にフリオンについて文句を言いましょう。商業探査: ボートは通過しました。万中山、v4.9.1.15 Apple、オープンソースのマルチモーダル大規模言語モデルをリリース フェレット ヤクルト会社、95G データが漏洩したことを確認