Despliegue de Swift en Kubernetes: desde la compilación local hasta el clúster de producción
\nSwift no es solo un lenguaje para iOS y macOS. Gracias a frameworks como Vapor y Kitura, Swift se utiliza cada vez más para escribir aplicaciones de servidor. Pero, ¿cómo entregar dicha aplicación a los usuarios? La respuesta es Kubernetes. En esta guía, veremos cómo empaquetar una aplicación Swift en Docker, configurar CI/CD y desplegarla en un clúster K8s. Aprenderá qué matices existen al compilar Swift en Linux, cómo optimizar la imagen y cómo escribir los manifiestos correctos para Kubernetes.
\n\n1. Preparación de la aplicación Swift para la contenerización
\nLo primero que enfrenta un desarrollador es Swift en Linux. Si escribe en macOS, necesita compilar de forma cruzada la aplicación para Linux (amd64/arm64). Consideremos un ejemplo basado en Vapor 4.
\nCreemos una aplicación HTTP simple:
\n// Sources/App/routes.swift\nimport Vapor\n\nfunc routes(_ app: Application) throws {\n app.get { req async in\n "¡Hola desde Swift en Kubernetes!"\n }\n app.get("health") { req async in\n "OK"\n }\n}\n\nPara compilar en Linux, usamos la imagen oficial de Swift. Creemos un Dockerfile con compilación en dos etapas:
# Primera etapa: compilación\nFROM swift:5.9-focal as builder\nWORKDIR /app\nCOPY Package.swift Package.resolved ./\nRUN swift package resolve\nCOPY . .\nRUN swift build -c release --static-swift-stdlib\n\n# Segunda etapa: imagen mínima\nFROM ubuntu:22.04\nRUN apt-get update && apt-get install -y ca-certificates libsqlite3-0 && rm -rf /var/lib/apt/lists/*\nWORKDIR /app\nCOPY --from=builder /app/.build/release/Run .\nEXPOSE 8080\nCMD ["./Run"]\n\nEl punto clave es la bandera --static-swift-stdlib. Esta incluye el enlace estático de la biblioteca estándar de Swift, lo que reduce el tamaño de la imagen y simplifica el despliegue. Sin ella, la imagen puede pesar 1+ GB.
2. Compilación de la imagen y carga en el registro
\nCompilamos la imagen y la subimos a Docker Hub (o cualquier otro registro):
\n# Compilación\ndocker build -t myrepo/swift-k8s-demo:1.0.0 .\n\n# Verificación local\ndocker run -p 8080:8080 myrepo/swift-k8s-demo:1.0.0\ncurl http://localhost:8080\n# Respuesta: ¡Hola desde Swift en Kubernetes!\n\n# Subida al registro\ndocker push myrepo/swift-k8s-demo:1.0.0\n\nOptimización de tamaño: la imagen basada en ubuntu:22.04 pesa ~150 MB. Si se usa alpine, se puede reducir a 50 MB, pero habrá que resolver el problema con glibc (Swift lo requiere). Se recomienda usar imágenes oficiales de Ubuntu o Debian.
3. Manifiestos de Kubernetes para la aplicación Swift
\nAhora despleguemos nuestra aplicación en el clúster. Crearemos un Deployment y un Service.
\ndeployment.yaml:
\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: swift-app\n labels:\n app: swift-app\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: swift-app\n template:\n metadata:\n labels:\n app: swift-app\n spec:\n containers:\n - name: swift-app\n image: myrepo/swift-k8s-demo:1.0.0\n ports:\n - containerPort: 8080\n livenessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 10\n readinessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 3\n periodSeconds: 5\n resources:\n requests:\n memory: "64Mi"\n cpu: "100m"\n limits:\n memory: "128Mi"\n cpu: "250m"\n\nservice.yaml:
\napiVersion: v1\nkind: Service\nmetadata:\n name: swift-app-service\nspec:\n selector:\n app: swift-app\n ports:\n - protocol: TCP\n port: 80\n targetPort: 8080\n type: ClusterIP\n\nPreste atención a las probes (sondeos).