Preparar y construir¶
Herramientas¶
| Herramienta | Versión | Dónde está en main |
Se usa para |
|---|---|---|---|
| Go | 1.27 | ~/.local/go/bin |
construir, probar, generadores |
| Node.js + npm | 20 | el sistema | la interfaz |
| controller-gen | v0.22.0 | ~/go/bin |
código de copia profunda y CRD a partir de los tipos de Go |
| setup-envtest | v0.25.1 | ~/go/bin |
descarga un servidor de la API de Kubernetes de prueba + etcd |
| kubectl | la del clúster | el sistema | todo lo del lado del clúster |
| docker | cualquiera | el sistema | solo para correr el cliente buildctl de make image |
El Makefile agrega ~/.local/go/bin y ~/go/bin al PATH de sus objetivos. Para una máquina nueva:
# Go
curl -sL https://go.dev/dl/go1.27.1.linux-arm64.tar.gz | tar -C ~/.local -xz
export PATH=$HOME/.local/go/bin:$HOME/go/bin:$PATH
go install sigs.k8s.io/controller-tools/cmd/[email protected]
go install sigs.k8s.io/controller-runtime/tools/[email protected]
El repositorio¶
rendimiento.ai/
├── cmd/rendimiento/ main.go: ajustes, conexiones, arranque (la raíz de composición)
├── api/v1alpha1/ recursos personalizados App y Addon (tipos de Go → CRD)
├── internal/
│ ├── spec/ rendimiento.yaml: tipos, valores predeterminados, validación
│ ├── detect/ qué contiene un repositorio (lenguaje, puerto, pruebas, necesidades)
│ ├── generate/ propuestas a partir de la detección (+ Dockerfiles en templates/)
│ ├── github/ la aplicación de GitHub: JWT, tokens, cliente de la API, árboles, OAuth
│ ├── platform/ orquestación: avisos web → ejecuciones → versiones → objetos App
│ ├── pipeline/ integración continua: plan, corredor, ejecutor de Kubernetes (pods de construcción)
│ ├── store/ Postgres: aplicaciones, ejecuciones, registros, versiones, sesiones, complementos
│ ├── render/ especificación + imágenes → objetos de Kubernetes (puro)
│ ├── controller/ controladores de App y Addon, ganchos, necesidades
│ ├── addon/ generación de complementos (Helm, kustomize), sincronización con git, catálogo
│ ├── renovate/ el complemento de Renovate
│ ├── catalog/ la página Servicios
│ ├── environment/ la página Entorno
│ ├── dns/ registros de Cloudflare, DNS dinámico
│ ├── events/ concentrador de actualizaciones en vivo (SSE)
│ └── api/ API HTTP, autenticación, avisos web, configuración, servidor de la interfaz
├── web/ la interfaz de React (src/) y su incrustación (embed.go)
├── templates/dockerfiles/ plantillas de Dockerfile para las tecnologías detectadas
├── deploy/ manifiestos de la propia plataforma (kubectl apply -k)
├── docs/ este libro (MkDocs Material)
├── hack/ herramientas de desarrollo: test-remote.sh, codemap, undoc
├── Dockerfile la imagen de la plataforma (interfaz + Go, en varias etapas)
├── Makefile construir, probar, imagen, desplegar
└── rendimiento.yaml cómo despliega rendimiento este libro
Objetivos de make¶
export PATH := $(HOME)/.local/go/bin:$(HOME)/go/bin:$(PATH)
# This cluster's values (registry, deploy overlay, nodes to avoid) live in
# local.mk, which is not in the public repository.
-include local.mk
TEST_DATABASE_URL ?= postgres://postgres:[email protected]:55432/rendimiento
IMAGE ?= registry.example.lan:5000/rendimiento
DEPLOY_DIR ?= deploy
.PHONY: generate ui build test test-remote test-db itest image railpack-image deploy docs-codemap docs-check
generate: ## deepcopy + CRD from api/v1alpha1
controller-gen object paths=./api/... paths=./internal/spec/...
controller-gen crd paths=./api/... output:crd:dir=deploy/crds
ui:
cd web && npm ci && npm run build
build: ui
go build -o rendimiento ./cmd/rendimiento
test-db: ## disposable Postgres for tests
docker run -d --rm --name rendimiento-testpg -e POSTGRES_PASSWORD=test -e POSTGRES_DB=rendimiento -p 127.0.0.1:55432:5432 postgres:17-alpine
# -p 1: store, platform and api tests share one test database.
# generate first: a stale CRD makes the API server silently drop new fields.
test: generate
@# envtest control planes left by an interrupted run keep using CPU and disk.
-@pkill -f '[k]ubebuilder-envtest/k8s/.*/(kube-apiserver|etcd)' ; rm -rf /tmp/k8s_test_framework_*
go vet ./...
KUBEBUILDER_ASSETS=$$(setup-envtest use -p path) TEST_DATABASE_URL=$(TEST_DATABASE_URL) go test -p 1 ./...
cd web && npm run typecheck
# The same steps on a worker node: main is the k3s control plane, and
# compiling plus envtest there slows the API server. Prefer this one.
test-remote:
TEST_EXCLUDE_NODES="$(TEST_EXCLUDE_NODES)" hack/test-remote.sh
itest: ## real build on the cluster's buildkitd
ITEST_REGISTRY="$(ITEST_REGISTRY)" ITEST_EXCLUDE_NODES="$(ITEST_EXCLUDE_NODES)" ITEST_RAILPACK_IMAGE="$(ITEST_RAILPACK_IMAGE)" \
go test -tags integration ./internal/pipeline -run TestBuildOnCluster -v -timeout 25m
# Build on the cluster's BuildKit pool (the buildkitd Service reaches one of
# its daemons), not on this node: main is also the k3s control plane, and a
# local compile starves its SQLite datastore.
BUILDKIT_PORT ?= 12345
image:
@kubectl port-forward -n devops-tools svc/buildkitd $(BUILDKIT_PORT):1234 >/dev/null 2>&1 & pf=$$!; \
trap "kill $$pf 2>/dev/null" EXIT; sleep 3; \
docker run --rm --network host -v $(CURDIR):/src:ro --entrypoint buildctl moby/buildkit:v0.18.2 \
--addr tcp://127.0.0.1:$(BUILDKIT_PORT) build --frontend dockerfile.v0 \
--local context=/src --local dockerfile=/src \
--output type=image,name=$(IMAGE):latest,push=true,registry.insecure=true \
--import-cache type=registry,ref=$(IMAGE):buildcache,registry.insecure=true \
--export-cache type=registry,ref=$(IMAGE):buildcache,mode=max,registry.insecure=true
RAILPACK_VERSION ?= 0.40.0
railpack-image: ## the railpack CLI image build pods use (RAILPACK_IMAGE)
@kubectl port-forward -n devops-tools svc/buildkitd $(BUILDKIT_PORT):1234 >/dev/null 2>&1 & pf=$$!; \
trap "kill $$pf 2>/dev/null" EXIT; sleep 3; \
docker run --rm --network host -v $(CURDIR)/deploy/railpack:/src:ro --entrypoint buildctl moby/buildkit:v0.18.2 \
--addr tcp://127.0.0.1:$(BUILDKIT_PORT) build --frontend dockerfile.v0 \
--local context=/src --local dockerfile=/src --opt build-arg:VERSION=$(RAILPACK_VERSION) \
--output type=image,name=$(IMAGE)-railpack:$(RAILPACK_VERSION),push=true,registry.insecure=true
# DEPLOY_DIR is deploy/ (example values) or a private overlay with a real
# cluster's settings on top of it (set in local.mk).
deploy:
kubectl kustomize --load-restrictor=LoadRestrictionsNone $(DEPLOY_DIR) | kubectl apply -f -
# The book's code reference, generated from the Go and TypeScript sources.
# The book's image regenerates it on every build; run this to preview it.
docs-codemap:
go run ./hack/codemap > docs/content/reference/code-map.md
# Mermaid diagrams are drawn in the browser, so mkdocs cannot catch their
# syntax errors; this parses each one with Mermaid itself.
docs-check:
cd hack/checkdiagrams && npm install --no-audit --no-fund --loglevel=error && node check.mjs ../../docs/content
| Objetivo | Hace | Dónde corre |
|---|---|---|
make generate |
código de copia profunda y CRD desde api/v1alpha1 e internal/spec |
aquí (ligero) |
make test-remote |
generar, vet, todas las pruebas de Go, revisión de tipos de la interfaz | un nodo trabajador |
make test |
lo mismo | aquí: evítelo en main |
make test-db |
un Postgres desechable para pruebas locales | aquí |
make itest |
construcciones reales en el grupo de BuildKit (Dockerfile y Railpack) | el clúster |
make image |
construye y envía rendimiento:latest |
el grupo de BuildKit |
make railpack-image |
la imagen con la herramienta de Railpack para los pods de construcción | el grupo de BuildKit |
make deploy |
kubectl apply -k deploy |
— |
make docs-codemap |
vuelve a generar docs/content/reference/code-map.md |
aquí |
make ui, make build |
la interfaz y un programa local | aquí (pesado) |
El ciclo de un cambio¶
# 1. editar el código (y el libro)
# 2. respuesta rápida sobre el paquete que tocó (lo bastante ligero para main)
go vet ./internal/render && go test ./internal/render
# 3. todo, en un nodo trabajador
make test-remote
# 4. publicar
make image && make deploy && kubectl -n rendimiento-system rollout restart deploy/rendimiento
# 5. confirmar y enviar (el libro se vuelve a desplegar solo)
Ejecutar rendimiento¶
rendimiento es un controlador: nunca corra una segunda copia contra el clúster de producción. Conciliaría los mismos objetos App que la copia real, y las dos se pelearían.
Para ejecutarlo fuera del clúster, use un clúster aparte (por ejemplo k3d o kind, en una laptop) con su propio Postgres:
make test-db # Postgres en 127.0.0.1:55432
kubectl apply -f deploy/crds/ # contra el clúster de prueba
export DATABASE_URL=postgres://postgres:[email protected]:55432/rendimiento?sslmode=disable
export ALLOWED_USERS=<su-cuenta-de-github> BASE_URL=http://localhost:8080 SETUP_TOKEN=dev LEADER_ELECTION=false
go run ./cmd/rendimiento # usa su kubeconfig actual
Luego abra http://localhost:8080/api/setup/github?token=dev para crear una aplicación de GitHub de desarrollo. Los avisos web necesitan una URL pública (un túnel como cloudflared); si no, use el botón Ejecutar en lugar de los envíos.
Trabajar en la interfaz¶
cd web && npm ci
npm run dev # Vite en :5173 con recarga en caliente; /api pasa a localhost:8080
npm run typecheck # lo que corren las pruebas
npm run build # web/dist, que incrusta la construcción de Go
El servidor de desarrollo necesita una API de rendimiento en localhost:8080, la local de arriba. La galleta de sesión la pone el inicio de sesión de ese servidor, así que primero inicie sesión en http://localhost:8080.
Generar código¶
make generate corre controller-gen dos veces:
objectescribezz_generated.deepcopy.go: los métodosDeepCopyque necesita cada tipo de Kubernetes (la caché entrega copias);crdescribedeploy/crds/*.yamla partir de los tipos de Go y sus marcas// +kubebuilder:(validación, columnas para mostrar, alcance, nombres cortos).
Las dos salidas se confirman en git. Después de cambiar api/v1alpha1 o internal/spec, vuelva a generar, aplique el CRD y reinicie la plataforma.