Gateway on Kubernetes — Deploying API Gateways in Container Orchestration
In this tutorial, you'll learn about Gateway Kubernetes. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Deploying an API Gateway on Kubernetes provides automatic scaling, self-healing, rolling updates, and service discovery, making it the ideal platform for production gateway deployments.
What You'll Learn
By the end of this lesson, you will create Kubernetes Deployment and Service manifests for the gateway, configure ConfigMaps and Secrets, set up Horizontal Pod Autoscaler, and implement zero-downtime rolling updates.
Why It Matters
Kubernetes automates the operational overhead of running gateway instances, allowing you to focus on configuration and optimization rather than infrastructure management.
Real-World Use
Durga Antivirus Pro runs its gateway on Kubernetes with 5 replicas, auto-scaling to 20 during peak hours, and rolling updates that replace instances without dropping connections.
Kubernetes Gateway Architecture
flowchart TD
Internet-->Ingress[Kubernetes Ingress]
Ingress-->Service[Gateway Service]
Service-->Pod1[Gateway Pod 1]
Service-->Pod2[Gateway Pod 2]
Service-->Pod3[Gateway Pod 3]
Pod1-->Config[ConfigMap]
Pod2-->Config
Pod3-->Config
Pod1-->HPA[Horizontal Pod Autoscaler]
Pod2-->HPA
Pod3-->HPA
Deployment Manifest
Create a Kubernetes Deployment for the gateway.
from typing import Dict, List, Optional
import json
class K8sDeployment:
def __init__(self, name: str, image: str,
replicas: int = 3,
namespace: str = "default"):
self.name = name
self.image = image
self.replicas = replicas
self.namespace = namespace
self.env_vars: Dict[str, str] = {}
self.ports: List[Dict] = []
self.resources: Dict = {}
self.probes: Dict = {}
self.config_maps: List[str] = []
self.secrets: List[str] = []
def add_env(self, key: str, value: str):
self.env_vars[key] = value
def add_port(self, container_port: int,
name: str = "http"):
self.ports.append({
"containerPort": container_port,
"name": name
})
def set_resources(self, requests: Dict,
limits: Dict):
self.resources = {
"requests": requests,
"limits": limits
}
def set_health_probe(self, path: str,
port: int = 8080,
delay: int = 5):
self.probes = {
"livenessProbe": {
"httpGet": {"path": path, "port": port},
"initialDelaySeconds": delay,
},
"readinessProbe": {
"httpGet": {"path": path, "port": port},
"initialDelaySeconds": delay,
}
}
def use_config_map(self, name: str):
self.config_maps.append(name)
def use_secret(self, name: str):
self.secrets.append(name)
def to_yaml(self) -> str:
spec = {
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": self.name,
"namespace": self.namespace,
"labels": {"app": self.name}
},
"spec": {
"replicas": self.replicas,
"selector": {
"matchLabels": {"app": self.name}
},
"template": {
"metadata": {
"labels": {"app": self.name}
},
"spec": {
"containers": [{
"name": self.name,
"image": self.image,
"ports": self.ports,
}]
}
}
}
}
container = spec["spec"]["template"][
"spec"]["containers"][0]
if self.env_vars:
container["env"] = [
{"name": k, "value": v}
for k, v in self.env_vars.items()
]
if self.resources:
container["resources"] = self.resources
if self.probes:
container.update(self.probes)
if self.config_maps:
container["envFrom"] = [
{"configMapRef": {"name": cm}}
for cm in self.config_maps
]
if self.secrets:
container["envFrom"].extend([
{"secretRef": {"name": sec}}
for sec in self.secrets
])
import yaml
return yaml.dump(spec, default_flow_style=False)
dep = K8sDeployment("api-gateway",
"dodatech/gateway:1.0.0",
replicas=3)
dep.add_port(8080)
dep.set_resources(
{"cpu": "500m", "memory": "512Mi"},
{"cpu": "2000m", "memory": "2Gi"}
)
dep.set_health_probe("/health")
dep.add_env("REDIS_URL", "redis://redis-svc:6379")
dep.use_config_map("gateway-config")
print(dep.to_yaml())
Horizontal Pod Autoscaler
Configure auto-scaling based on CPU and memory.
from typing import Dict, Optional
class K8sHPA:
def __init__(self, name: str,
deployment: str,
min_replicas: int = 3,
max_replicas: int = 50,
namespace: str = "default"):
self.name = name
self.deployment = deployment
self.min_replicas = min_replicas
self.max_replicas = max_replicas
self.namespace = namespace
self.metrics: list = []
def add_cpu_metric(self,
target_utilization: int = 70):
self.metrics.append({
"type": "Resource",
"resource": {
"name": "cpu",
"target": {
"type": "Utilization",
"averageUtilization": target_utilization
}
}
})
def add_memory_metric(self,
target_utilization: int = 80):
self.metrics.append({
"type": "Resource",
"resource": {
"name": "memory",
"target": {
"type": "Utilization",
"averageUtilization": target_utilization
}
}
})
def to_yaml(self) -> str:
spec = {
"apiVersion": "autoscaling/v2",
"kind": "HorizontalPodAutoscaler",
"metadata": {
"name": self.name,
"namespace": self.namespace
},
"spec": {
"scaleTargetRef": {
"apiVersion": "apps/v1",
"kind": "Deployment",
"name": self.deployment
},
"minReplicas": self.min_replicas,
"maxReplicas": self.max_replicas,
"metrics": self.metrics,
}
}
import yaml
return yaml.dump(spec, default_flow_style=False)
hpa = K8sHPA("gateway-hpa", "api-gateway",
min_replicas=3, max_replicas=20)
hpa.add_cpu_metric(70)
hpa.add_memory_metric(80)
print(hpa.to_yaml())
ConfigMap and Secret Management
Store gateway configuration in Kubernetes-native resources.
from typing import Dict, Optional
import base64
class K8sConfigMap:
def __init__(self, name: str,
namespace: str = "default"):
self.name = name
self.namespace = namespace
self.data: Dict[str, str] = {}
def add(self, key: str, value: str):
self.data[key] = value
def load_from_file(self, key: str,
filepath: str):
with open(filepath) as f:
self.data[key] = f.read()
def to_yaml(self) -> str:
spec = {
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": self.name,
"namespace": self.namespace
},
"data": self.data
}
import yaml
return yaml.dump(spec, default_flow_style=False)
class K8sSecret:
def __init__(self, name: str,
namespace: str = "default"):
self.name = name
self.namespace = namespace
self.data: Dict[str, str] = {}
def add(self, key: str, value: str):
self.data[key] = base64.b64encode(
value.encode()
).decode()
def to_yaml(self) -> str:
spec = {
"apiVersion": "v1",
"kind": "Secret",
"metadata": {
"name": self.name,
"namespace": self.namespace
},
"type": "Opaque",
"data": self.data
}
import yaml
return yaml.dump(spec, default_flow_style=False)
cm = K8sConfigMap("gateway-config")
cm.add("RATE_LIMIT", "100")
cm.add("LOG_LEVEL", "info")
secret = K8sSecret("gateway-secret")
secret.add("JWT_SECRET", "my-super-secret-key")
print("ConfigMap and Secret created")
Common Mistakes
Mistake 1: Not Setting Resource Limits
Without resource limits, a single gateway pod can starve other pods on the same node.
Mistake 2: Missing Health Probes
Without liveness and readiness probes, Kubernetes cannot detect and restart unhealthy pods.
Mistake 3: Ingress Routing Conflicts
Multiple Ingress resources with overlapping paths cause routing issues. Keep Ingress rules simple.
Mistake 4: ConfigMap Updates Without Restart
ConfigMap changes are not automatically picked up. Use a reloader or restart pods on config change.
Mistake 5: No Pod Anti-Affinity
Without anti-affinity, pods may all run on the same node, defeating high availability.
Practice Questions
- Why use a Kubernetes Service in front of the gateway Deployment?
- How do liveness and readiness probes differ?
- What is the role of the Horizontal Pod Autoscaler?
- How do you update gateway configuration without downtime?
- What is pod anti-affinity and why is it important?
Challenge
Build a complete Kubernetes deployment for the gateway that includes a Deployment with 3 replicas, a Service of type ClusterIP, a ConfigMap for rate limit and log level configuration, a Secret for JWT signing keys, a HorizontalPodAutoscaler scaling on CPU at 70 percent, and liveness and readiness probes on /health.
FAQ
Mini Project
Build a complete Kubernetes deployment for the gateway consisting of a Deployment (3 replicas, resource limits, health probes), a Service (ClusterIP, port 8080), a ConfigMap for configuration, a Secret for secrets, and a HorizontalPodAutoscaler (3-20 replicas, CPU at 70 percent).
What's Next
Learn about Gateway Service Mesh for advanced traffic management, or explore Gateway Scaling for scaling strategies.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro