7.3 KiB
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 1–5 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
-
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
-
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