Deploy and manage applications on Kubernetes with production best practices
Deploy and manage containerized applications on Kubernetes with production best practices for high availability, security, and scalability.
For Hanzo/Lux services this generic skill is background knowledge only — deployment is prescribed by HIP-0117 (one binary, three modes) and the operator. See skills/hanzo-cloud-architecture/SKILL.md.
cloud serve — single process, NO Kubernetes. The whole cloud(IAM, KMS, o11y, tasks, console, ...) in one binary with per-tenant SQLite. This is local dev and single-node/edge production.
cloud cluster init — the binary fetches k3s, bootstraps the cluster, installs the operator, and hands reconciliation to services.hanzo.ai CRs. Devs do NOT hand-write Deployments; the operator reconciles CRs. (Decided per HIP-0117; staged.)
helm install cloud ./helm/cloud — BYO Kubernetes, same image.Rules that override the generic advice below:
services.hanzo.ai CR (or universe manifests), never by kubectl create deployment.
our runners); GitHub is the OSS mirror. Never build images locally.
ghcr.io/hanzoai/ (Hanzo) / ghcr.io/luxfi/ (Lux) — never mix.hanzoai/ingress — no nginx, no caddy.providers (BYO provider).
This skill covers Kubernetes deployment strategies, including:
Workloads:
Services:
Configuration:
Security:
Rolling Update (Default):
Recreate:
Canary:
Blue-Green:
# From command line
kubectl create deployment web --image=nginx:1.25 --replicas=3
# From YAML
kubectl apply -f deployment.yaml
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
# Create service
kubectl expose deployment web --port=80 --type=LoadBalancer
# From YAML
kubectl apply -f service.yaml
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: LoadBalancer
# Update image
kubectl set image deployment/web nginx=nginx:1.26
# Edit deployment
kubectl edit deployment/web
# Apply changes from file
kubectl apply -f deployment.yaml
# Monitor rollout
kubectl rollout status deployment/web
# View history
kubectl rollout history deployment/web
# Rollback to previous version
kubectl rollout undo deployment/web
# Rollback to specific revision
kubectl rollout undo deployment/web --to-revision=2
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
labels:
app: api
version: v1
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
version: v1
spec:
serviceAccountName: api
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- api
topologyKey: kubernetes.io/hostname
containers:
- name: api
image: myapp/api:v1.0.0
ports:
- name: http
containerPort: 8080
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: api-config
key: db.host
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: api-secrets
key: db.password
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2
memory: 2Gi
startupProbe:
httpGet:
path: /healthz/startup
port: http
periodSeconds: 10
failureThreshold: 30
livenessProbe:
httpGet:
path: /healthz/live
port: http
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz/ready
port: http
periodSeconds: 5
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
data:
db.host: "postgres.default.svc.cluster.local"
db.port: "5432"
app.yaml: |
server:
port: 8080
timeout: 30s
---
# Secret
# ❌ BAD: Hardcoded credentials - example only, never do this in production
# In production, use sealed-secrets, external-secrets-operator, or your cloud provider's secret management
apiVersion: v1
kind: Secret
metadata:
name: api-secrets
type: Opaque
stringData:
db.password: "changeme123" # Example only - use secret management in production
api.key: "secret-api-key" # Example only - use secret management in production
# Get resources
kubectl get deployments
kubectl get pods
kubectl get services
kubectl get all
# Describe resource
kubectl describe deployment web
kubectl describe pod web-abc123
# View logs
kubectl logs deployment/web
kubectl logs -f pod/web-abc123 # Follow logs
kubectl logs pod/web-abc123 --previous # Previous container
# Execute commands in pod
kubectl exec -it pod/web-abc123 -- /bin/sh
# Port forwarding
kubectl port-forward deployment/web 8080:80
# Scale deployment
kubectl scale deployment/web --replicas=5
# Delete resources
kubectl delete deployment web
kubectl delete -f deployment.yaml
# Check pod status
kubectl get pods
kubectl describe pod <pod-name>
# Common issues:
# - ImagePullBackOff: Check image name and registry credentials
# - CrashLoopBackOff: Check logs for application errors
# - Pending: Check resource availability and node constraints
# View events
kubectl get events --sort-by='.lastTimestamp'
# Check logs
kubectl logs <pod-name>
# Check service and endpoints
kubectl get service web
kubectl get endpoints web
# Test DNS
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup web
# Test connectivity
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- curl http://web
# Check rollout status
kubectl rollout status deployment/web
# View deployment events
kubectl describe deployment web
# Check replica sets
kubectl get rs -l app=web
# Pause and resume
kubectl rollout pause deployment/web
kubectl rollout resume deployment/web
containers-docker: Container fundamentalscloud-aws-eks: AWS Kubernetes servicecloud-gcp-gke: Google Kubernetes Engineobservability-prometheus: Metrics collectioncicd-github-actions: CI/CD automationinfrastructure-terraform: Infrastructure as CodeComprehensive resources for Kubernetes deployment are available in the resources/ directory:
resources/REFERENCE.md (1,800+ lines) Complete reference covering:
resources/scripts/validate_manifests.py Validate Kubernetes YAML manifests for correctness and best practices:
# Validate single file
./validate_manifests.py deployment.yaml
# Validate directory
./validate_manifests.py --strict manifests/
# JSON output
./validate_manifests.py --json deployment.yaml
resources/scripts/analyze_deployment.py Analyze deployments for issues and optimization opportunities:
# Analyze file
./analyze_deployment.py deployment.yaml
# Analyze live cluster
./analyze_deployment.py --cluster --namespace production
# JSON output
./analyze_deployment.py --json --cluster
resources/scripts/test_deployment.sh Test deployments in local Kubernetes cluster:
# Test with kind
./test_deployment.sh deployment.yaml
# Test with minikube
./test_deployment.sh --provider minikube manifests/
# Keep cluster for debugging
./test_deployment.sh --no-cleanup deployment.yaml
resources/examples/manifests/basic-deployment/ Simple deployment example:
resources/examples/manifests/production-deployment/ Production-ready deployment:
resources/examples/helm/sample-chart/ Complete Helm chart structure:
resources/examples/kustomize/ Kustomize overlays for environments:
base/: Base manifestsoverlays/dev/: Development environment customizationsoverlays/prod/: Production environment customizationsresources/examples/cicd/github-actions-deploy.yml Complete GitHub Actions workflow: