k8s-and-chill/CLAUDE.md
Felix Wolf 6f717a602f feat: Initial setup of GitOps-managed Kubernetes cluster
Configures `myks` for Helm chart rendering with `ytt` overlays to manage cluster applications.
Defines prototypes and environment-specific configurations for core applications including ArgoCD, Traefik, Cert-Manager, and Forgejo.
Adds comprehensive documentation covering cluster setup, GitOps structure, and development environment.
Integrates `direnv` for environment variable management, `gitignore` for file exclusion, and `sops` for secret encryption.
Includes rendered Kubernetes manifests and ArgoCD application resources for initial deployment.
2026-03-30 18:21:05 +02:00

3.4 KiB

k8s-and-chill

Project Overview

GitOps-managed Kubernetes cluster on Hetzner Cloud running Talos Linux. Uses myks for Helm chart rendering with ytt overlays, targeting ArgoCD for continuous deployment.

Cluster

  • 3 Talos control-plane nodes (CAX11 ARM64, Hetzner Cloud Nuremberg)
  • Node IPs: 195.201.219.111, 195.201.140.75, 195.201.219.17
  • allowSchedulingOnControlPlanes: true (no dedicated workers)
  • All namespaces use pod-security.kubernetes.io/enforce: privileged

Domain & DNS

  • Domain: tr1ceracop.de (registered at INWX)
  • DNS: Managed at INWX with wildcard A record *.tr1ceracop.de pointing to node IPs
  • Forgejo: https://git.tr1ceracop.de
  • ArgoCD: https://argocd.tr1ceracop.de

Deployed Applications

App Namespace Notes
traefik traefik Ingress controller, DaemonSet with hostPort 80/443
cert-manager cert-manager Let's Encrypt HTTP-01 via ClusterIssuer letsencrypt
forgejo forgejo Git server, SQLite, local-path PVC
argocd argocd GitOps controller
local-path-provisioner local-path-storage Default StorageClass, installed via upstream manifest

myks Structure

prototypes/         # Application templates (helm values + ytt overlays)
  argocd/
  traefik/
  cert-manager/
  forgejo/
envs/
  env-data.ytt.yaml           # Global ArgoCD config
  _env/                       # Shared overlays (annotations, secrets)
  production/
    env-data.ytt.yaml          # App list for production
    _apps/{app}/app-data.ytt.yaml  # Per-app overrides
rendered/
  envs/production/{app}/       # kubectl-ready manifests
  argocd/production/           # ArgoCD Application resources
talos/
  controlplane.yaml            # Talos machine config
  talosconfig                  # Talos client config
  kubeconfig                   # Cluster kubeconfig

Prototype Pattern

Each prototype follows this structure:

  • app-data.ytt.yaml — namespace declaration
  • vendir/vendir-data.ytt.yaml — chart name, version, repository URL
  • vendir/base.ytt.yaml — vendir config template (identical across all)
  • helm/{chart}.yaml — Helm values overrides
  • ytt/ns.ytt.yaml — Namespace resource + namespace overlay on all resources

Key Commands

myks render                          # Render all apps
myks render production <app>         # Render single app
kubectl apply -f rendered/envs/production/<app>/ --server-side  # Deploy

Kubeconfig & Talos

export KUBECONFIG=./talos/kubeconfig
export TALOSCONFIG=./talos/talosconfig

Known Issues / TODOs

  • Forgejo admin password: Hardcoded in rendered secrets (r8sA8CPHD9!bt6d). Move to external secret before pushing to git.
  • Namespace race condition: First kubectl apply of a new app often fails because namespace isn't ready. Re-apply once.
  • Traefik DaemonSet updates: Requires updateStrategy.rollingUpdate.maxSurge: 0 because hostPort conflicts prevent surge.
  • Forgejo Ingress API version: Chart renders extensions/v1beta1, fixed via ytt/ingress-fix.ytt.yaml overlay to networking.k8s.io/v1.
  • ArgoCD Phase 3: Repo not yet pushed to Forgejo, ArgoCD not yet wired.

Secrets (not in git)

  • cert-manager/letsencrypt-account-key — ACME account key (auto-generated)
  • argocd/argocd-initial-admin-secret — ArgoCD admin password (auto-generated)