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>
172 lines
5.2 KiB
YAML
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
|