Disable SSH; serve git.unkin.net + git.k8s.syd1 admin route
Per the forge design: drop git-over-ssh (HTTPS clones only, estate norm) and serve the new instance on both the canonical git.unkin.net and a git.k8s.syd1.au.unkin.net admin/backup route (same dual-name pattern as identity). Only the k8s admin name goes live now (external-dns); the git.unkin.net DNS flip stays the gated final cutover step. - values: DISABLE_SSH + START_SSH_SERVER false; DOMAIN/ROOT_URL/SSH_DOMAIN -> git.unkin.net; drop the SSH LoadBalancer service - overlay: $patch-delete the chart's leftover gitea-ssh Service - gateway/httproute: listeners + routes for git.unkin.net and git.k8s.syd1.au.unkin.net; cert CN git.unkin.net (both as SANs); external-dns publishes only git.k8s.syd1.au.unkin.net -> 198.18.200.4 - bind-internal: prepared (commented) git-dns-internal DNSRecord as the gated apex cutover step - docs: SSH removed, dual hostnames, git.unkin.net flip as the final step Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
This commit is contained in:
+29
-26
@@ -14,8 +14,8 @@ for rollback.
|
||||
| Repo/LFS storage | RWX PVC `gitea-shared-storage` (`cephfs-raid6-delete`, 20Gi) | `/shared/apps/gitea` |
|
||||
| DB | CNPG `gitea-postgres` (2 instances) + pgbouncer, S3 backup `cnpg-gitea` 04:00/30d | Patroni-shared Postgres |
|
||||
| Cache/session/queue | standalone Valkey (db 0/1/2, AOF) | Redis sentinel |
|
||||
| SSH | LoadBalancer VIP `198.18.200.10:2222` (built-in per-pod SSH server) | host sshd, port 2222 |
|
||||
| Ingress | Gateway API → `git2.k8s.syd1.au.unkin.net` (temp) | HAProxy `be_gitea` → git.unkin.net |
|
||||
| SSH | **disabled** (`DISABLE_SSH`) — HTTPS clones only | host sshd, port 2222 |
|
||||
| Ingress | Gateway API → `git.unkin.net` + `git.k8s.syd1.au.unkin.net` | HAProxy `be_gitea` → git.unkin.net |
|
||||
| Actions | **disabled** (CI stays Woodpecker) | runner deployed separately |
|
||||
| Container registry | **disabled** (moved to artifactapi `docker-internal`) | built-in, in use |
|
||||
| Other package types | enabled (generic archives for *arr etc. still used) | built-in |
|
||||
@@ -52,11 +52,13 @@ vault kv put kv/kubernetes/namespace/gitea/default/oauth-credentials \
|
||||
|
||||
## Stages
|
||||
|
||||
**0 — Validate on the temp host.** Merge this PR + the terraform-authentik PR
|
||||
(gitea OIDC app). ArgoCD syncs the `gitea` app. Confirm: `git2.k8s.syd1.au.unkin.net`
|
||||
serves, local-admin login, OIDC login (Authentik → auto-register/link), create a
|
||||
test repo, HTTPS push/clone, SSH push/clone via `198.18.200.10:2222`, and a
|
||||
Woodpecker webhook fires against the temp host.
|
||||
**0 — Validate on the admin route.** Merge this PR + the terraform-authentik PR
|
||||
(gitea OIDC app). ArgoCD syncs the `gitea` app; external-dns publishes
|
||||
`git.k8s.syd1.au.unkin.net` → the gateway VIP (safe — new name, empty instance).
|
||||
`git.unkin.net` stays on the live VM until stage 2. Confirm on the admin route:
|
||||
local-admin login, OIDC login (Authentik → auto-register/link), create a test
|
||||
repo, HTTPS push/clone (SSH is disabled — HTTPS only), and a Woodpecker webhook
|
||||
fires against `git.k8s.syd1.au.unkin.net`.
|
||||
|
||||
**1 — Data migration rehearsal.** Gitea is already Postgres→Postgres, so **no DB
|
||||
engine conversion** — a plain SQL dump/restore plus a filesystem copy of the data
|
||||
@@ -82,18 +84,22 @@ Then set `gitea-inner` to the VM's real `SECRET_KEY`/`INTERNAL_TOKEN` (above) an
|
||||
restart the deployment. Verify repos/issues/LFS/users. Rehearse fully before the
|
||||
freeze so the freeze window is just a delta.
|
||||
|
||||
**2 — Freeze + cutover.** Put the VM read-only (stop Woodpecker/webhooks), take a
|
||||
final dump/restore of the delta. Then:
|
||||
- Add `git.unkin.net` to the Gateway: append it as a second listener hostname +
|
||||
cert SAN (`cert-manager.io/common-name` stays, add the host to the listeners and
|
||||
a matching HTTPRoute), and set `gitea.config.server.{DOMAIN,ROOT_URL,SSH_DOMAIN}`
|
||||
back to `git.unkin.net`.
|
||||
- Repoint DNS `git.unkin.net` → the internal Traefik VIP `198.18.200.4`. **Record
|
||||
owner:** `git.unkin.net` currently resolves to the HAProxy VRRP anycast VIP
|
||||
`198.18.19.17` (`roles::infra::halb::haproxy2 anycast_ip`); the A record lives in
|
||||
the `main.unkin.net` zone (Puppet DNS `roles::infra::dns::master`). Update it
|
||||
there (or via the bind estate) — **not** external-dns, which only owns the
|
||||
`*.k8s.…` records.
|
||||
**2 — Freeze + cutover (the `git.unkin.net` DNS flip).** Put the VM read-only (stop
|
||||
Woodpecker/webhooks), take a final dump/restore of the delta. The Gateway already
|
||||
serves `git.unkin.net` (listener + cert SAN) and the app already advertises
|
||||
`ROOT_URL https://git.unkin.net/`, so cutover is **only the DNS flip**:
|
||||
- Repoint `git.unkin.net` → the internal Traefik VIP `198.18.200.4`.
|
||||
- **Where the record lives (reconciled):** `git.unkin.net` resolves TODAY via the
|
||||
**Puppet DNS master** (`profiles::dns::master`, records from PuppetDB exported
|
||||
resources) to the HAProxy VRRP VIP `198.18.19.17` → the VM. The GitOps home for
|
||||
the `unkin.net` apex is the **k8s bind-operator** `unkin-net` BindZone
|
||||
(`apps/base/bind-internal/authoritative/`), where `identity.unkin.net` already
|
||||
lives as a DNSRecord — but that zone currently holds only SOA+NS + a few records
|
||||
(the bulk apex migration off Puppet is a pending follow-up). So at cutover, flip
|
||||
**whichever is the live authority for `unkin.net` at that moment**: either
|
||||
uncomment the `git-dns-internal` DNSRecord in `records.yaml` (prepared, gated) if
|
||||
the k8s bind cluster is live, or change the Puppet-side record. **Not**
|
||||
external-dns — it owns only the `k8s.syd1.au.unkin.net` zone.
|
||||
|
||||
**3 — Consumer verification.** After DNS/cert flips:
|
||||
|
||||
@@ -112,16 +118,13 @@ VM was never modified, so rollback is a single record change.
|
||||
|
||||
## Open decisions / hard problems
|
||||
|
||||
- **SSH on git.unkin.net:2222.** One A record can't point at both the HTTPS gateway
|
||||
VIP (`.4`) and a separate SSH VIP. Options: (a) HTTPS-only clones (estate norm,
|
||||
SSH dropped); (b) a Traefik `TCPRoute` so `.4:2222` reaches the SSH service
|
||||
(share one VIP); (c) keep SSH on a dedicated host/VIP. Validation uses (c) via
|
||||
`git2-ssh.k8s.…:2222`.
|
||||
- **SSH is disabled** (`DISABLE_SSH`) — HTTPS clones only, the estate norm. No SSH
|
||||
VIP, no SSH DNS, nothing to cut over.
|
||||
- **artifactapi's own image is circular** — it currently pulls `git.unkin.net/unkin/
|
||||
artifactapi`. It can't pull itself from `docker-internal`. Keep it on an
|
||||
external/bootstrap-safe registry (or node-preloaded) before the VM registry goes
|
||||
away; not repointed in the registry-migration PR.
|
||||
- **`forge_remote_id` stability** (Woodpecker) hinges on preserving Gitea repo IDs —
|
||||
guaranteed by a full SQL restore, broken by any re-create/re-migrate path.
|
||||
- **Cutover window**: freeze = final delta dump/restore + DNS TTL. Keep the
|
||||
`main.unkin.net` record TTL low a day ahead.
|
||||
- **Cutover window**: freeze = final delta dump/restore + DNS TTL. Lower the
|
||||
`git.unkin.net` record TTL (600s in both zones) a day ahead so the flip is quick.
|
||||
|
||||
Reference in New Issue
Block a user