Table of Contents
Understanding Routes and Ingress in OpenShift
In OpenShift, exposing services externally is handled primarily through Routes and, in newer versions, through Kubernetes Ingress and OpenShift Route-based ingress controllers. This chapter focuses on how these mechanisms work, how they differ, and when to use which.
Role of Routes vs Ingress in OpenShift
OpenShift historically introduced its own abstraction, the Route, before Kubernetes had Ingress. Today you will encounter:
- OpenShift Routes – OpenShift-specific, deeply integrated with the platform.
- Kubernetes Ingress – Standard Kubernetes API, supported via the OpenShift ingress controller.
- IngressController (cluster-level) – OpenShift’s operator-managed configuration for ingress/routers.
At a high level:
- Routes are the primary, first-class way to expose HTTP(S) services in OpenShift.
- Ingress is available for Kubernetes compatibility and some advanced use cases (e.g., multi‑tenant Ingress, third‑party controllers).
- IngressController defines how external traffic enters the cluster, while Routes/Ingress define what is exposed and under which hostnames/paths.
OpenShift Routes: Core Concepts
A Route maps an external DNS host name to a Service inside the cluster. The router (ingress controller) receives incoming traffic, matches the host/path, and forwards to the appropriate Service and then Pods.
Key fields of a Route resource:
spec.host– external host name, e.g.myapp.example.comspec.to– backend target (usually a Service)spec.port– target Service port (optional if the Service has a single port)spec.tls– TLS configuration (termination type, certificates, etc.)spec.path– optional URL path, e.g./api
Example basic Route:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: myapp
spec:
host: myapp.apps.example.com
to:
kind: Service
name: myapp
port:
targetPort: httpAfter creation:
- The router advertises
myapp.apps.example.comvia the cluster’s configured wildcard DNS or specific DNS entries. - Requests to this hostname are forwarded to the
myappService.
Route Creation Methods
You typically create Routes by:
- Using the web console: “Create Route” from a Service.
- Using
oc: oc expose service myapp(simple Route with defaults)oc create -f route.yaml(custom configuration)
Example with oc expose:
oc expose service myapp --hostname=myapp.apps.example.com
This creates a Route pointing to the myapp Service with the given host.
TLS Termination in Routes
One of the most important aspects of Routes is TLS/HTTPS handling. OpenShift routers support three main TLS termination types:
- Edge termination
- Passthrough termination
- Re-encrypt termination
Each has different implications for security, certificate management, and application behavior.
Edge Termination
- TLS is terminated at the router.
- Traffic from client to router is encrypted.
- Traffic from router to backend Service/Pods is plaintext (HTTP).
- Certificates are managed at the router level.
Use when:
- You trust the internal cluster network.
- You want to centralize certificate management.
- Your application expects plain HTTP internally.
Example:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: myapp-edge
spec:
host: myapp.apps.example.com
to:
kind: Service
name: myapp
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect
Key option: insecureEdgeTerminationPolicy:
Redirect– force HTTP to HTTPS (recommended).Allow– accept both HTTP and HTTPS.None– disable plain HTTP for this Route.
Passthrough Termination
- TLS is not terminated at the router.
- Traffic from client to router to backend is encrypted end‑to‑end.
- The application Pod terminates TLS (must listen on HTTPS).
- The router forwards TCP directly to the backend, using SNI to route.
Use when:
- The application must see the original TLS connection (e.g., mutual TLS, custom cipher requirements).
- You want end-to-end encryption without termination at the router.
Limitations:
- The router cannot rewrite headers, inject X-Forwarded headers, or perform HTTP-level routing.
- Path-based routing does not work; routing is based primarily on SNI hostnames.
Example:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: myapp-passthrough
spec:
host: secure.myapp.apps.example.com
to:
kind: Service
name: myapp-https
tls:
termination: passthroughRe-encrypt Termination
- TLS is terminated at the router and re-established as TLS to the backend.
- Client → Router: encrypted (with router’s certificate).
- Router → Pod: encrypted (with backend’s certificate).
- The router can use a separate CA/cert to validate backend.
Use when:
- You need encrypted traffic all the way to the Pod.
- You also want the router to do HTTP-level operations (e.g., header injection).
- You want to control trust between router and backend.
Example:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: myapp-reencrypt
spec:
host: myapp-secure.apps.example.com
to:
kind: Service
name: myapp
tls:
termination: reencrypt
destinationCACertificate: |-
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
The destinationCACertificate field is used by the router to verify the backend’s certificate.
Advanced Route Features
Beyond simple host-to-service mapping, Routes support several advanced routing features.
Path-Based Routing
Routes can optionally specify a spec.path, making them match only a subset of the URL:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: api-route
spec:
host: myapp.apps.example.com
path: /api
to:
kind: Service
name: myapp-apiMultiple Routes can share the same host but different paths, each pointing to different Services. The router:
- Matches the most specific path first.
- Then falls back to less specific or pathless routes.
Wildcard Routes
Routes support wildcard hosts, such as *.example.com, enabling routing for multiple subdomains with a single Route.
Example:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: wildcard-route
spec:
host: '*.apps.example.com'
to:
kind: Service
name: shared-backend
wildcardPolicy: SubdomainUse cases:
- Multi-tenant applications where each tenant gets
tenantX.apps.example.com. - Dynamic subdomain mapping without creating many Routes.
Sticky Sessions (Session Affinity)
For stateful HTTP applications, you may require that requests from the same client are always routed to the same Pod.
- OpenShift routers can be configured to use cookies for session affinity.
- At the Route level, you influence behavior via annotations.
Example annotations (actual keys may vary with router implementation/version):
metadata:
annotations:
haproxy.router.openshift.io/disable_session_affinity: "false"Be aware:
- Sticky sessions complicate scaling and rolling updates.
- Consider whether you can make your application stateless instead.
Custom Headers and Timeouts
Routes can be annotated to control behaviors such as:
- Request/response timeouts.
- Header insertion (e.g., HSTS, custom app headers).
- Maximum connections or rates.
Examples:
metadata:
annotations:
haproxy.router.openshift.io/timeout: 5m
haproxy.router.openshift.io/hsts_header: "max-age=31536000;includeSubDomains;preload"Exact annotation keys depend on the router implementation (commonly HAProxy-based in OpenShift).
Route Sharding and Multiple Routers
In larger environments:
- You can deploy multiple router/ingress instances (via different IngressControllers).
- Routes can be “sharded” to specific routers using:
- Namespace labels
- Route labels/annotations
- IngressController configuration
Typical reasons:
- Separate internal vs external exposure.
- Different certificates or domains per business unit.
- Different performance or security profiles.
Kubernetes Ingress on OpenShift
While Routes are OpenShift-specific, Ingress is the Kubernetes standard API for HTTP(S) external access.
Basic Ingress Structure
An Ingress defines:
- One or more hosts.
- Rules mapping host + path → backend Service.
- Optional TLS sections.
Example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: myapp.apps.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
tls:
- hosts:
- myapp.apps.example.com
secretName: myapp-tlsOn OpenShift:
- The default ingress controller supports this Ingress resource and maps it into routing rules.
- TLS certificates are provided via standard Kubernetes Secrets.
Comparing Routes and Ingress
Key differences from a user perspective:
- API:
- Route:
route.openshift.io/v1,kind: Route - Ingress:
networking.k8s.io/v1,kind: Ingress - Ecosystem:
- Ingress is portable across Kubernetes distributions.
- Route is OpenShift-specific but more deeply integrated.
- Feature maturity:
- Routes often expose OpenShift router capabilities directly (e.g., specific HAProxy annotations).
- Ingress might be more generic but can use annotations specific to the controller as well.
- TLS configuration:
- Routes define termination type (
edge,passthrough,reencrypt) directly. - Ingress typically offloads most details to the controller; TLS is bound to Secrets.
When to use which:
- Use Routes when:
- You primarily target OpenShift.
- You need Route-specific features (e.g., custom termination types, Route sharding models that rely on Route semantics).
- Use Ingress when:
- You want configuration portable across Kubernetes distributions.
- You use tooling or charts that assume Ingress.
Ingress Controllers and OpenShift Routers
An IngressController in OpenShift is a cluster-scoped resource that defines how routers/ingress pods behave and where they run.
Example (simplified):
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
name: default
namespace: openshift-ingress-operator
spec:
domain: apps.example.com
replicas: 2
endpointPublishingStrategy:
type: LoadBalancerServiceImportant aspects:
domain– wildcard domain for routes (e.g.,*.apps.example.com).endpointPublishingStrategy– how the router is exposed:LoadBalancerService,HostNetwork,NodePortService, etc.- You can create additional IngressControllers with:
- Different domains.
- Different certificates.
- Different network exposure (internal vs internet-facing).
Routes and Ingress resources are bound to a given IngressController based on:
- Domain matching.
- Route/namespace labels or specific configuration (depending on cluster policy).
Practical Considerations and Patterns
Mapping DNS and Domains
In practice, to use Routes/Ingress:
- Cluster admin configures an IngressController with
domain, e.g.apps.example.com. - DNS is configured so that
*.apps.example.compoints to: - The load balancer in front of the routers, or
- The router nodes (depending on the publishing strategy).
- As a developer, you create:
- Routes or Ingress with hosts that are subdomains of
apps.example.com.
No per-Route DNS record is usually needed due to wildcard DNS.
Choosing Hostnames
Guidelines:
- Use meaningful, environment-specific host names:
myapp-dev.apps.example.commyapp-qa.apps.example.commyapp.apps.example.com(for production).- Avoid embedding version numbers in hostnames; use paths or separate Routes for blue/green deployments instead.
Blue-Green and Canary with Routes
Routes can help implement deployment strategies:
- Blue/Green:
- Two Services (
myapp-blue,myapp-green). - Switch the Route’s
spec.to.namefrom blue to green. - Cutover traffic instantly with minimal DNS changes.
- Canary (depending on router features and annotations):
- Use route weights (if supported) or multiple backends through different Routes and router configs to split traffic gradually.
- Or expose multiple versions under different hosts/paths for controlled user testing.
Security and Compliance Considerations
- Ensure that:
- TLS is enforced (
insecureEdgeTerminationPolicy: Redirect). - Certificates are managed and rotated (via cluster-wide certificate management or external tools).
- Use internal-only IngressControllers for applications not meant to be internet-exposed:
- Domain:
apps.internal.example.com - Publishing strategy that’s only reachable from inside the corporate network or VPN.
- Combine Route/Ingress configuration with:
- NetworkPolicies (for pod-level access control).
- Authentication/authorization at the app or API gateway layer.
Hands-On Checklist for Routes and Ingress
To solidify understanding, focus on being comfortable with:
- Creating basic HTTP and HTTPS Routes using:
- Web console
oc exposeand YAML manifests- Configuring different TLS terminations:
- Edge, passthrough, and re-encrypt
- Using paths and hostnames to direct traffic:
- Different paths to different Services
- Wildcard routes
- Reading and interpreting Route status:
oc get route myapp -o yaml- Understanding
status.ingressand assigned host name. - Creating a simple Ingress resource for a Service and verifying access.
- Understanding how host names relate to the IngressController’s domain and DNS setup.
These skills prepare you to build on top of OpenShift’s networking stack, integrating routes and ingress with security, scaling, and application deployment patterns described in other chapters.