Files
k8s-manifests/gitea/deployment-gitea-runner.yaml
T
chemavxandClaude Opus 5 e6ba49a1af gitea-runner: el janitor deja el uso del volumen en su log
Tras el desalojo del 2026-08-12 no quedaba nada que mirar: el emptyDir
muere con el pod, así que la causa hubo que deducirla por descarte.

Ahora el janitor mide /dind (montado en solo lectura) antes y después de
cada barrido y lo escribe en su log, cada 6h. La próxima vez habrá curva
de crecimiento medida en vez de conjeturas.

No se usa Prometheus porque no puede verlo: kubelet_volume_stats_* solo
emite series para PVCs y container_fs_usage_bytes viene vacío en k3s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 20:17:09 +00:00

172 lines
5.2 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: gitea-runner
name: gitea-runner
namespace: gitea
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: gitea-runner
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
kubectl.kubernetes.io/restartedAt: '2026-05-05T09:17:26Z'
labels:
app: gitea-runner
spec:
containers:
- args:
- --host=tcp://0.0.0.0:2375
- --tls=false
env:
- name: DOCKER_TLS_CERTDIR
image: docker:24.0.9-dind
imagePullPolicy: IfNotPresent
livenessProbe:
exec:
command:
- docker
- info
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 1
name: dind
resources:
limits:
cpu: '2'
memory: 4Gi
requests:
cpu: 500m
memory: 2Gi
securityContext:
privileged: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/docker
name: dind-storage
- mountPath: /etc/docker/daemon.json
name: docker-daemon-config
subPath: daemon.json
- mountPath: /etc/buildkit/buildkitd.toml
name: buildkitd-config
subPath: buildkitd.toml
- args:
- |
until nc -z localhost 2375 2>/dev/null; do sleep 1; done
exec /usr/local/bin/run.sh
command:
- /bin/sh
- -c
env:
- name: GITEA_INSTANCE_URL
value: http://gitea.gitea.svc.cluster.local:3000
- name: GITEA_RUNNER_NAME
value: k8s-runner
- name: CONFIG_FILE
value: /etc/act_runner/config.yaml
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
key: GITEA_RUNNER_REGISTRATION_TOKEN
name: gitea-runner-secret-infisical
- name: DOCKER_HOST
value: tcp://localhost:2375
image: gitea/act_runner:0.6.1
imagePullPolicy: Always
name: runner
resources:
limits:
cpu: '1'
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: runner-data
- mountPath: /etc/act_runner
name: runner-config
# Recolector de imágenes huérfanas. El emptyDir de dind está capado a 10Gi,
# pero el GC de dockerd y el de buildkit calculan su umbral contra el disco
# del nodo (913G), así que no saltan nunca antes del desalojo. El 2026-08-12
# el pod fue desalojado tras 21 días por eso. Lo que se acumula son imágenes
# sin tag: cada vez que upstream republica catthehacker/ubuntu:act-22.04, la
# anterior (1,5G) queda colgada y nadie la borra.
# prune SIN -a a propósito: borra solo las dangling, jamás una imagen con tag,
# así que no vacía la caché de act ni la de buildkit y los builds no se frenan.
# Además deja el uso del volumen en su propio log cada vuelta. El emptyDir
# muere con el pod, así que tras un desalojo no queda nada que inspeccionar:
# el 2026-08-12 hubo que deducir la causa por descarte. Con esto, la próxima
# vez `kubectl logs -c janitor` da la curva de crecimiento ya medida.
# Prometheus no vale para esto: kubelet_volume_stats_* solo cubre PVCs.
- args:
- |
sleep 30
while true; do
antes=$(du -sm /dind 2>/dev/null | cut -f1)
docker image prune -f >/dev/null 2>&1 || true
ahora=$(du -sm /dind 2>/dev/null | cut -f1)
echo "[janitor] $(date -Iseconds) dind ${ahora}MB de 10240MB (antes del barrido ${antes}MB)"
sleep 21600
done
command:
- /bin/sh
- -c
env:
- name: DOCKER_HOST
value: tcp://localhost:2375
image: docker:24.0.9-cli
imagePullPolicy: IfNotPresent
name: janitor
resources:
limits:
cpu: 100m
memory: 64Mi
requests:
cpu: 10m
memory: 32Mi
volumeMounts:
- mountPath: /dind
name: dind-storage
readOnly: true
dnsPolicy: ClusterFirst
nodeSelector:
kubernetes.io/hostname: chemavx-k8
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- emptyDir: {}
name: runner-data
- configMap:
defaultMode: 420
name: gitea-runner-config
name: runner-config
- emptyDir:
sizeLimit: 10Gi
name: dind-storage
- configMap:
defaultMode: 420
name: docker-daemon-config
name: docker-daemon-config
- configMap:
defaultMode: 420
name: buildkitd-config
name: buildkitd-config