K8s pod logs without Loki
Running DockLog in kubernetes mode, kubeconfig mount, in-cluster deploy, WebSockets through ingress.
You don't need Fluent Bit and Loki to answer "what is this pod printing right now?"
For a small cluster, staging, or a k3s box in the garage, DockLog in kubernetes mode gives you live pod logs, basic workload views, and the same RBAC/alert stuff as Docker mode. One container, no DaemonSet.
It does not replace long-term log storage. Keep your cloud provider or Loki for retention if you need it. Use this for tailing during deploys and incidents. We wrote up how DockLog compares to Loki for the split-brain setup.
Runtime mode
| Mode | What you get |
|---|---|
docker | Default, socket only |
kubernetes | Pods, deployments, events, pod logs |
both | Toggle in the UI when you have socket and kubeconfig on the same host |
DockLog starts even if the cluster is unreachable; K8s pages just show a connection warning until credentials work.
Homelab: mount kubeconfig
DockLog on the host, not in the cluster:
services:
docklog:
image: aimldev/docklog:latest
ports:
- "127.0.0.1:8888:8000"
environment:
RUNTIME_MODE: kubernetes
KUBECONFIG: /app/kube/config
K8S_NAMESPACES: default,staging,production
SECRET_KEY: ${SECRET_KEY}
DB_PATH: /app/data/docklog.db
TRUST_PROXY: "true"
ALLOWED_ORIGINS: https://docklog.example.com
volumes:
- ~/.kube/config:/app/kube/config:ro
- ./data:/app/data
restart: unless-stoppedK8S_NAMESPACES limits what the instance queries. Leave it out only if you mean cluster-wide and your creds allow it.
Context matters: if your kubeconfig has three contexts, DockLog uses the current context. kubectl config use-context before docker compose up or set KUBECONFIG to a single-context file.
In-cluster (more production-shaped)
Namespace + ServiceAccount, bind a ClusterRole with at least get/list/watch on pods, pods/log, namespaces, events. Deploy the image with serviceAccountName: docklog, mount a PVC for /app/data, expose via Service and Ingress.
Add write verbs on pods only if you enable restart/delete in DockLog and accept that risk.
ServiceAccount and ClusterRole
apiVersion: v1
kind: ServiceAccount
metadata:
name: docklog
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: docklog-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "namespaces", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: docklog-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: docklog-reader
subjects:
- kind: ServiceAccount
name: docklog
namespace: monitoringFor restart buttons, add delete on pods (restart is implemented via delete/recreate). Only if ALLOW_RESTART is on and you accept blast radius.
Deployment skeleton
apiVersion: apps/v1
kind: Deployment
metadata:
name: docklog
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: docklog
template:
metadata:
labels:
app: docklog
spec:
serviceAccountName: docklog
containers:
- name: docklog
image: aimldev/docklog:latest
ports:
- containerPort: 8000
env:
- name: RUNTIME_MODE
value: kubernetes
- name: K8S_NAMESPACES
value: default,staging,production
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: docklog-secrets
key: secret-key
- name: DB_PATH
value: /app/data/docklog.db
- name: TRUST_PROXY
value: "true"
- name: ALLOWED_ORIGINS
value: https://docklog.example.com
volumeMounts:
- name: data
mountPath: /app/data
volumes:
- name: data
persistentVolumeClaim:
claimName: docklog-dataExpose via ClusterIP Service plus Ingress with proxy-read-timeout: "86400" on nginx ingress. TRUST_PROXY and ALLOWED_ORIGINS when TLS terminates at ingress. Full ingress examples: reverse proxy post.
Ingress and WebSockets
Same mistake every time: logs connect, scroll for 30 seconds, stop. Ingress didn't forward upgrades.
nginx ingress needs long timeouts (see annotations above). Plain nginx:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;Test: open pod logs, wait two minutes without scrolling. If the stream dies at 60s, it's the proxy.
Who sees which namespaces
Cluster RBAC = what the DockLog pod can reach. Per-user allowed_containers = what each login sees.
| Pattern | Who sees it |
|---|---|
staging | All pods in namespace staging |
production/api-* | Pods named api-* in production |
*-worker-* | Pod name match across allowed namespaces |
Combine with K8S_NAMESPACES so kube-system never appears even if someone fat-fingers a pattern.
Details: RBAC post.
Alerts on K8s events
Crash loop backoff and image pull failures show up as K8s event rules. Scope to production/* unless you like staging noise.
| Event | Usually means |
|---|---|
| CrashLoopBackOff | App exiting on start, check logs |
| ImagePullBackOff | Wrong tag, registry auth, rate limit |
| FailedScheduling | Resources, taints, PVC pending |
Channel setup: Slack/Teams post.
Hybrid host
RUNTIME_MODE=both, mount socket and kubeconfig. Logs page gets a Docker/K8s toggle. Common when compose runs your apps and k3s runs everything else.
environment:
RUNTIME_MODE: both
KUBECONFIG: /app/kube/config
K8S_NAMESPACES: default,staging,production
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/.kube/config:/app/kube/config:ro
- ./data:/app/dataSame user can have alice-* for Docker and staging/* for K8s in one allowed_containers field.
When it's broken
| Symptom | Check |
|---|---|
| Empty pod list | ServiceAccount verbs, K8S_NAMESPACES |
| Logs drop after 60s | Ingress/proxy timeout |
| Wrong namespaces for a user | Their allowed_containers, not cluster RBAC |
| Works on laptop, not in cluster | In-cluster token vs mounted config confusion |
| Connection warning on startup | Cluster down or wrong context |
| Admin sees pods, user doesn't | User pattern typo; use namespace/pod syntax |
Works on laptop, not in cluster: mounted kubeconfig uses your user creds; in-cluster uses ServiceAccount token. Different RBAC bindings.
Verify ServiceAccount access with kubectl auth can-i list pods --as=system:serviceaccount:monitoring:docklog -A before blaming DockLog.
Official K8s guide for screenshots. Compose baseline if you're on the same machine as Docker. Compare with terminal tools: DockLog vs k9s. Wider tool landscape: K8s monitoring guide.