MCP HubMCP Hub
스킬 목록으로 돌아가기

deploy-to-kubernetes

pjt222
업데이트됨 2 days ago
8 조회
17
2
17
GitHub에서 보기
디자인data

정보

이 스킬은 프로덕션 환경에 적합한 설정을 위해 kubectl 매니페스트와 Helm 차트를 사용하여 애플리케이션을 Kubernetes 클러스터에 배포합니다. 배포, 서비스, 설정을 처리하며 헬스 체크, 리소스 제한, 점진적 롤아웃을 구현합니다. 클라우드 Kubernetes 서비스(EKS/GKE/AKS)에 배포하거나 Docker Compose에서 마이그레이션하거나, 다중 환경 배포를 관리할 때 사용하세요.

빠른 설치

Claude Code

추천
기본
npx skills add pjt222/agent-almanac -a claude-code
플러그인 명령대체
/plugin add https://github.com/pjt222/agent-almanac
Git 클론대체
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/deploy-to-kubernetes

Claude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서


name: deploy-to-kubernetes description: > Despliega aplicaciones en clústeres de Kubernetes usando manifiestos kubectl para Deployments, Services, ConfigMaps, Secrets y recursos Ingress. Implementa verificaciones de salud, límites de recursos, actualizaciones progresivas y empaquetado de charts Helm para despliegues en producción. Útil al desplegar nuevas aplicaciones en EKS, GKE, AKS o clústeres autohospedados, migrar de Docker Compose a orquestación de contenedores, implementar actualizaciones progresivas sin tiempo de inactividad, o configurar despliegues multientorno entre dev, staging y producción. locale: es source_locale: en source_commit: 6f65f316 translator: claude-opus-4-6 translation_date: 2026-03-16 license: MIT allowed-tools: Read Write Edit Bash Grep Glob metadata: author: Philipp Thoss version: "1.0" domain: devops complexity: intermediate language: multi tags: kubernetes, k8s, kubectl, deployment, service

Desplegar en Kubernetes

Despliega aplicaciones contenerizadas en Kubernetes con configuraciones listas para producción, incluyendo verificaciones de salud, gestión de recursos y despliegues automatizados.

Cuándo Usar

  • Al desplegar nuevas aplicaciones en clústeres de Kubernetes (EKS, GKE, AKS, autohospedados)
  • Al migrar de Docker Compose o VMs tradicionales a orquestación de contenedores
  • Al implementar actualizaciones progresivas sin tiempo de inactividad y reversiones
  • Al gestionar la configuración de aplicaciones y secretos en Kubernetes
  • Al configurar despliegues multientorno (dev, staging, producción)
  • Al crear charts Helm reutilizables para distribución de aplicaciones

Entradas

  • Requerido: Acceso al clúster de Kubernetes (kubectl cluster-info)
  • Requerido: Imágenes de contenedor subidas al registro (Docker Hub, ECR, GCR, Harbor)
  • Requerido: Requisitos de la aplicación (puertos, variables de entorno, volúmenes)
  • Opcional: Certificados TLS para ingress HTTPS
  • Opcional: Requisitos de almacenamiento persistente (StatefulSets, PVCs)
  • Opcional: CLI de Helm para despliegues basados en charts

Procedimiento

Consulta Ejemplos Extendidos para archivos de configuración completos y plantillas.

Paso 1: Crear Namespace y Cuotas de Recursos

Organiza las aplicaciones en namespaces con límites de recursos y RBAC.

# Create namespace
kubectl create namespace myapp-prod

# Apply resource quota
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: myapp-prod
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    persistentvolumeclaims: "5"
    services.loadbalancers: "2"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: myapp-prod
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    type: Container
EOF

# Create service account
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp
  namespace: myapp-prod
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myapp-role
  namespace: myapp-prod
rules:
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myapp-rolebinding
  namespace: myapp-prod
subjects:
- kind: ServiceAccount
  name: myapp
  namespace: myapp-prod
roleRef:
  kind: Role
  name: myapp-role
  apiGroup: rbac.authorization.k8s.io
EOF

# Verify namespace setup
kubectl get resourcequota -n myapp-prod
kubectl get limitrange -n myapp-prod
kubectl get sa -n myapp-prod

Esperado: Namespace creado con cuotas de recursos limitando el cómputo y el almacenamiento. LimitRange establece solicitudes y límites predeterminados de CPU/memoria. ServiceAccount configurado con RBAC de mínimo privilegio.

