Skaffold: Flujo de Desarrollo Kubernetes Automatizado
Skaffold automatiza el ciclo build-push-deploy para el desarrollo de aplicaciones en Kubernetes, detectando cambios en el código y actualizando el clúster en tiempo real. Esta guía explica cómo configurar Skaffold en Linux para sincronización de archivos, hot reload, pipelines de construcción, estrategias de despliegue y la integración con CI/CD.
Requisitos Previos
- Docker instalado y en ejecución
kubectlconfigurado con acceso a un clúster (local con kind/minikube o remoto)- Conocimientos básicos de Kubernetes y Docker
# Verificar Docker
docker version
# Verificar kubectl
kubectl cluster-info
Instalación de Skaffold
# Linux (amd64)
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
chmod +x skaffold
sudo mv skaffold /usr/local/bin/
# Verificar la instalación
skaffold version
# Completado automático de comandos para bash
skaffold completion bash >> ~/.bashrc
source ~/.bashrc
Configuración Básica
Skaffold se configura mediante el archivo skaffold.yaml en la raíz del proyecto:
# Inicializar Skaffold en un proyecto existente (detecta Dockerfile y manifiestos)
skaffold init
# O crear manualmente el archivo de configuración
cat << 'EOF' > skaffold.yaml
apiVersion: skaffold/v4beta8
kind: Config
metadata:
name: mi-aplicacion
# Configuración de construcción de imágenes
build:
artifacts:
- image: mi-aplicacion
context: .
docker:
dockerfile: Dockerfile
# Construir localmente sin subir al registro
local:
push: false
useBuildkit: true
# Configuración del despliegue
manifests:
rawYaml:
- k8s/deployment.yaml
- k8s/service.yaml
deploy:
kubectl: {}
EOF
Estructura de proyecto recomendada:
mi-aplicacion/
├── skaffold.yaml
├── Dockerfile
├── src/
│ └── app.py
└── k8s/
├── deployment.yaml
└── service.yaml
Modos de Sincronización y Hot Reload
La sincronización de archivos evita reconstruir la imagen completa en cada cambio:
# skaffold.yaml con sincronización de archivos
build:
artifacts:
- image: mi-app-python
context: .
sync:
# Sincronización manual: copia archivos directamente al contenedor
manual:
- src: 'src/**/*.py'
dest: /app/src
- src: 'templates/**/*.html'
dest: /app/templates
# Sincronización inferida: Skaffold detecta el método automáticamente
infer:
- '**/*.js'
- '**/*.css'
Para aplicaciones con hot reload nativo (por ejemplo, Node.js con nodemon):
# Configuración para Node.js con nodemon
build:
artifacts:
- image: mi-app-node
context: .
docker:
dockerfile: Dockerfile.dev
sync:
infer:
- '**/*.js'
- 'package.json'
# Dockerfile.dev - Usa nodemon para hot reload
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# nodemon reinicia la app al detectar cambios
CMD ["npx", "nodemon", "--watch", "src", "src/index.js"]
Pipelines de Construcción
Skaffold soporta múltiples backends de construcción:
# Construcción con Kaniko (en el clúster, sin Docker local)
build:
artifacts:
- image: registry.empresa.com/mi-app
kaniko:
cache:
repo: registry.empresa.com/cache
cluster:
pullSecretName: regcred
namespace: kaniko
---
# Construcción con Buildpacks (sin Dockerfile)
build:
artifacts:
- image: mi-app-buildpack
buildpacks:
builder: gcr.io/buildpacks/builder:latest
dependencies:
paths:
- src/
- package.json
---
# Construcción multi-etapa paralela
build:
artifacts:
- image: frontend
context: frontend/
- image: backend
context: backend/
- image: worker
context: worker/
# Construir todas las imágenes en paralelo
local:
concurrency: 0
Estrategias de Despliegue
# Despliegue con Helm
manifests:
helm:
releases:
- name: mi-app
chartPath: helm/mi-app
valuesFiles:
- helm/values-dev.yaml
setValues:
image.tag: "" # Skaffold gestiona el tag automáticamente
recreatePods: false
deploy:
helm: {}
# Despliegue con Kustomize
manifests:
kustomize:
paths:
- k8s/overlays/desarrollo
deploy:
kubectl:
defaultNamespace: desarrollo
# Verificar el despliegue con health checks
deploy:
kubectl:
defaultNamespace: default
statusCheck: true
statusCheckDeadlineSeconds: 120
tolerateFailuresUntilDeadline: true
Perfiles de Skaffold
Los perfiles permiten tener configuraciones diferentes para desarrollo, staging y CI:
# skaffold.yaml con múltiples perfiles
apiVersion: skaffold/v4beta8
kind: Config
metadata:
name: mi-aplicacion
# Configuración base
build:
artifacts:
- image: mi-app
context: .
manifests:
kustomize:
paths:
- k8s/base
# Perfil de desarrollo local
profiles:
- name: dev
activation:
- command: dev # Se activa automáticamente con skaffold dev
build:
local:
push: false
manifests:
kustomize:
paths:
- k8s/overlays/desarrollo
# Perfil de staging con imagen en registry
- name: staging
build:
artifacts:
- image: registry.empresa.com/mi-app
manifests:
kustomize:
paths:
- k8s/overlays/staging
# Perfil de CI/CD sin watch
- name: ci
build:
local:
push: true
useBuildkit: true
manifests:
kustomize:
paths:
- k8s/overlays/produccion
Usar los perfiles:
# Desarrollo con hot reload (perfil dev activado automáticamente)
skaffold dev --profile dev
# Despliegue en staging
skaffold run --profile staging
# Pipeline de CI
skaffold run --profile ci --tag $(git rev-parse --short HEAD)
# Limpiar recursos después del desarrollo
skaffold delete --profile dev
Integración con CI/CD
# Ejemplo de pipeline en GitLab CI
cat << 'EOF' > .gitlab-ci.yml
stages:
- build
- deploy
variables:
SKAFFOLD_DEFAULT_REPO: registry.gitlab.com/mi-org/mi-app
build-y-deploy-staging:
stage: deploy
image: gcr.io/k8s-skaffold/skaffold:latest
script:
# Configurar acceso al clúster de staging
- kubectl config set-cluster staging --server=$K8S_STAGING_SERVER
- kubectl config set-credentials ci --token=$K8S_TOKEN
- kubectl config set-context staging --cluster=staging --user=ci
- kubectl config use-context staging
# Construir y desplegar con el perfil de staging
- skaffold run --profile staging --tag ${CI_COMMIT_SHORT_SHA}
only:
- develop
deploy-produccion:
stage: deploy
script:
- skaffold run --profile ci --tag ${CI_COMMIT_TAG}
only:
- tags
EOF
# Comandos útiles de Skaffold
# Iniciar en modo desarrollo con logs en tiempo real
skaffold dev --verbosity info
# Ver el estado del pipeline
skaffold run --dry-run
# Depurar con puertos de debug abiertos
skaffold debug
# Ver diagnósticos del entorno
skaffold diagnose
Solución de Problemas
# Ver logs detallados
skaffold dev --verbosity debug 2>&1 | head -100
# Forzar reconstrucción sin cache
skaffold dev --no-prune --cache-artifacts=false
# Verificar que las imágenes se construyen correctamente
skaffold build --dry-run
# Errores de contexto Docker: verificar el contexto actual
kubectl config current-context
# Ver los manifiestos que Skaffold generaría sin aplicarlos
skaffold render
# Problemas de sincronización de archivos
skaffold dev --verbosity debug 2>&1 | grep -i sync
Error "image not found" después del build:
# Verificar que la imagen se construyó correctamente
docker images | grep mi-app
# Si usas un registro remoto, verificar credenciales
docker login registry.empresa.com
kubectl create secret docker-registry regcred \
--docker-server=registry.empresa.com \
--docker-username=usuario \
--docker-password=contraseña
Conclusión
Skaffold elimina la fricción del desarrollo en Kubernetes automatizando completamente el ciclo de construcción y despliegue, permitiendo a los desarrolladores centrarse en el código en lugar de en los comandos de Docker y kubectl. La combinación de perfiles para diferentes entornos y la integración nativa con Helm, Kustomize y sistemas de CI/CD convierte a Skaffold en una herramienta imprescindible para cualquier equipo que trabaje con Kubernetes a diario.


