Skip to content

Kubernetes Deployment Guide for aeronet

This guide provides end-to-end Kubernetes examples for deploying an aeronet server with:

  • a ConfigMap-managed server configuration
  • built-in probe endpoints (/livez, /readyz, /startupz)
  • liveness, readiness, and startup probes in Deployment
  • an optional Service

You will find two configuration styles:

  1. ConfigMap with YAML config and comments
  2. ConfigMap with JSON config without comments

These examples are templates. Replace image names, command/args, ports, and resource values for your workload.

Prerequisites

  1. A container image that runs your aeronet server.
  2. Your server process reads config from a file path (examples use /etc/aeronet/server.yaml or /etc/aeronet/server.json).
  3. Built-in probes enabled in the config.

For probe behavior and options, see FEATURES.md.

Generate a Baseline Config File

The examples directory includes a small CLI tool that dumps aeronet's default full configuration (server + router) in JSON or YAML. This is useful as a starting point for clients before turning the content into a Kubernetes ConfigMap.

Build and run:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DAERONET_ENABLE_GLAZE=ON
cmake --build build --target aeronet-config-dump

# Print YAML to stdout
./build/examples/aeronet-config-dump --format yaml

# Write JSON to a file
./build/examples/aeronet-config-dump --format json --output server.json

Then place the generated file content in the ConfigMap (server.yaml or server.json) and tune values for your environment (ports, limits, TLS, telemetry, probes, and routing defaults).

Option A: ConfigMap with YAML Config and Comments

The manifest below contains:

  • one ConfigMap with a commented YAML server config
  • one Deployment mounting that config file
  • one Service
apiVersion: v1
kind: ConfigMap
metadata:
  name: aeronet-config-yaml
data:
  # This file is mounted into the container and read by your server process.
  server.yaml: |
    server:
      # Listen port used by the pod.
      port: 8080

      # Enable built-in Kubernetes-style probes.
      builtinProbes:
        enabled: true
        livenessPath: /livez
        readinessPath: /readyz
        startupPath: /startupz
        contentType: text/plain

      # Optional HTTP behavior tuning.
      enableKeepAlive: true
      keepAliveTimeout: 5000ms

      # Optional telemetry example.
      telemetry:
        otelEnabled: false
        dogStatsDEnabled: false

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aeronet-example-yaml
  labels:
    app: aeronet-example-yaml
spec:
  replicas: 2
  selector:
    matchLabels:
      app: aeronet-example-yaml
  template:
    metadata:
      labels:
        app: aeronet-example-yaml
    spec:
      containers:
        - name: aeronet
          image: your-registry/aeronet:latest
          imagePullPolicy: IfNotPresent

          # Adjust command/args to your image entrypoint contract.
          args: ["--config", "/etc/aeronet/server.yaml"]

          ports:
            - name: http
              containerPort: 8080

          volumeMounts:
            - name: aeronet-config
              mountPath: /etc/aeronet
              readOnly: true

          # Liveness checks process health.
          livenessProbe:
            httpGet:
              path: /livez
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 2
            failureThreshold: 3

          # Readiness controls whether pod receives traffic.
          readinessProbe:
            httpGet:
              path: /readyz
              port: http
            initialDelaySeconds: 5
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 3

          # Startup probe protects slow initialization paths.
          startupProbe:
            httpGet:
              path: /startupz
              port: http
            initialDelaySeconds: 2
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 30

          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "256Mi"

      volumes:
        - name: aeronet-config
          configMap:
            name: aeronet-config-yaml

---
apiVersion: v1
kind: Service
metadata:
  name: aeronet-example-yaml
spec:
  selector:
    app: aeronet-example-yaml
  ports:
    - name: http
      port: 80
      targetPort: http
  type: ClusterIP

Apply it with:

kubectl apply -f aeronet-yaml-example.yaml

Option B: ConfigMap with JSON Config Without Comments

JSON does not support comments. The example below intentionally keeps the JSON payload comment-free.

apiVersion: v1
kind: ConfigMap
metadata:
  name: aeronet-config-json
data:
  server.json: |
    {
      "server": {
        "port": 8080,
        "enableKeepAlive": true,
        "keepAliveTimeout": "5000ms",
        "builtinProbes": {
          "enabled": true,
          "livenessPath": "/livez",
          "readinessPath": "/readyz",
          "startupPath": "/startupz",
          "contentType": "text/plain"
        },
        "telemetry": {
          "otelEnabled": false,
          "dogStatsDEnabled": false
        }
      }
    }

Pair it with this Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aeronet-example-json
  labels:
    app: aeronet-example-json
spec:
  replicas: 2
  selector:
    matchLabels:
      app: aeronet-example-json
  template:
    metadata:
      labels:
        app: aeronet-example-json
    spec:
      containers:
        - name: aeronet
          image: your-registry/aeronet:latest
          imagePullPolicy: IfNotPresent
          args: ["--config", "/etc/aeronet/server.json"]
          ports:
            - name: http
              containerPort: 8080
          volumeMounts:
            - name: aeronet-config
              mountPath: /etc/aeronet
              readOnly: true
          livenessProbe:
            httpGet:
              path: /livez
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 2
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /readyz
              port: http
            initialDelaySeconds: 5
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 3
          startupProbe:
            httpGet:
              path: /startupz
              port: http
            initialDelaySeconds: 2
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 30
      volumes:
        - name: aeronet-config
          configMap:
            name: aeronet-config-json

Apply it with:

kubectl apply -f aeronet-json-configmap.yaml
kubectl apply -f aeronet-json-deployment.yaml

Isolating Probes on a Dedicated Port

When a MultiHttpServer worker is busy for a long time inside a request handler (a heavy computation, a slow blocking dependency call, ...), an inline probe answered by that same worker can time out — and Kubernetes may restart a pod that is merely busy. To avoid this, serve the probes from a dedicated listener on their own port/thread that never runs application handlers, and point the Kubernetes probes at that port.

Enable it with builtinProbes.dedicatedPort (server config), then expose the extra port and target it in the probes:

server:
  port: 8080
  # nbThreads: 0  # 0 => one worker per CPU
  builtinProbes:
    enabled: true
    dedicatedPort: 9091          # probes served here, isolated from application load on :8080
    livenessStaleThreshold: 15s  # report unhealthy only if ALL workers are wedged in a handler this long
    livenessPath: /livez
    readinessPath: /readyz
    startupPath: /startupz
# ... in the container spec:
ports:
  - name: http
    containerPort: 8080
  - name: probes
    containerPort: 9091
livenessProbe:
  httpGet:
    path: /livez
    port: probes          # target the dedicated probe port, not http
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /readyz
    port: probes
  periodSeconds: 5
startupProbe:
  httpGet:
    path: /startupz
    port: probes
  periodSeconds: 5
  failureThreshold: 30

dedicatedPort: 0 (the default, or omitting it) keeps the probes inline on the application port, matching the earlier examples. See FEATURES.md for the readiness/startup/liveness semantics of the dedicated listener.

Probe Tuning Guidance

  1. Keep liveness checks strict enough to catch hangs, but avoid false positives under transient load.
  2. Keep readiness checks representative of traffic readiness, not just process up/down.
  3. Use startup probe for slow warmup paths so liveness does not restart pods too early.
  4. Prefer named ports (port: http) in probes to avoid drift when container ports change.
  5. For latency-sensitive services, serve probes on a dedicated port (see above) so application load cannot starve them.

Common Validation Commands

kubectl get pods
kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl get endpoints aeronet-example-yaml