En caso de fallo: Para errores de cuota, verifica que el clúster tiene recursos suficientes con kubectl describe nodes. Para errores de RBAC, comprueba los permisos de cluster-admin con kubectl auth can-i create role --namespace myapp-prod. Usa kubectl describe en los recursos rechazados para ver las violaciones de cuota/límite.

Paso 2: Configurar Secretos y ConfigMaps de la Aplicación

Externaliza la configuración y los datos sensibles usando ConfigMaps y Secrets.

# Create ConfigMap from literal values
kubectl create configmap myapp-config \
  --namespace=myapp-prod \
  --from-literal=LOG_LEVEL=info \
  --from-literal=API_TIMEOUT=30s \
  --from-literal=FEATURE_FLAGS='{"newUI":true,"betaAPI":false}'

# Create ConfigMap from file
cat > app.properties <<EOF
database.pool.size=20
cache.ttl=3600
retry.attempts=3
EOF

kubectl create configmap myapp-properties \
  --namespace=myapp-prod \
  --from-file=app.properties

# Create Secret for database credentials
kubectl create secret generic myapp-db-secret \
  --namespace=myapp-prod \
  --from-literal=username=appuser \
  --from-literal=password='sup3rs3cr3t!' \
  --from-literal=connection-string='postgresql://db.example.com:5432/myapp'

# Create TLS secret for ingress
kubectl create secret tls myapp-tls \
  --namespace=myapp-prod \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key

# Verify secrets/configmaps
kubectl get configmap -n myapp-prod
kubectl get secret -n myapp-prod
kubectl describe configmap myapp-config -n myapp-prod

Para configuraciones más complejas, usa manifiestos YAML:

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
  namespace: myapp-prod
data:
  nginx.conf: |
    server {
      listen 8080;
      location / {
        proxy_pass http://backend:3000;
        proxy_set_header Host $host;
      }
    }
  app-config.json: |
    {
      "logLevel": "info",
      "features": {
        "authentication": true,
        "metrics": true
      }
    }
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: myapp-secret
  namespace: myapp-prod
type: Opaque
stringData:  # Automatically base64 encoded
  api-key: "sk-1234567890abcdef"
  jwt-secret: "my-jwt-signing-key"

Esperado: Los ConfigMaps almacenan configuración no sensible, los Secrets almacenan credenciales/claves. Los valores son accesibles para los Pods mediante variables de entorno o montajes de volumen. Los secrets TLS tienen el formato correcto para recursos Ingress.

En caso de fallo: Para problemas de codificación, usa stringData en lugar de data en YAML. Para errores de secret TLS, verifica el formato del certificado y la clave con openssl x509 -in tls.crt -text -noout. Para problemas de acceso, comprueba los permisos RBAC de la ServiceAccount. Muestra el secret decodificado con kubectl get secret myapp-secret -o jsonpath='{.data.api-key}' | base64 -d.

Paso 3: Crear Deployment con Verificaciones de Salud y Límites de Recursos

Despliega la aplicación con configuración lista para producción, incluyendo sondas y gestión de recursos.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: myapp-prod
  labels:
    app: myapp
    version: v1.0.0
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0  # Zero-downtime updates
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
        version: v1.0.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/metrics"
    spec:
      serviceAccountName: myapp
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
      containers:
      - name: myapp
        image: myregistry.io/myapp:v1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        env:
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: myapp-config
              key: LOG_LEVEL
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: myapp-db-secret
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: myapp-db-secret
              key: password
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        resources:
          requests:
            cpu: 250m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /healthz
            port: http
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: http
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 2
        startupProbe:
          httpGet:
            path: /healthz
            port: http
          initialDelaySeconds: 0
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 30  # 5 minutes for slow startup
        volumeMounts:
        - name: config
          mountPath: /etc/myapp
          readOnly: true
        - name: cache
          mountPath: /var/cache/myapp
      volumes:
      - name: config
        configMap:
          name: myapp-properties
      - name: cache
        emptyDir: {}
      imagePullSecrets:
      - name: registry-credentials

Aplica y monitorea el despliegue:

# Apply deployment
kubectl apply -f deployment.yaml

# Watch rollout status
kubectl rollout status deployment/myapp -n myapp-prod

# Check pod status
kubectl get pods -n myapp-prod -l app=myapp

# View pod logs
kubectl logs -n myapp-prod -l app=myapp --tail=50 -f

# Describe deployment for events
kubectl describe deployment myapp -n myapp-prod

