2026-03-25 11:46:39 +01:00

7.3 KiB
Raw Blame History

Finding Flags

docker run --rm ghcr.io/wundergraph/cosmo/router:latest --help

docker run --rm docker.redpanda.com/redpandadata/redpanda:v23.2.15 redpanda start --help

docker run --rm ghcr.io/timeplus-io/proton:latest proton server --help

Pinot uses subcommands: docker run --rm apachepinot/pinot:latest StartController -help

docker run --rm quay.io/minio/minio:latest server --help

Comparison

Feature Docker Compose (docker-compose.yaml) K3s Manifest (deployment.yaml)
Image image: nginx:latest image: nginx:latest
Env Var environment: - DB_HOST=localhost "env: - name: DB_HOST value: ""localhost"""
Ports "ports: - ""80:80""" ports: - containerPort: 80 (plus a Service object)
Volumes volumes: - ./data:/app/data volumeMounts: - mountPath: /app/data name: my-vol
  • Kompose will generate the .yaml files (Deployments, Services, etc.) that K3s understands. It's not always perfect, but it handles about 90% of the heavy lifting. kompose convert -f docker-compose.yaml
Category Command Line Flag Docker Compose Key K8s Equivalence
Environment "-e, --env environment: env: or envFrom:
Volumes "-v, --volume" volumes: volumeMounts: & volumes:
Commands (End of string) command: args: (usually)
Entrypoint --entrypoint entrypoint: command
Networking -p, --publish" ports: Service or containerPort

General Pattern for Finding Flags (The "Deep Dive")

If --help doesn't work or the container exits too fast, use these three "Detective" steps:

Inspect the Entrypoint: docker inspect <image_name> --format='{{.Config.Entrypoint}} {{.Config.Cmd}}' This tells you exactly what script or binary is running so you know what to call with --help.

Environment Variable Overrides: Many modern images (Bitnami, Confluent) use env vars instead of flags. Check the env section of their DockerHub page.

The "Dry Run" strategy: Run the container with an interactive shell: docker run -it --entrypoint /bin/sh <image_name> Once inside, manually run the binary with -h

  • Most modern cloud-native images follow the POSIX/GNU convention. You can generally find flags using: --help or -h

  • help (as a subcommand, common in Go/Rust tools)

  • Looking at the ENTRYPOINT in the Dockerfile.

Common Patterns by Tech Stack:
Java (Flink, Pinot): Usually uses a custom shell script entrypoint. Flags are often passed as -Dproperty=value or via a conf.yaml.

Go (Benthos, Cosmo, NATS): Very consistent. container-name --help almost always works.

C++/Rust (Yugabyte, RisingWave): Usually binary-driven. binary-name --help works, but you must know the path to the binary (e.g., /home/yugabyte/bin/yb-tserver).

Finding & Placing Flags in Helm/K8s

In Kubernetes, you don't "find" K8s-specific flags inside the image. The image only cares about its own flags. You just have to decide how to pass them from the YAML.

Where do they go? In a Helm chart template (usually templates/deployment.yaml), flags go into the args or command section of the container spec.

Example: Converting your Yugabyte T-Server flag Your Compose: --tserver_master_addrs=yb-master:7100

In Helm values.yaml: tserver: masterAddresses: "yb-master-service.db.svc.cluster.local:7100"

In Helm templates/statefulset.yaml: containers:

  • name: yb-tserver image: yugabytedb/yugabyte:latest command: ["/home/yugabyte/bin/yb-tserver"] args:
    • "--tserver_master_addrs={{ .Values.tserver.masterAddresses }}"
    • "--rpc_bind_addresses=$(POD_IP):9100" # Use K8s env vars

App Centric Structure

Where to run helm create? You should run this inside your project root, usually in a directory named /charts or /deploy.

my-project/
├── docker-compose.yml
├── python/
├── benthos-configs/
└── deploy/               <-- Run "helm create" here
    ├── cosmo-router/     <-- Resulting folder
    ├── yugabyte/
    └── airflow/

This structure treats Kubernetes manifests as "just another part of the code."

Logic: Everything needed to run the cosmo-router application (code, Dockerfile, and Helm chart) stays in one place.

Best for: Small teams where the same person writes the code and manages the deployment.

Cluster Centric

Namespace Services (Folder) Why?
db "yugabytedb, redis-nats, elasticsearch-nats, minio, garage, postgres-airflow, proton Persistence layers and heavy stateful workloads.
infra "nats, redpanda, redpanda_console, prometheus, grafana-0, zookeeper, pinot-* Message brokers, streaming
apps "cosmo-router, subgraph-python, postgraphile, hasura, grafbase, benthos, superset, streampark, flink-*,risingwave-standalone, owl-shop, debezium-pinot Business logic, Gateways, and ETL/Stream processing jobs.
/k8s-infra
├── namespaces/
│   ├── infra-ns.yaml
│   └── db-ns.yaml
├── infra/ (Benthos, NATS, etc.)
│   └── kustomization.yaml
├── db/ (YugabyteDB)
│   └── kustomization.yaml
└── apps/


This structure treats the Kubernetes Cluster as a single entity, and your repository describes the state of that cluster.

Logic: You organize by operational domains (Database, Networking, Application layers).

Best for: Production environments, GitOps (using tools like ArgoCD), and scenarios where you have many moving parts (like your 15+ services).
Feature App-Centric (/deploy) Cluster-Centric (/k8s-infra)
Separation of Concerns Low. Infra and App code are mixed. High. Clear boundaries between DBs, Infra, and Apps.
Blast Radius High. A change in the app repo might trigger an infra redeploy. Low. You can update the apps/ without touching the db/ logic.
Dependency Management Difficult. Hard to see if apps is ready for the db. Better. kustomization.yaml can order the execution
RBAC (Permissions) Hard to restrict. Everyone has access to everything. Easy. You can give a dev access to apps-ns but lock the db-ns.
Scaling Complexity Good for 15 services. "Essential for your 15+ services (Redpanda, Yugabyte, etc.).

Generalizing K8s to Docker Compose

Think of a Pod in K8s as the closest relative to a Service in Docker Compose. However, K8s splits responsibilities across multiple objects:

Deployment/StatefulSet: This is your docker-compose.yaml logic—how many replicas you want and what image to use.

Service: This is your ports: section. While Compose handles networking internally, K8s requires an explicit Service object to route traffic to your pods.

ConfigMap/Secret: This is a more robust version of the env_file: or environment: keys in Compose.

PersistentVolumeClaim (PVC): This replaces the host-path mapping (-v /host:/container) with a request for storage that stays alive even if the pod dies.

Fully Qualified Domain Name/ FQDN

  1. kubectl get svc -n db # check your NAME TYPE CLUSTER-IP PORT(S) yb-tservers ClusterIP 10.43.0.50 5433/TCP,9042/TCP yb-masters ClusterIP 10.43.0.60 7100/TCP,7000/TCP

  2. Add your name with <namespace>.svc.cluster.local:port: Our namespace is db, so FQDN: yb-tservers.db.svc.cluster.local:5433

Apply changes

if you are using Kustomize:

kubectl apply -k . -n infra
kubectl rollout restart deployment benthos -n infra
kubectl rollout status deployment benthos -n infra # check status

if you originally installed via a Helm chart:
helm upgrade benthos <chart-path> -n infra -f values.yaml