deploy-to-kubernetes
О программе
Этот навык Claude развертывает приложения в кластерах Kubernetes, используя манифесты kubectl и Helm-чарты для готовых к эксплуатации конфигураций. Он обрабатывает деплойменты, сервисы, конфигурации, а также реализует проверки работоспособности, ограничения ресурсов и rolling-обновления. Используйте его для развертывания в облачных или локальных K8s, миграции с Docker Compose или настройки мульти-средовых деплойментов.
Быстрая установка
Claude Code
Рекомендуетсяnpx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/deploy-to-kubernetesСкопируйте и вставьте эту команду в Claude Code для установки этого навыка
Документация
Deploy to Kubernetes
Containerized apps → K8s. Prod-ready: health checks, resource mgmt, auto rollouts.
Use When
- New apps → K8s (EKS, GKE, AKS, self-hosted)
- Compose/VMs → orchestration migrate
- Zero-downtime rolling updates + rollbacks
- Config + secrets mgmt
- Multi-env (dev, staging, prod)
- Reusable Helm charts
In
- Required: Cluster access (
kubectl cluster-info) - Required: Images in registry (Docker Hub, ECR, GCR, Harbor)
- Required: App reqs (ports, env vars, volumes)
- Optional: TLS certs → HTTPS ingress
- Optional: Persistent storage (StatefulSets, PVCs)
- Optional: Helm CLI
Do
See Extended Examples for complete configuration files and templates.
Step 1: Namespace + resource quotas
Orgs apps → namespaces w/ limits + 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
→ NS created w/ quotas. LimitRange sets defaults. SA least-priv RBAC.
If err: Quota → check nodes (kubectl describe nodes). RBAC → kubectl auth can-i create role --namespace myapp-prod. Rejected resources → kubectl describe.
Step 2: Secrets + ConfigMaps
Externalize config + sensitive data.
# 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
Complex → 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"
→ ConfigMaps → non-sensitive. Secrets → creds/keys. Pods read via env/volume. TLS → Ingress.
If err: Encoding → use stringData not data. TLS → openssl x509 -in tls.crt -text -noout. Access → SA RBAC. Decode → kubectl get secret myapp-secret -o jsonpath='{.data.api-key}' | base64 -d.
Step 3: Deployment w/ health + limits
Prod-ready w/ probes + resource mgmt.
# 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
Apply + monitor:
# 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
→ 3 replicas rolling. Readiness pre-traffic. Liveness restarts unhealthy. Limits prevent OOM. Logs show startup.
If err: ImagePullBackOff → image + imagePullSecret (kubectl get secret registry-credentials -o yaml). CrashLoopBackOff → kubectl logs pod-name --previous. Probe fail → port-forward + curl. OOMKilled → increase mem or find leaks.
Step 4: Expose via Service + LB
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: myapp-prod
# ... (see EXAMPLES.md for complete configuration)
Apply + test:
# Apply services
kubectl apply -f service.yaml
# Get service details
kubectl get svc -n myapp-prod
# ... (see EXAMPLES.md for complete configuration)
→ LB → external IP. ClusterIP → stable internal DNS. Endpoints = healthy pod IPs. Curl OK.
If err: LB pending → cloud integration + quotas. No endpoints → kubectl get pods --show-labels matches selector. Refused → targetPort matches container. Debug → kubectl port-forward bypass.
Step 5: HPA
Auto scale on CPU/mem/custom.
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
namespace: myapp-prod
# ... (see EXAMPLES.md for complete configuration)
Install metrics-server:
# 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)
→ HPA monitors. Scale up on threshold, down gradual. Metrics via kubectl top.
If err: "unknown" metrics → metrics-server running + pod requests defined. No scale → kubectl top pods vs target. Flapping → stabilizationWindowSeconds. Slow → reduce periodSeconds.
Step 6: Helm chart
Reusable, multi-env.
# Create Helm chart structure
helm create myapp-chart
cd myapp-chart
# Edit Chart.yaml
cat > Chart.yaml <<EOF
# ... (see EXAMPLES.md for complete configuration)
→ Chart packages all resources. Dry-run renders. Install orders. Upgrades roll. Rollback reverts.
If err: Template → helm template . local render. Dep → helm dependency update. Values → path in values.yaml. Inspect → helm get manifest myapp -n myapp-prod.
Check
- Pods Running + all ready
- Readiness pre-endpoints
- Liveness restarts unhealthy
- Reqs/limits prevent OOM + overcommit
- Secrets/ConfigMaps mounted
- Svcs DNS resolve (cluster.local)
- LB/Ingress external
- HPA scales up/down
- Rolling zero-downtime
- Logs → kubectl or centralized
Traps
- No readiness: Traffic before ready. Always readiness probes verify deps.
- Insufficient startup: Fast liveness kills slow apps. Use startupProbe w/ high failureThreshold.
- No resource limits: Unlimited CPU/mem → node instability. Always set reqs + limits.
- Hardcoded config: Env-specific in manifests → no reuse. ConfigMaps, Secrets, Helm values.
- Default SA: Unnecessary perms. Dedicated SA + minimal RBAC.
- No rolling strategy: Recreate all → downtime. RollingUpdate + maxUnavailable: 0.
- Secrets in VCS: Sensitive → Git. Sealed-secrets, external-secrets-operator, or vault.
- No PDB: Cluster maint drains → break. PodDisruptionBudget → min available.
→
setup-docker-compose— container fundamentals pre-K8scontainerize-mcp-server— images for deploywrite-helm-chart— advanced Helmmanage-kubernetes-secrets— SealedSecrets + external-secrets-operatorconfigure-ingress-networking— NGINX Ingress + cert-managerimplement-gitops-workflow— ArgoCD/Flux declarativesetup-container-registry— registry integration
GitHub репозиторий
Похожие навыки
executing-plans
ДизайнИспользуйте навык executing-plans, когда у вас есть полный план реализации для выполнения контролируемыми партиями с контрольными точками проверки. Он загружает и критически анализирует план, затем выполняет задачи небольшими партиями (по умолчанию 3 задачи), сообщая о прогрессе между каждой партией для проверки архитектором. Это обеспечивает систематическую реализацию со встроенными контрольными точками проверки качества.
requesting-code-review
ДизайнЭтот навык запускает суб-агента для ревью кода, который анализирует изменения в коде на соответствие требованиям перед дальнейшими действиями. Его следует использовать после завершения задач, реализации крупных функций или перед слиянием с основной веткой. Ревью помогает выявить проблемы на ранней стадии, сравнивая текущую реализацию с исходным планом.
connect-mcp-server
ДизайнЭтот навык предоставляет разработчикам подробное руководство по подключению серверов MCP к Claude Code с использованием транспортов HTTP, stdio или SSE. Он охватывает установку, конфигурацию, аутентификацию и безопасность для интеграции внешних сервисов, таких как GitHub, Notion и пользовательские API. Используйте его при настройке интеграций MCP, конфигурации внешних инструментов или работе с Model Context Protocol от Claude.
web-cli-teleport
ДизайнЭтот навык помогает разработчикам выбирать между веб-интерфейсом Claude Code и CLI на основе анализа задачи, а также обеспечивает бесшовное перемещение сессий между этими средами. Он оптимизирует рабочий процесс, управляя состоянием и контекстом сессии при переключении между веб-интерфейсом, CLI или мобильным приложением. Используйте его для сложных проектов, требующих различных инструментов на разных этапах работы.
