Skip to content

Commit dc6cb72

Browse files
johnmathewsclaude
andcommitted
Update docs for blob storage, Prometheus metrics, and new K8s concepts
- Dictionary: add ServiceMonitor, kubectl rollout restart, pod READY column, kubectl get all limitations, default namespace, Azurite, ACR image building - Architecture: update store worker details, gateway /metrics endpoint, mark Helm charts as installed - Demo guide: mention blob uploads and Prometheus metrics in talking points Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5f3226f commit dc6cb72

3 files changed

Lines changed: 93 additions & 7 deletions

File tree

docs/architecture.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ storing → completed).
135135
| Aspect | Detail |
136136
|---|---|
137137
| Framework | FastAPI |
138-
| Endpoints | `/health`, `/api/documents`, `/api/generate`, `/` (web UI) |
138+
| Endpoints | `/health`, `/api/documents`, `/api/generate`, `/metrics`, `/` (web UI) |
139139
| K8s role | Single Deployment with a Service and Ingress |
140140
| Scaling | HPA based on CPU (not queue-based — it handles HTTP, not queue work) |
141141

@@ -165,9 +165,10 @@ storing → completed).
165165
| Aspect | Detail |
166166
|---|---|
167167
| Database | PostgreSQL with pgvector extension |
168-
| Blob store | Azure Blob Storage (optional, via `BLOB_CONNECTION_STRING`) |
168+
| Blob store | Azure Blob Storage (via `BLOB_CONNECTION_STRING` in K8s Secret) |
169+
| Metrics | Prometheus counters: `documentstream_blob_uploads_total`, `documentstream_blob_bytes_total` (by doc_type) |
169170
| Input | Redis stream `classified` |
170-
| Stored data | Document metadata, classification results, vector embedding (384 dims), blob URL |
171+
| Stored data | Document metadata, doc_type, classification results, vector embedding (384 dims), blob URL |
171172
| Scaling | KEDA ScaledObject watching `classified` stream depth |
172173

