chore: add CLAUDE.md, kubectl notes, and settings/gitignore tweaks
Document the repo for Claude Code, note a couple of handy kubectl one-liners, allow a few more Bash/WebFetch/WebSearch permissions used during this session, and ignore the relocated zot sync-credentials.json. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,11 @@
|
||||
"Bash(for f:*)",
|
||||
"Bash(do echo:*)",
|
||||
"Read(//Users/jan.novak/srv/personal/home-kubernetes/**)",
|
||||
"Bash(done)"
|
||||
"Bash(done)",
|
||||
"Bash(ssh docker-30 *)",
|
||||
"Bash(git add *)",
|
||||
"WebSearch",
|
||||
"WebFetch(domain:cert-manager.io)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,4 +11,5 @@ tmp/
|
||||
vms/utility-101-shadow/docker/monitoring/smtp_password
|
||||
|
||||
docker-30/zot/sync-credentials.json
|
||||
vms-home/docker-30/zot/sync-credentials.json
|
||||
kubernetes-kvm-terraform/gke_gcloud_auth_plugin_cache
|
||||
|
||||
105
CLAUDE.md
Normal file
105
CLAUDE.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Repository Purpose
|
||||
|
||||
Home Kubernetes lab infrastructure-as-code. Manages VM provisioning (Terraform/KVM), Kubernetes cluster configuration, and application deployments via Flux GitOps — all pointing at a self-hosted Gitea instance.
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Terraform (kubernetes-kvm-terraform/)
|
||||
```bash
|
||||
cd kubernetes-kvm-terraform
|
||||
tofu init
|
||||
tofu plan
|
||||
tofu apply
|
||||
tofu destroy
|
||||
```
|
||||
|
||||
### Flux GitOps
|
||||
```bash
|
||||
# Check reconciliation status
|
||||
kubectl get kustomizations -A
|
||||
kubectl get helmreleases -A
|
||||
|
||||
# Force reconcile
|
||||
flux reconcile kustomization flux-system --with-source
|
||||
flux reconcile helmrelease <name> -n <namespace>
|
||||
|
||||
# Watch logs
|
||||
flux logs --follow
|
||||
|
||||
# Check source sync
|
||||
flux get sources git
|
||||
```
|
||||
|
||||
### kubectl — common ops
|
||||
```bash
|
||||
export KUBECONFIG=kubernetes-kvm-terraform/kubeconfig
|
||||
kubectl get nodes
|
||||
kubectl get pods -A
|
||||
kubectl get secrets -A
|
||||
```
|
||||
|
||||
### Docker Compose (docker-30/ services)
|
||||
```bash
|
||||
# These run on 192.168.0.30 (docker-30), accessed via SSH
|
||||
ssh novakj@192.168.0.30
|
||||
cd /path/to/service && docker compose up -d
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Infrastructure Layer
|
||||
- **Hypervisors**: homer (192.168.0.7) and beelink (192.168.0.6) run KVM/libvirt
|
||||
- **Terraform provider**: primary `qemu+ssh://novakj@192.168.0.7/system`, secondary alias `kvm-beelink` for 192.168.0.6
|
||||
- **Kubernetes master**: kube-master-31 @ 192.168.0.31:6443, bootstrapped via kubeadm
|
||||
- **OS**: Ubuntu 24.04 Noble cloud images, network bridge `br0`, subnet 192.168.0.0/24
|
||||
|
||||
### GitOps Layer (`gitops/home-kubernetes/`)
|
||||
Flux syncs from Gitea (`https://gitea.home.hrajfrisbee.cz`, main branch, every 10 minutes). The reconciliation order is enforced via `dependsOn` in `flux-system/extra-kustomizations.yaml`:
|
||||
|
||||
```
|
||||
00-crds → 00-rbac → cilium → cert-manager → external-secrets → everything else
|
||||
```
|
||||
|
||||
Each application lives in its own subdirectory under `gitops/home-kubernetes/` and is referenced as a Flux `Kustomization` resource. Prune is enabled — removing a manifest from git removes it from the cluster.
|
||||
|
||||
### Secrets Flow
|
||||
Vault (docker-30) → External-Secrets controller (in-cluster) → Kubernetes `Secret` objects. Applications reference `ExternalSecret` CRs that pull from Vault paths. Do not put real secrets in git.
|
||||
|
||||
### Networking
|
||||
- **CNI**: Cilium 1.19.x with Gateway API and Hubble UI enabled
|
||||
- **L2 LB**: Cilium `CiliumL2AnnouncementPolicy` + `CiliumLoadBalancerIPPool` for bare-metal load-balancer IPs (defined in `gitops/home-kubernetes/cilium/`)
|
||||
- **Ingress**: ingress-nginx for HTTP(S) workloads; Gateway API for newer apps
|
||||
- **TLS**: cert-manager issues wildcard cert (`*.home.hrajfrisbee.cz`) referenced by apps
|
||||
|
||||
### Storage
|
||||
- **democratic-CSI**: iSCSI volumes backed by FreeNAS at 192.168.0.40
|
||||
- **Longhorn**: configured but disabled in Flux (directory present, not in `extra-kustomizations.yaml`)
|
||||
|
||||
### Supporting Services on docker-30 (192.168.0.30)
|
||||
All managed with Docker Compose:
|
||||
- **Gitea** — Git server + act_runner (GitHub Actions-compatible CI)
|
||||
- **Vault** — secrets backend for External Secrets
|
||||
- **Zot** — private OCI/container registry
|
||||
- **Kanidm** — identity management / OIDC provider
|
||||
- **nginx** — reverse proxy for docker-30 services
|
||||
|
||||
## Key Conventions
|
||||
|
||||
- **New application**: create a directory under `gitops/home-kubernetes/<app-name>/`, add a `Kustomization` entry in `flux-system/extra-kustomizations.yaml` with appropriate `dependsOn`.
|
||||
- **Helm apps**: use a `HelmRepository` + `HelmRelease` pair; pin chart versions explicitly.
|
||||
- **Secrets**: add an `ExternalSecret` CR pointing to the Vault path; never commit actual secret values.
|
||||
- **Terraform state**: `kubernetes-kvm-terraform/terraform.tfstate*` is gitignored/sensitive; treat it carefully.
|
||||
- **kubeconfig**: `kubernetes-kvm-terraform/kubeconfig` is gitignored; obtain it from the master node after provisioning.
|
||||
|
||||
|
||||
## Plans
|
||||
|
||||
When Claude Code's plan mode is used, save the plan file inside the repo at
|
||||
`docs/plans/YYYY-MM-DD-HHMM-<slug>.md` instead of the default `~/.claude/plans/`
|
||||
location. Get the timestamp with `date "+%Y-%m-%d-%H%M"` (matches the changelog
|
||||
convention). The `<slug>` should be a short kebab-case summary of the plan's topic.
|
||||
14
docs/kubernetes-extras.md
Normal file
14
docs/kubernetes-extras.md
Normal file
@@ -0,0 +1,14 @@
|
||||
## kubectl
|
||||
|
||||
```bash
|
||||
# condensed -o wide
|
||||
kubectl get pods -A -o wide --watch | awk '
|
||||
/NOMINATED NODE/ { sub(/[[:space:]]+NOMINATED NODE[[:space:]]+READINESS GATES[[:space:]]*$/,""); print; fflush(); next }
|
||||
{ sub(/[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]*$/,""); print; fflush() }
|
||||
'
|
||||
|
||||
# condensed -o wide
|
||||
kubectl get pods -A --watch -o custom-columns=\
|
||||
'NAMESPACE:.metadata.namespace,NAME:.metadata.name,STATUS:.status.phase,RESTARTS:.status.containerStatuses[0].restartCount,IP:.status.podIP,NODE:.spec.nodeName'
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user