|
|
|
@@ -479,31 +479,58 @@ docker-compose up -d
|
|
|
|
|
|
|
|
|
|
Includes optional services: Kafka, Prometheus, Grafana (commented out by default)
|
|
|
|
|
|
|
|
|
|
### Kubernetes
|
|
|
|
|
### Kubernetes (GitOps)
|
|
|
|
|
|
|
|
|
|
**Deploy:**
|
|
|
|
|
The recommended way to run notifier in Kubernetes is from a GitOps repository
|
|
|
|
|
(ArgoCD, Flux, or similar) that reconciles a Kustomize base + per-cluster
|
|
|
|
|
overlay, rather than applying manifests by hand. A typical setup:
|
|
|
|
|
|
|
|
|
|
- **Kustomize layout:** a `base/` with the Deployment, Service, ConfigMap, and
|
|
|
|
|
routing resources, plus an overlay per cluster/environment that sets the
|
|
|
|
|
namespace and pins the image tag. Pin an explicit version tag in the overlay —
|
|
|
|
|
don't deploy `latest`.
|
|
|
|
|
- **Secrets:** keep credentials out of git entirely. Use a secrets operator
|
|
|
|
|
(e.g. Vault Secrets Operator, External Secrets) to materialize a Secret, and
|
|
|
|
|
inject it via `envFrom` — notifier layers `NOTIFIER_*` environment variables
|
|
|
|
|
over the mounted `config.yaml`, so secret fields can be left blank in the
|
|
|
|
|
committed ConfigMap.
|
|
|
|
|
- **Config:** mount `config.yaml` from a ConfigMap at `/app/config.yaml` with the
|
|
|
|
|
non-secret settings (server mode, queue, notifier accounts).
|
|
|
|
|
- **Topology:** run a **single replica** for now — the queue and notification
|
|
|
|
|
state are in-memory, so multiple replicas won't share state (see Roadmap).
|
|
|
|
|
Point startup/readiness/liveness probes at `/health` on the REST port, and use
|
|
|
|
|
a restricted security context (non-root, read-only rootfs, seccomp
|
|
|
|
|
`RuntimeDefault`, all capabilities dropped). One Service can expose both the
|
|
|
|
|
HTTP and gRPC ports.
|
|
|
|
|
- **Exposure:** with Gateway API, use an `HTTPRoute` matching the `/api/v1` and
|
|
|
|
|
`/health` prefixes and a `GRPCRoute` matching the `notifier.v1.NotifierService`
|
|
|
|
|
service. Keeping the two routes' matches disjoint lets REST and gRPC share one
|
|
|
|
|
TLS-terminated hostname without shadowing each other; the gateway terminates
|
|
|
|
|
TLS and speaks h2c to the pod's plaintext gRPC port.
|
|
|
|
|
|
|
|
|
|
**Deploying a change:**
|
|
|
|
|
```bash
|
|
|
|
|
kubectl apply -f k8s/
|
|
|
|
|
# 1. Build and push a versioned multi-arch image
|
|
|
|
|
REGISTRY=registry.example.com/org VERSION=v0.1.5 make docker-build
|
|
|
|
|
|
|
|
|
|
# 2. Bump the pinned tag in your GitOps overlay (kustomization.yaml -> newTag)
|
|
|
|
|
|
|
|
|
|
# 3. Commit and push — your GitOps controller syncs it
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Included resources:**
|
|
|
|
|
- Deployment (3 replicas with rolling updates)
|
|
|
|
|
- Services (separate for REST and gRPC)
|
|
|
|
|
- ConfigMap (configuration management)
|
|
|
|
|
- HPA (auto-scaling 3-10 pods based on CPU/memory)
|
|
|
|
|
- Ingress (external access with TLS)
|
|
|
|
|
- Secret template (for credentials)
|
|
|
|
|
|
|
|
|
|
**Access locally:**
|
|
|
|
|
**Access for debugging:**
|
|
|
|
|
```bash
|
|
|
|
|
kubectl port-forward svc/notifier-rest 8080:8080
|
|
|
|
|
kubectl port-forward svc/notifier-grpc 50051:50051
|
|
|
|
|
kubectl -n <namespace> port-forward svc/notifier 8080:80 50051:50051
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Using Kustomize:**
|
|
|
|
|
```bash
|
|
|
|
|
kubectl apply -k k8s/
|
|
|
|
|
```
|
|
|
|
|
### Reference manifests (`k8s/`)
|
|
|
|
|
|
|
|
|
|
The `k8s/` directory in this repo contains **standalone example manifests**
|
|
|
|
|
(Deployment, REST/gRPC/metrics Services, ConfigMap, HPA, Ingress, RBAC, secret
|
|
|
|
|
template) for trying the service on a generic cluster with
|
|
|
|
|
`kubectl apply -k k8s/`. They are illustrative starting points, not a
|
|
|
|
|
production reference — a real GitOps deployment will differ (replica count,
|
|
|
|
|
Gateway API vs. Ingress, operator-managed secrets vs. plain Secret manifests).
|
|
|
|
|
|
|
|
|
|
## Architecture
|
|
|
|
|
|
|
|
|
|