Mastering the Sidecar Pattern: Log Collection, Request Forwarding, and Interception in Kubernetes
This article explains the sidecar concept, compares it with SDK approaches, and provides detailed Kubernetes examples—including a log‑collection sidecar, a request‑forwarding sidecar, and an HTTP‑intercepting sidecar—complete with YAML manifests and Rust and Scala code to demonstrate implementation and deployment.
Sidecar, literally “sidecar”, is a pattern where an auxiliary container is attached to an application container to separate control logic from business logic. In microservices, sidecars can handle functions such as log collection, service registration, discovery, rate limiting, and authentication, avoiding code bloat in the main service.
The sidecar approach introduces some performance overhead and latency, while SDK‑based implementations can make the codebase bulky and harder to upgrade; sidecars allow independent evolution of control and business capabilities.
Sidecar Implementation Principles
In Kubernetes a pod is the smallest deployable unit and can host multiple containers that share storage volumes and the network stack. This enables the sidecar pattern by running additional containers or init‑containers that access shared volumes.
Log Collection Sidecar
The log‑collection sidecar leverages a shared volume to read application logs. The following YAML defines a pod with an nginx container and a sidecar container that continuously reads the nginx PID file.
apiVersion: v1
kind: Pod
metadata:
name: webserver
spec:
volumes:
- name: shared-logs
emptyDir: {}
containers:
- name: nginx
image: ttbb/nginx:mate
volumeMounts:
- name: shared-logs
mountPath: /opt/sh/openresty/nginx/logs
- name: sidecar-container
image: ttbb/base
command: ["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/logsAfter creating the pod with kubectl create -f, the sidecar’s log output can be viewed using kubectl logs webserver sidecar-container.
Request Forwarding Sidecar
A simple Rust HTTP server is provided, and a sidecar written in Rust periodically sends requests to it. The server code:
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
handle_connection(stream);
}
println!("Hello, world!");
}
fn handle_connection(mut stream: TcpStream) {
let mut buffer = [0; 1024];
stream.read(&mut buffer).unwrap();
let contents = "Hello";
let response = format!(
"HTTP/1.1 200 OK
Content-Length: {}
{}",
contents.len(),
contents
);
println!("receive a request!");
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}The forwarding sidecar runs every 15 seconds and issues an HTTP GET request:
use std::thread;
use std::time::Duration;
fn main() {
loop {
thread::sleep(Duration::from_secs(15));
let response = reqwest::blocking::get("http://localhost:7878").unwrap();
println!("{}", response.text().unwrap())
}
}Both containers are built with the intput/build.sh script and deployed via the following pod manifest:
apiVersion: v1
kind: Pod
metadata:
name: webserver
spec:
containers:
- name: input-server
image: sidecar-examples:input-http-server
- name: input-sidecar
image: sidecar-examples:sidecar-inputLogs from the input server show the received requests.
Request Interception Sidecar
A Scala Akka‑HTTP server is presented, and a sidecar intercepts HTTP requests and logs them. The server code:
package 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")
implicit val executionContext: ExecutionContextExecutor = system.executionContext
val route =
path("hello") {
get {
println("receive a request")
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
}
}
val bindingFuture = Http().newServerAt("localhost", 7979).bind(route)
while (true) {
Thread.sleep(15000L)
}
}
}The sidecar is built with output/build.sh and deployed together with the workload container:
apiVersion: v1
kind: Pod
metadata:
name: output
spec:
volumes:
- name: shared-logs
emptyDir: {}
containers:
- name: output-workload
image: sidecar-examples:output-workload
imagePullPolicy: Never
- name: sidecar-output
image: sidecar-examples:sidecar-output
imagePullPolicy: NeverObserving kubectl logs output output-workload displays the HTTP responses from the sidecar.
All example code is available in the original repository.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
