As an OpenShift cluster grows by helping developers deliver features and applications faster, the efficiency of resource use becomes a central concern. Many OpenShift rollouts start with at least two physical clusters, one for development and one for production. While this has the perceived advantage of simplifying the mental model and some administrative aspects, OpenShift’s automated resilience, enhanced access controls, and advanced Routing features can logically isolate dev and prod environments on a single cluster. The Kubernetes scheduler at OpenShift’s core maximizing the density of applications running on each node. With additional configuration, further density and compute savings are possible through features like Quality of Service QoS.

This post shows how to deploy isolated development and production versions of an application on a single cluster by redirecting requests to the appropriate environment. If engineers are benchmarking and load testing a development application, it should not impact production traffic or production performance. For this reason, we will deploy “sharded” routing in an OpenShift cluster, creating multiple routers for particular purposes.

Cluster and Router Architecture

This is our high level cluster and router architecture:

In this cluster, we do not dedicate nodes to the different production and dev workloads. We just split traffic by routing requests appropriately.

Global Load Balancer: HAProxy

The global load balancer, at the top of the architecture diagram, runs haproxy with the following key lines of configuration:

acl host_router_dev req.ssl_sni -m sub -i apps-dev.example.com
acl host_router_prod req.ssl_sni -m sub -i apps-prod.example.com

use_backend atomic-openshift-router-dev if host_router_dev
use_backend atomic-openshift-router-prod if host_router_prod

(The complete haproxy configuration can be found here.)

OpenShift Routers

As shown in the architecture chart, different subdomains are sent to different OpenShift Routers. We deploy 3 routers: 2 for Production, and 1 for Development. Routers are deployed with the OpenShift command-line API tool, oc. The oc adm router subcommands are used to manipulate router deployments:

oc adm router router-prod --replicas=2 --force-subdomain='${name}-${namespace}.apps-prod.example.com'
oc adm router router-dev --replicas=1 --force-subdomain='${name}-${namespace}.apps-dev.example.com'

We use --force-subdomain to force separate subdomains for separate routers.

Next, we will dedicate each router deployment to serve traffic to only a subset of namespaces:

oc set env dc/router-prod NAMESPACE_LABELS="router=prod"
oc set env dc/router-dev NAMESPACE_LABELS="router=dev"

We ensure that our routers are running on their dedicated nodes, by specifying node labels for the router deployments to select:

oc label node infra1.example.com "router=prod"
oc label node infra2.example.com "router=prod"
oc label node infra3.example.com "router=dev"

#patch deployments of the router:
oc patch dc router-dev -p "spec:
template:
spec:
nodeSelector:
router: dev"

oc patch dc router-prod -p "spec:
template:
spec:
nodeSelector:
router: prod"

OpenShift Namespace, Project, and Application Labels and Selectors

With router and node labels set, we create OpenShift projects for prod and dev, labeling them accordingly.

oc new-project prod
oc label namespace prod router=prod

Now, let's test our configuration with a new OpenShift application in the prod project we just created and labeled:

# oc new-app cakephp-mysql-example
[...]
# oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
cakephp-mysql-example cakephp-mysql-example-prod.apps-prod.example.com cakephp-mysql-example web edge None

Notice that the route already uses the apps-prod subdomain, for production workloads.

Let’s test the same routing pattern for development environments.

# oc new-project dev
# oc label namespace dev router=dev
# oc new-app cakephp-mysql-example
# oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
cakephp-mysql-example cakephp-mysql-example-dev.apps-dev.example.com cakephp-mysql-example web edge None

Next, we test both URLs as a client, using curl:

# curl -sSLk -D - https://cakephp-mysql-example-dev.apps-dev.example.com -o /dev/null
HTTP/1.1 200 OK
Date: Wed, 11 Apr 2018 13:27:54 GMT
Server: Apache/2.4.27 (Red Hat) OpenSSL/1.0.1e-fips
Content-Length: 64467
Content-Type: text/html; charset=UTF-8
Set-Cookie: 1b15022d32bdaf178e4bb662559c535f=9b517482994c000cd2b19fe8ca6174e2; path=/; HttpOnly; Secure
Cache-control: private

# curl -sSLk -D - https://cakephp-mysql-example-prod.apps-prod.example.com -o /dev/null
HTTP/1.1 200 OK
Date: Wed, 11 Apr 2018 13:28:46 GMT
Server: Apache/2.4.27 (Red Hat) OpenSSL/1.0.1e-fips
Content-Length: 64484
Content-Type: text/html; charset=UTF-8
Set-Cookie: 2e2307f4645f03dde968155c002d6b44=8316f5abdc2526e8edcb1b110e430325; path=/; HttpOnly; Secure
Cache-control: private

Conclusion

By splitting traffic, we ensure that we can meet our application Service Level Agreements (SLAs) while reducing the number of clusters we have to manage and the resources consumed. By having everything in one cluster, we can save on hardware, people resources, and maintenance costs.

Before you move toward a "one cluster” architecture, ask yourself: Are you and your organization are ready for this?

Acknowledgements

This post is a simplified version of the OpenShift router documentation.

Special thanks to @noeloc.


저자 소개

UI_Icon-Red_Hat-Close-A-Black-RGB

채널별 검색

automation icon

오토메이션

기술, 팀, 인프라를 위한 IT 자동화 최신 동향

AI icon

인공지능

고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트

open hybrid cloud icon

오픈 하이브리드 클라우드

하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요

security icon

보안

환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보

edge icon

엣지 컴퓨팅

엣지에서의 운영을 단순화하는 플랫폼 업데이트

Infrastructure icon

인프라

세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보

application development icon

애플리케이션

복잡한 애플리케이션에 대한 솔루션 더 보기

Virtualization icon

가상화

온프레미스와 클라우드 환경에서 워크로드를 유연하게 운영하기 위한 엔터프라이즈 가상화의 미래