Rainbow Deploys: Infinite Colors for K8s Long-Draining Services

Shift Kubernetes Service selectors to new git-colored Deployments for zero-downtime deploys on stateful, long-connection services—old pods drain naturally without restarts.

Core Technique: Selector Shifts Without Pod Disruption

Rainbow deploys extend blue/green by using infinite "colors" (first 6 hex chars of git HEAD) as Deployment labels matched by Service selectors. Deploy new versions by creating fresh Deployments with unique colors, then update the Service selector to point only to the new pods. Old Deployments persist, allowing TCP/HTTP connections to drain over time (e.g., minutes or hours) until clients close them or you delete the old Deployment. This avoids rolling updates that kill long-lived connections abruptly.

Key Kubernetes config in app.yaml:

  • Deployment has color: __COLOR__ label.
  • Service selector matches app: rainbow-deploys, color: __COLOR__. make install runs cat app.yaml | sed s/__COLOR__/$(COLOR)/g | kubectl apply -f -, where COLOR derives from git HEAD, repointing the Service instantly while old pods handle draining traffic.

Trade-off: Old Deployments accumulate (e.g., rainbow-deploys-3c3fdc, rainbow-deploys-9d2cc9), requiring manual cleanup via kubectl delete deployment <old-name> to reclaim resources.

Demo Setup and Validation

Repo includes Go app (main.go) serving:

  • HTTP on :8080: Returns hex color of git HEAD at build time.
  • TCP on :8081: Prints color every 5 seconds indefinitely.

Prerequisites: minikube, Docker env setup. Commands:

  1. minikube start; eval $(minikube docker-env); export DOCKER_IMAGE=your-image; make image; make install → Creates rainbow-deploys-<color> Deployment (2 replicas), NodePort Service (8080→31080, 8081→31081).
  2. Access: minikube service rainbow-deploys → http://:31080 shows color; telnet <ip> 31081 streams color.
  3. Rebuild/deploy: make image; make install → New Deployment appears, Service shifts (old connections on TCP continue printing old color).
  4. kubectl get deployments shows both; delete older after drain: kubectl delete deployment rainbow-deploys-3c3fdc.

Dockerfile, Makefile, app.yaml provided for direct replication; LICENSE is MIT.

When to Use: Handling Stateful Realities

Ideal for services with long-running TCP (e.g., WebSockets, streaming) or in-memory state where restarts lose connections. Contrasts stateless short-cycle services fine with standard rolling updates. See author's 2018 blog for production cases avoiding backend restarts.

Summarized by x-ai/grok-4.1-fast via openrouter

5066 input / 1483 output tokens in 9039ms

© 2026 Edge