Files
k8s-manifests/gitea/deployment-gitea-runner.yaml
T
chemavxandClaude Opus 5 472bb6e5b9 gitea-runner: sidecar que barre imágenes huérfanas en dind
El pod fue desalojado el 2026-08-12 tras 21 días: el emptyDir de dind
superó su límite de 10Gi.

La caché de buildx no era la causa (los workflows hacen `buildx rm` al
inicio de cada run y se recicla sola, ~330M). Lo que se acumula son
imágenes sin tag: al republicar upstream catthehacker/ubuntu:act-22.04,
la anterior (1,5G) queda colgada para siempre.

Ni el GC de dockerd ni el de buildkit lo recogen porque ambos calculan
su umbral contra el disco del nodo (913G), no contra el cap del pod.
Nunca saltan antes del desalojo.

El sidecar hace `docker image prune -f` cada 6h por localhost:2375.
Sin -a: solo dangling, nunca una imagen con tag, así que la caché de
act y la de buildkit siguen intactas y los builds no se frenan.

Se descartó un CronJob externo: exigiría pods/exec o publicar el 2375
como Service, y ese puerto va sin TLS ni auth sobre un docker
privilegiado.

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

159 lines
4.5 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.
- args:
- |
while true; do
sleep 21600
docker image prune -f || true
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
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