# Check resource usage
kubectl top pods -n myapp-prod -l app=myapp

Esperado: El Deployment crea 3 réplicas con estrategia de actualización progresiva. Los Pods pasan las sondas de disponibilidad antes de recibir tráfico. Las sondas de vida reinician los pods no saludables. Las solicitudes/límites de recursos previenen los OOM kills. Los registros muestran un inicio exitoso de la aplicación.

En caso de fallo: Para ImagePullBackOff, verifica que la imagen existe y que imagePullSecret es válido con kubectl get secret registry-credentials -o yaml. Para CrashLoopBackOff, comprueba los registros con kubectl logs pod-name --previous. Para fallos de sonda, prueba los endpoints manualmente con kubectl port-forward y curl localhost:8080/healthz. Para pods OOMKilled, aumenta los límites de memoria o investiga las fugas de memoria.

Paso 4: Exponer la Aplicación con Services y Balanceadores de Carga

Crea recursos Service para exponer aplicaciones interna y externamente.

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: myapp-prod
# ... (see EXAMPLES.md for complete configuration)

Aplica y prueba los servicios:

# Apply services
kubectl apply -f service.yaml

# Get service details
kubectl get svc -n myapp-prod

# ... (see EXAMPLES.md for complete configuration)

Esperado: El Service LoadBalancer aprovisiona un LB externo con IP/hostname público. El Service ClusterIP proporciona DNS interno estable. La lista de endpoints muestra las IPs de Pods saludables. Las solicitudes curl tienen éxito con las respuestas esperadas.

En caso de fallo: Para LoadBalancer pendiente, comprueba la integración del proveedor de nube y las cuotas. Para ausencia de endpoints, verifica que las etiquetas del Pod coinciden con el selector del Service con kubectl get pods --show-labels. Para conexión rechazada, verifica que targetPort coincide con el puerto del contenedor. Usa kubectl port-forward para omitir la capa Service al depurar.

Paso 5: Configurar el Escalado Automático Horizontal de Pods

Implementa escalado automático basado en CPU/memoria o métricas personalizadas.

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  namespace: myapp-prod
# ... (see EXAMPLES.md for complete configuration)

Instala metrics-server si no está disponible:

# Install metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# Verify metrics-server
kubectl get deployment metrics-server -n kube-system
kubectl top nodes
# ... (see EXAMPLES.md for complete configuration)

Esperado: HPA monitorea las métricas de CPU/memoria. Cuando se superan los umbrales, las réplicas escalan hasta maxReplicas. Cuando la carga disminuye, las réplicas se reducen gradualmente (la ventana de estabilización previene el aleteo). Las métricas son visibles con kubectl top.

En caso de fallo: Para métricas "unknown", verifica que metrics-server está en ejecución y que los Pods tienen solicitudes de recursos definidas. Para ausencia de escalado, comprueba que la utilización actual supera los objetivos con kubectl top pods. Para aleteo, aumenta stabilizationWindowSeconds. Para escalado lento, reduce periodSeconds en las políticas de scaleUp.

Paso 6: Empaquetar la Aplicación con un Chart Helm

Crea un chart Helm reutilizable para despliegues multientorno.

# Create Helm chart structure
helm create myapp-chart
cd myapp-chart

# Edit Chart.yaml
cat > Chart.yaml <<EOF
# ... (see EXAMPLES.md for complete configuration)

Esperado: El chart Helm empaqueta todos los recursos de Kubernetes con valores con plantilla. El dry-run muestra los manifiestos renderizados. La instalación despliega todos los recursos en el orden correcto. Las actualizaciones realizan actualizaciones progresivas. La reversión vuelve a la revisión anterior.

En caso de fallo: Para errores de plantilla, ejecuta helm template . para renderizar localmente sin instalar. Para problemas de dependencias, ejecuta helm dependency update. Para fallos de anulación de valores, verifica que la ruta YAML existe en values.yaml. Usa helm get manifest myapp -n myapp-prod para ver los recursos desplegados reales.

Validación

  • Pods en estado Running con todos los contenedores listos
  • Las sondas de disponibilidad pasan antes de que los Pods se agreguen a los endpoints del Service
  • Las sondas de vida reinician automáticamente los contenedores no saludables
  • Las solicitudes y límites de recursos previenen los OOM kills y el sobrecompromiso del nodo
  • Los Secrets y ConfigMaps están montados correctamente con los valores esperados
  • Los Services se resuelven vía DNS (cluster.local) desde otros Pods
  • LoadBalancer/Ingress es accesible desde redes externas
  • HPA escala las réplicas hacia arriba bajo carga y hacia abajo cuando está inactivo
  • Las actualizaciones progresivas se completan sin tiempo de inactividad
  • Los registros se recopilan y son accesibles vía kubectl logs o registro centralizado