173174
### Queue Module (`src/worker/queue.py`)
@@ -211,7 +212,7 @@ When stopped (`az aks stop` + `az postgres flexible-server stop`): ~€0.01/hr (
211212
| chaos-mesh/chaos-mesh | chaos-mesh | Chaos engineering |
212213
| ingress-nginx | ingress-nginx | HTTP routing |
213214

214-
*Not yet installed — these are deployed when the AKS cluster is provisioned.*
215+
All charts are installed and running on the live AKS cluster.
215216

216217
### CI/CD
217218

docs/demo-guide.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ Before the interview:
3636
**Show:** Click "Generate" with 5 scenarios
3737

3838
> "Each loan scenario generates 5 linked documents. They share the same loan ID, client,
39-
> and property — just like a real bank's document management system."
39+
> and property — just like a real bank's document management system. Each PDF is uploaded
40+
> to Azure Blob Storage automatically — you can see the count and total size per document
41+
> type on the Grafana dashboard."
4042
4143
**Point out the two classifier columns:**
4244
> "Every document goes through two classifiers. The rule-based classifier handles privacy
@@ -148,7 +150,9 @@ Before the interview:
148150
> "The full pipeline: FastAPI gateway receives uploads, puts them on a Redis stream.
149151
> Extract workers pull text with PyMuPDF. Classify workers run both rule-based and
150152
> semantic classification. Store workers save metadata and embeddings to PostgreSQL
151-
> with pgvector, and original PDFs to Azure Blob Storage."
153+
> with pgvector, and original PDFs to Azure Blob Storage. The gateway exposes Prometheus
154+
> metrics — blob upload counts and sizes by document type — which Prometheus scrapes
155+
> via a ServiceMonitor and Grafana displays in real time."
152156
153157
**Show:** Cost breakdown
154158

docs/dictionary.md

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,34 @@ file, but managed by K8s and versioned.
3838

3939
### Secret
4040
Same as ConfigMap but for sensitive data (passwords, API keys). Base64-encoded at rest.
41-
Like Docker secrets.
41+
Like Docker secrets. Referenced via `secretRef` in a Deployment's `envFrom` — if listed
42+
after a ConfigMap, Secret values override ConfigMap values with the same key.
43+
44+
**Important:** Never commit Secrets to git. Create them via `kubectl create secret` or
45+
apply a gitignored YAML file. GitHub Push Protection will block pushes containing keys.
46+
47+
### ServiceMonitor
48+
A Custom Resource (CRD) used by the **kube-prometheus-stack** to tell Prometheus which
49+
services to scrape. Pod annotations like `prometheus.io/scrape: "true"` do **not** work
50+
with kube-prometheus-stack — you must create a ServiceMonitor instead.
51+
52+
Key gotcha: the ServiceMonitor needs a `release: prometheus` label (or whatever label
53+
selector your Prometheus instance uses). Without it, Prometheus silently ignores it.
54+
55+
```yaml
56+
apiVersion: monitoring.coreos.com/v1
57+
kind: ServiceMonitor
58+
metadata:
59+
labels:
60+
release: prometheus # required!
61+
spec:
62+
selector:
63+
matchLabels:
64+
app: gateway
65+
endpoints:
66+
- port: http # must match a named port on the Service
67+
path: /metrics
68+
```
4269
4370
---
4471
@@ -57,6 +84,17 @@ How K8s deploys a new version: start new pods, wait until they're ready, then ki
5784
At no point are zero pods running. This gives you **zero-downtime deployments**. If the new
5885
pods fail their readiness probes, K8s stops the rollout automatically.
5986

87+
### `kubectl rollout restart`
88+
Triggers a rolling restart of all pods in a deployment without changing any YAML. Needed
89+
when a ConfigMap or Secret changes — K8s does **not** automatically restart pods when their
90+
ConfigMap values change. You have to tell it to.
91+
92+
```bash
93+
kubectl rollout restart deployment/gateway deployment/store-worker
94+
kubectl rollout status deployment/gateway # watch progress
95+
kubectl rollout history deployment/gateway # see past revisions
96+
```
97+
6098
### Rollback
6199
Undo a deployment: `kubectl rollout undo deployment/my-app`. K8s keeps the previous pod
62100
spec and can revert to it instantly.
@@ -67,6 +105,28 @@ spec and can revert to it instantly.
67105
- **Limit:** "This container must never use more than 512MB RAM."
68106
If it exceeds the memory limit, K8s kills it (OOMKilled).
69107

108+
### Pod READY Column
109+
When you run `kubectl get pods`, the READY column shows `1/1` or `2/2`. This is
110+
`READY_CONTAINERS/TOTAL_CONTAINERS` in that pod. A pod with an app + sidecar container
111+
would show `2/2` when both are ready, or `1/2` if one is still starting.
112+
113+
### `kubectl get all` Limitations
114+
Despite the name, `kubectl get all` only returns a hardcoded subset: Pods, Services,
115+
Deployments, ReplicaSets, StatefulSets, DaemonSets, Jobs, CronJobs. It does **not**
116+
include HPAs, ConfigMaps, Secrets, Ingresses, PVCs, ServiceMonitors, ScaledObjects, etc.
117+
118+
To see everything in a namespace, be explicit:
119+
```bash
120+
kubectl get deploy,svc,hpa,ingress,configmap,scaledobject -n documentstream
121+
```
122+
123+
### Default Namespace
124+
Set a default namespace to avoid typing `-n documentstream` on every command:
125+
```bash
126+
kubectl config set-context --current --namespace=documentstream
127+
kubectl config view --minify | grep namespace # verify
128+
```
129+
70130
### Horizontal Pod Autoscaler (HPA)
71131
Watches a metric (CPU, memory, custom) and adjusts the number of pod replicas. Example:
72132
"If average CPU > 70%, add more pods. If < 30%, remove pods." Like auto-scaling in cloud
@@ -154,6 +214,27 @@ not in use (you only pay for disk storage while stopped).
154214

155215
### Azure Blob Storage
156216
Object storage for files (like S3). We store the original PDF files here. Extremely cheap.
217+
PDFs are organized as `{doc_id}/{loan_id}/{doc_type}.pdf` in a container called `documents`.
218+
219+
### Azurite
220+
Microsoft's local emulator for Azure Storage. Runs as a Docker container and provides the
221+
same API as real Azure Blob Storage. Used in `docker-compose.yml` for local dev so you don't
222+
need a real Azure account to test blob uploads.
223+
224+
### Building and Pushing Images to ACR
225+
`docker build` only creates the image **locally**. To deploy to AKS, you must also push:
226+
227+
```bash
228+
# Option 1: Build locally + push (need --platform for ARM Mac → AMD64 cluster)
229+
docker build --platform linux/amd64 -t acrdocumentstream.azurecr.io/gateway:latest -f src/gateway/Dockerfile .
230+
az acr login --name acrdocumentstream
231+
docker push acrdocumentstream.azurecr.io/gateway:latest
232+
233+
# Option 2: Build remotely on ACR (no platform flag needed, builds on Linux)
234+
az acr build --registry acrdocumentstream --image gateway:latest --file src/gateway/Dockerfile .
235+
```
236+
237+
After pushing, `kubectl rollout restart deployment/gateway` tells K8s to pull the new image.
157238

158239
---
159240

0 commit comments

Comments
 (0)