Initial commit: GitOps Starter Pack
A teaching-first, single-cluster GitOps setup: Talos Linux + Argo CD with an app-of-apps layout, MetalLB pre-installed for real LoadBalancer IPs on bare metal, a demo app, and a progressive docs/ walkthrough with a CLAUDE.md tutor persona and guided bootstrap checklist. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# 08 — Growing up: what to add next
|
||||
|
||||
Everything up to here is deliberately minimal — enough to understand the
|
||||
whole loop, nothing more. This doc is a map of the natural next steps, each
|
||||
with why you'd want it and roughly what it involves. None of it is built
|
||||
for you; each is its own project once you're ready.
|
||||
|
||||
## More nodes
|
||||
|
||||
Right now, one machine is both control plane and worker
|
||||
(`allowSchedulingOnControlPlanes: true` in
|
||||
[`talos/patch-controlplane.yaml`](../talos/patch-controlplane.yaml)). That's
|
||||
a single point of failure: if that machine dies, the cluster is gone.
|
||||
|
||||
To grow beyond it:
|
||||
|
||||
1. Boot a second machine from the Talos ISO, same as the first.
|
||||
2. Generate a **worker** config instead of a control-plane one — you
|
||||
already have `_out/worker.yaml` from
|
||||
[`docs/02-talos-bootstrap.md`](02-talos-bootstrap.md), unused until now.
|
||||
3. `talosctl apply-config --insecure --nodes <NEW_NODE_IP> --file _out/worker.yaml`
|
||||
4. `kubectl get nodes` should show two nodes shortly after.
|
||||
|
||||
For real resilience against a control-plane node failing (not just adding
|
||||
worker capacity), you'd want an odd number of control-plane nodes — 3 is
|
||||
the normal minimum — because etcd (the cluster's data store) uses majority
|
||||
voting to agree on state, and majority voting needs an odd number to avoid
|
||||
ties. That's a bigger step than this doc covers in detail; ask Claude when
|
||||
you're actually ready to take it.
|
||||
|
||||
## Ingress
|
||||
|
||||
Right now, thanks to MetalLB ([`docs/05-metallb.md`](05-metallb.md)), the
|
||||
demo app gets its own dedicated IP address
|
||||
(see [`apps/demo/service.yaml`](../apps/demo/service.yaml)). That's a real
|
||||
improvement over NodePort, but it doesn't scale past a handful of apps
|
||||
either: every app still needs its own IP address out of a pool that's only
|
||||
so big, and there's no way to route by hostname (`app1.example.com` vs
|
||||
`app2.example.com` sharing one IP on port 443).
|
||||
|
||||
An **Ingress controller** is itself just another app you'd deploy the same
|
||||
way as anything else in this repo (see
|
||||
[`docs/07-adding-new-apps.md`](07-adding-new-apps.md)) — commonly as a
|
||||
Helm-based app, since most ingress controllers are distributed that way,
|
||||
same as MetalLB. It typically sits behind one single MetalLB
|
||||
`LoadBalancer` Service (one IP, total, for every app), and you add an
|
||||
`Ingress` resource per app instead of giving each one its own
|
||||
`LoadBalancer` Service — trading "one IP per app" for "one IP, many
|
||||
hostnames."
|
||||
|
||||
## cert-manager
|
||||
|
||||
Once you have Ingress and real hostnames, you'll want HTTPS. `cert-manager`
|
||||
is the standard tool for this — it watches for certificate requests and
|
||||
automatically obtains and renews them (commonly via Let's Encrypt). Also
|
||||
just another app in this repo's structure once you get there.
|
||||
|
||||
## Secrets management
|
||||
|
||||
**This repo is public. Never commit a plaintext secret, credential, token,
|
||||
or private key to it — anyone can read your Git history, forever, even if
|
||||
you delete the file in a later commit.**
|
||||
|
||||
Kubernetes' own `Secret` resource does not encrypt anything — it just
|
||||
base64-encodes data, which is not encryption, only encoding (trivially
|
||||
reversible by anyone). None of the manifests in this repo need secrets yet,
|
||||
which is exactly why this hasn't come up so far. When you add something
|
||||
that does (a database password, an API key), you need one of:
|
||||
|
||||
- **[Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets)** —
|
||||
encrypts a secret using a key that only your cluster holds, producing a
|
||||
`SealedSecret` file that's safe to commit; the cluster decrypts it into a
|
||||
normal Secret on the fly.
|
||||
- **[SOPS](https://github.com/getsops/sops)** (often paired with Argo CD via
|
||||
a plugin) — encrypts values inside a normal-looking YAML file using a key
|
||||
from a system like age or a cloud KMS, decrypted at sync time.
|
||||
|
||||
Either is a reasonable choice; don't improvise your own approach. Ask
|
||||
Claude to walk you through setting one up when you have a real secret to
|
||||
manage — it's a short, well-trodden path once you're at that point.
|
||||
|
||||
> **Ask Claude:** if you're about to commit anything you're even slightly
|
||||
> unsure about, paste it (or describe it) and ask first. Cheaper than a
|
||||
> `git filter-branch` later.
|
||||
|
||||
## Where to go from here
|
||||
|
||||
You've now seen the whole shape: Talos underneath, Argo CD watching Git,
|
||||
app-of-apps organizing what it manages. Everything in this doc is more of
|
||||
the same pattern — a new app, a new file, a push. Pick whichever expansion
|
||||
is actually useful to you and start there.
|
||||
Reference in New Issue
Block a user