Errores Comunes

  • Sondas de disponibilidad faltantes: Los Pods reciben tráfico antes de iniciarse completamente. Siempre implementa sondas de disponibilidad que verifiquen las dependencias de la aplicación.

  • Tiempo de inicio insuficiente: Las sondas de vida rápidas matan las aplicaciones de inicio lento. Usa startupProbe con un failureThreshold generoso para la inicialización.

  • Sin límites de recursos: Los Pods consumen CPU/memoria ilimitada causando inestabilidad del nodo. Siempre establece solicitudes y límites.

  • Configuración codificada: Los valores específicos del entorno en los manifiestos impiden la reutilización. Usa ConfigMaps, Secrets y valores de Helm.

  • Cuenta de servicio predeterminada: Los Pods tienen permisos de clúster innecesarios. Crea ServiceAccounts dedicados con RBAC mínimo.

  • Sin estrategia de actualización progresiva: Los Deployments recrean todos los Pods simultáneamente causando tiempo de inactividad. Usa RollingUpdate con maxUnavailable: 0.

  • Secretos en control de versiones: Datos sensibles confirmados en Git. Usa sealed-secrets, external-secrets-operator o vault.

  • Sin presupuesto de interrupción de pods: El mantenimiento del clúster drena nodos y rompe el servicio. Crea PodDisruptionBudget para garantizar réplicas disponibles mínimas.

Habilidades Relacionadas

  • setup-docker-compose - Fundamentos de orquestación de contenedores antes de Kubernetes
  • containerize-mcp-server - Creación de imágenes de contenedor para el despliegue
  • write-helm-chart - Desarrollo avanzado de charts Helm
  • manage-kubernetes-secrets - SealedSecrets y external-secrets-operator
  • configure-ingress-networking - Configuración de NGINX Ingress y cert-manager
  • implement-gitops-workflow - ArgoCD/Flux para despliegues declarativos
  • setup-container-registry - Integración del registro de imágenes

GitHub 저장소

pjt222/agent-almanac
경로: i18n/es/skills/deploy-to-kubernetes
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

executing-plans

디자인

executing-plans 스킬은 검토 체크포인트가 포함된 통제된 배치로 실행할 완전한 구현 계획이 있을 때 사용합니다. 이 스킬은 계획을 불러와 비판적으로 검토한 후, 소규모 배치(기본값 3개 작업)로 작업을 실행하면서 각 배치 사이에 진행 상황을 아키텍트 검토를 위해 보고합니다. 이를 통해 내재된 품질 관리 체크포인트를 갖춘 체계적인 구현이 보장됩니다.

스킬 보기

requesting-code-review

디자인

이 스킬은 코드 변경 사항을 요구 사항에 따라 분석하기 위해 코드 리뷰어 하위 에이전트를 호출합니다. 작업 완료 후, 주요 기능 구현 후, 또는 메인 브랜치에 병합하기 전에 사용해야 합니다. 이 리뷰는 현재 구현체와 원래 계획을 비교하여 문제를 조기에 발견하는 데 도움이 됩니다.

스킬 보기

connect-mcp-server

디자인

이 스킬은 개발자들이 HTTP, stdio 또는 SSE 전송 방식을 통해 MCP 서버를 Claude Code에 연결하는 포괄적인 가이드를 제공합니다. GitHub, Notion 및 사용자 정의 API와 같은 외부 서비스를 통합하기 위한 설치, 구성, 인증 및 보안을 다룹니다. MCP 통합 설정, 외부 도구 구성 또는 Claude의 모델 컨텍스트 프로토콜 작업 시 활용하세요.

스킬 보기

web-cli-teleport

디자인

이 스킬은 작업 분석을 기반으로 개발자가 Claude Code 웹 인터페이스와 CLI 인터페이스 중 선택할 수 있도록 돕고, 두 환경 간 원활한 세션 텔레포트를 가능하게 합니다. 웹, CLI 또는 모바일 환경 전환 시 세션 상태와 컨텍스트를 관리하여 워크플로를 최적화합니다. 다양한 단계에서 서로 다른 도구가 필요한 복잡한 프로젝트에 사용하세요.

스킬 보기