### 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 --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 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 |backplanes, and observability tools.| |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 |of resources.| |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 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 `.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 -n infra -f values.yaml ```