Kubernetes Deployment Guide for GKE
Overview
Production-ready Kubernetes manifests for deploying CODITECT Dev Context v2.0 to Google Kubernetes Engine (GKE).
Architecture:
- Django REST API backend with gunicorn
- PostgreSQL 15 (Cloud SQL with Cloud SQL Proxy sidecar)
- Redis for caching and Celery broker
- HTTPS with Google-managed SSL certificates
- Horizontal auto-scaling (3-20 pods)
- Multi-tenant support with row-level security
Prerequisites
Required Tools
gcloudCLI (v450.0.0+)kubectl(v1.28+)- Docker (for building images)
- GCP project with billing enabled
Required GCP APIs
Enable these APIs in your GCP project:
gcloud services enable \
container.googleapis.com \
sqladmin.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
secretmanager.googleapis.com \
storage-api.googleapis.com
Quick Start (15 minutes)
1. Set Environment Variables
export PROJECT_ID="your-gcp-project-id"
export REGION="us-central1"
export CLUSTER_NAME="coditect-gke-cluster"
export DB_INSTANCE="coditect-postgres"
2. Create GKE Cluster
gcloud container clusters create $CLUSTER_NAME \
--project=$PROJECT_ID \
--region=$REGION \
--num-nodes=3 \
--machine-type=n1-standard-2 \
--enable-autoscaling \
--min-nodes=3 \
--max-nodes=10 \
--enable-autorepair \
--enable-autoupgrade \
--enable-stackdriver-kubernetes \
--workload-pool=$PROJECT_ID.svc.id.goog \
--addons=HttpLoadBalancing,HorizontalPodAutoscaling
3. Configure kubectl
gcloud container clusters get-credentials $CLUSTER_NAME \
--region=$REGION \
--project=$PROJECT_ID
4. Create Cloud SQL Instance
gcloud sql instances create $DB_INSTANCE \
--project=$PROJECT_ID \
--database-version=POSTGRES_15 \
--tier=db-f1-micro \
--region=$REGION \
--root-password=$(openssl rand -base64 32)
5. Build and Push Docker Image
# Build production image
docker build -f dockerfile.production \
-t gcr.io/$PROJECT_ID/coditect-backend:2.0.0 .
# Push to Google Container Registry
docker push gcr.io/$PROJECT_ID/coditect-backend:2.0.0
6. Update Manifests
Edit these files and replace placeholders:
-
04-deployment.yaml:PROJECT_ID→ Your GCP project IDREGION→ Your Cloud SQL regionINSTANCE_NAME→ Your Cloud SQL instance name
-
06-ingress.yaml:- Reserve static IP first (see below)
7. Create Secrets in Google Secret Manager
# Django secret key
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())' | \
gcloud secrets create django-secret-key --data-file=-
# Database password
gcloud sql users set-password postgres \
--instance=$DB_INSTANCE \
--password=$(openssl rand -base64 32)
# Store DB password in Secret Manager
gcloud sql users describe postgres --instance=$DB_INSTANCE | \
grep password | awk '{print $2}' | \
gcloud secrets create db-password --data-file=-
8. Reserve Static IP
gcloud compute addresses create coditect-backend-ip --global
gcloud compute addresses describe coditect-backend-ip --global
9. Deploy to GKE
kubectl apply -f k8s/01-namespace.yaml
kubectl apply -f k8s/02-configmap.yaml
kubectl apply -f k8s/03-secrets.yaml
kubectl apply -f k8s/04-deployment.yaml
kubectl apply -f k8s/05-service.yaml
kubectl apply -f k8s/06-ingress.yaml
kubectl apply -f k8s/07-hpa.yaml
10. Run Database Migrations
# Get a pod name
POD=$(kubectl get pods -n coditect-dev-context -l app=coditect-backend -o jsonpath='{.items[0].metadata.name}')
# Run migrations
kubectl exec -it $POD -n coditect-dev-context -- python manage.py migrate
# Create superuser
kubectl exec -it $POD -n coditect-dev-context -- python manage.py createsuperuser
11. Configure DNS
Point your domain to the static IP:
# Get IP address
gcloud compute addresses describe coditect-backend-ip --global --format="value(address)"
# In your DNS provider, create:
# A Record: api.coditect.ai → <STATIC_IP>
# A Record: *.coditect.ai → <STATIC_IP>
12. Wait for SSL Certificate
# Check certificate status
kubectl describe managedcertificate coditect-ssl-cert -n coditect-dev-context
# This can take 5-20 minutes
13. Verify Deployment
# Check pods
kubectl get pods -n coditect-dev-context
# Check service
kubectl get svc -n coditect-dev-context
# Check ingress
kubectl get ingress -n coditect-dev-context
# Test API
curl https://api.coditect.ai/health/
Manifest Files
| File | Description |
|---|---|
01-namespace.yaml | Isolated namespace for all resources |
02-configmap.yaml | Non-sensitive configuration |
03-secrets.yaml | Sensitive credentials (use Secret Manager) |
04-deployment.yaml | Main application deployment with Cloud SQL Proxy |
05-service.yaml | Internal load balancer |
06-ingress.yaml | External HTTPS access with SSL |
07-hpa.yaml | Horizontal pod autoscaler |
Monitoring & Operations
View Logs
# All pods
kubectl logs -f -n coditect-dev-context -l app=coditect-backend
# Specific pod
kubectl logs -f POD_NAME -n coditect-dev-context
# Cloud SQL Proxy logs
kubectl logs POD_NAME -n coditect-dev-context -c cloud-sql-proxy
Shell Access
kubectl exec -it POD_NAME -n coditect-dev-context -- /bin/bash
Database Access
# Via Cloud SQL Proxy in pod
kubectl exec -it POD_NAME -n coditect-dev-context -- \
psql -h 127.0.0.1 -U postgres -d coditect_dev_context
Scale Manually
# Scale to 5 replicas
kubectl scale deployment coditect-backend \
-n coditect-dev-context \
--replicas=5
Update Deployment
# Build new image
docker build -f dockerfile.production -t gcr.io/$PROJECT_ID/coditect-backend:2.0.1 .
docker push gcr.io/$PROJECT_ID/coditect-backend:2.0.1
# Update deployment
kubectl set image deployment/coditect-backend \
backend=gcr.io/$PROJECT_ID/coditect-backend:2.0.1 \
-n coditect-dev-context
# Watch rollout
kubectl rollout status deployment/coditect-backend -n coditect-dev-context
Rollback Deployment
# View rollout history
kubectl rollout history deployment/coditect-backend -n coditect-dev-context
# Rollback to previous version
kubectl rollout undo deployment/coditect-backend -n coditect-dev-context
# Rollback to specific revision
kubectl rollout undo deployment/coditect-backend \
-n coditect-dev-context \
--to-revision=2
Security Best Practices
1. Use Workload Identity
Enable Workload Identity for secure GCP service account access:
# Create GCP service account
gcloud iam service-accounts create coditect-backend \
--display-name="CODITECT Backend Service Account"
# Bind to Kubernetes service account
gcloud iam service-accounts add-iam-policy-binding \
coditect-backend@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:$PROJECT_ID.svc.id.goog[coditect-dev-context/coditect-backend-sa]"
# Grant necessary permissions
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:coditect-backend@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:coditect-backend@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:coditect-backend@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/storage.admin"
2. Enable Cloud Armor
DDoS protection and rate limiting:
gcloud compute security-policies create coditect-armor-policy \
--description="DDoS protection for CODITECT"
# Rate limiting rule
gcloud compute security-policies rules create 1000 \
--security-policy=coditect-armor-policy \
--expression="true" \
--action="rate-based-ban" \
--rate-limit-threshold-count=100 \
--rate-limit-threshold-interval-sec=60 \
--ban-duration-sec=600
3. Network Policies
Restrict pod-to-pod communication (optional):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: coditect-backend-netpol
namespace: coditect-dev-context
spec:
podSelector:
matchLabels:
app: coditect-backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8000
Cost Optimization
Right-Size Resources
Monitor actual usage and adjust:
# View resource usage
kubectl top pods -n coditect-dev-context
kubectl top nodes
# Update resource requests/limits in 04-deployment.yaml
Use Preemptible Nodes
For non-critical workloads:
gcloud container node-pools create preemptible-pool \
--cluster=$CLUSTER_NAME \
--region=$REGION \
--preemptible \
--num-nodes=2 \
--machine-type=n1-standard-2
Cleanup Unused Resources
# Delete unused images
gcloud container images list --repository=gcr.io/$PROJECT_ID
gcloud container images delete gcr.io/$PROJECT_ID/coditect-backend:old-tag
Troubleshooting
Pods Not Starting
# Check pod events
kubectl describe pod POD_NAME -n coditect-dev-context
# Common issues:
# - Image pull errors → Check GCR permissions
# - CrashLoopBackOff → Check logs
# - Pending state → Insufficient cluster resources
Database Connection Failures
# Check Cloud SQL Proxy logs
kubectl logs POD_NAME -n coditect-dev-context -c cloud-sql-proxy
# Verify Cloud SQL instance is running
gcloud sql instances describe $DB_INSTANCE
# Check firewall rules
gcloud compute firewall-rules list
SSL Certificate Not Provisioning
# Check certificate status
kubectl describe managedcertificate coditect-ssl-cert -n coditect-dev-context
# Verify DNS is pointing to static IP
dig api.coditect.ai
# Certificate provisioning can take up to 20 minutes
Production Readiness Checklist
- GKE cluster created with autoscaling
- Cloud SQL instance provisioned
- Static IP reserved and DNS configured
- Secrets stored in Google Secret Manager
- Workload Identity configured
- Docker image built and pushed
- All manifests applied
- Database migrations run
- SSL certificate provisioned
- API health check passing
- Monitoring and logging configured
- Backup strategy implemented
- Disaster recovery plan documented
- Load testing completed
- Security scan passed
Version: 2.0.0 Last Updated: 2025-11-26 Maintainer: AZ1.AI Development Team