DEV Community

Cheedge Lee
Cheedge Lee

Posted on • Originally published at notes-renovation.hashnode.dev

Sidecar container simplified examples

A sidecar container is commonly used in real-world applications to augment the functionality of the primary container. And here we will see some simplified examples of typical sidecar container use cases, along with their scripts or configurations.

1. Logging and Monitoring

Scenario: A sidecar container collects logs from the primary application and sends them to a logging service.

apiVersion: v1 kind: Pod metadata: name: logging-sidecar spec: containers: - name: app-container image: nginx volumeMounts: - name: shared-logs mountPath: /var/log/nginx - name: log-collector image: busybox command: ["sh", "-c", "tail -f /var/log/nginx/access.log"] volumeMounts: - name: shared-logs mountPath: /var/log/nginx volumes: - name: shared-logs emptyDir: {} 
Enter fullscreen mode Exit fullscreen mode
  • The nginx app writes logs to /var/log/nginx.
    • default logs: access.log record the access messages; error.log record error messages.
  • The log-collector sidecar tails the log file and can send it to an external logging service.
# when we access the ngnix controlplane $ curl 192.168.1.4 # it will record the access msg controlplane $ k exec -it pods/logging-sidecar -c log-collector -- cat /var/log/nginx/access.log 192.168.1.4 - - [07/Dec/2024:21:34:51 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.88.1" "-" 192.168.0.0 - - [07/Dec/2024:21:35:13 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.68.0" "-" 
Enter fullscreen mode Exit fullscreen mode

2. Security Proxy

Scenario: A sidecar acts as a proxy to add authentication or encryption to requests before they reach the primary container.

  • main-app container serves traffic.
  • Sidecar container intercepts and routes traffic.
apiVersion: v1 kind: Pod metadata: name: proxy-sidecar spec: containers: - name: main-app image: httpd ports: - containerPort: 80 - name: envoy-proxy image: envoyproxy/envoy:v1.27.0 args: ["-c", "/etc/envoy/envoy.yaml"] ports: - containerPort: 10000 
Enter fullscreen mode Exit fullscreen mode

Then configure envoy.yaml to route traffic. Access the service through the proxy and verify logs in Envoy. The configure file envoy.yaml can be found here.

And the envoy-proxy container not install vim or nano editor, so you can use

kubectl cp <local-file-path> <pod-name>:<pod-destination-path> -c <container-name> kubectl cp <pod-name>:<source-path> <destination-path> -c <container-name> # eg. kubectl cp proxy-sidecar:/etc/envoy/envoy.yaml ./envoy.yaml -c envoy-proxy 
Enter fullscreen mode Exit fullscreen mode

to copy it outside pod to edit it.

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES proxy-sidecar 2/2 Running 0 13m 192.168.1.4 node01 <none> <none> controlplane $ curl http://192.168.1.4:10000 
Enter fullscreen mode Exit fullscreen mode

The auth-proxy sidecar intercepts requests to the main-app, applies authentication, and forwards them.

3. File Synchronization

Scenario: A sidecar container keeps files synchronized between the application and an external storage system:

  • main-app container save file under /data
  • syncer sidecar container synchronize it at /backup
apiVersion: v1 kind: Pod metadata: name: data-sync-sidecar spec: containers: - name: main-app image: busybox command: ["/bin/sh", "-c"] args: ["echo 'hallo syncer!' > /data/file.txt; sleep 3600"] volumeMounts: - name: data-volume mountPath: /data - name: syncer image: alpine command: ["/bin/sh", "-c"] args: ["apk add --no-cache rsync; while true; do rsync -av /data/ /backup/; sleep 10; done"] volumeMounts: - name: data-volume mountPath: /data - name: backup-volume mountPath: /backup volumes: - name: data-volume emptyDir: {} - name: backup-volume emptyDir: {} 
Enter fullscreen mode Exit fullscreen mode

The sync-agent periodically synchronizes files between /data and /backup.

4. Initialization with InitContainer

Scenario: A initContainers init-db container, which used to init the db provided for main application to use. (The whole yaml file can be checked at this GitHub Repo).

Here we use a busybox as the main app container, but it just a placeholder. We can run the actual application that relies on the initialization performed by the initContainer. For example, the main container is some web application.
You can check this Repo which is the full yaml file for a flask app to use the initContainers container.

apiVersion: v1 kind: Pod metadata: name: db-init-pod spec: initContainers: - name: init-db image: postgres:latest command: ["sh", "-c"] args: - | until pg_isready -h postgres -U user; do echo "Waiting for PostgreSQL to be ready..."; sleep 2; done; psql -h postgres -U user -d mydb -c "CREATE TABLE IF NOT EXISTS test (id SERIAL PRIMARY KEY, name TEXT);" env: - name: PGPASSWORD value: "password" # Match the PostgreSQL password containers: - name: app image: busybox command: ["/bin/sh", "-c"] args: ["echo 'App starting'; sleep 3600"] 
Enter fullscreen mode Exit fullscreen mode

And then we can verify Database Initialization by logging into the PostgreSQL container and check for the test table. or inspect the init-db logs for progress or errors.

NAME READY STATUS RESTARTS AGE db-init-pod 1/1 Running 0 33s postgres-7c8f74d97b-cxdmp 1/1 Running 0 32s # check the log controlplane $ k logs db-init-pod -c init-db # logging into postgres container verify the db controlplane $ k exec -it postgres-7c8f74d97b-cxdmp -- psql -U user -d mydb -c "\dt" List of relations Schema | Name | Type | Owner --------+------+-------+------- public | test | table | user (1 row) 
Enter fullscreen mode Exit fullscreen mode

or if you change the busybox image to what your app used eg. flask

controlplane $ kubectl logs db-init-pod -c init-db postgres:5432 - no response Waiting for PostgreSQL to be ready... postgres:5432 - accepting connections CREATE TABLE controlplane $ kubectl logs db-init-pod -c app 
Enter fullscreen mode Exit fullscreen mode

And then we can add a svc to access the Flask application.


Benefits of Sidecars:

The sidecars container has many other usages, such as debugging, caching. And it's better to use a sidecar container, as:

  • Modularity: Sidecars add functionality without altering the primary app.
  • Scalability: The same sidecar logic can be reused across different apps.
  • Separation of Concerns: Keeps application code clean and focused.

Therefore it is a powerful tool for extending functionality while maintaining a clean architecture.

Reference

In official document, we can see more details about the sidecar container.
Also we can check here for the init containers.

Top comments (0)