- Overview
- Routers
- Available Router Plug-ins
- Configuration Parameters
- Route Host Names
- Route Types
- Path Based Routes
- Secured Routes
- Router Sharding
- Route-specific Annotations
- Creating Routes Specifying a Wildcard Subdomain Policy
- Route Status
- Denying or Allowing Certain Domains in Routes
- Disabling the Namespace Ownership Check
Overview
Route는 simple-app.cloud.example.com 형태의 Domain Name으로 Service를 노출시킴으로써 외부의 Client가 접속할 수 있는 통로 역할을 해준다.
외부에서 접속시 DNS 명에 대한 IP 정보 판별은 Route의 역할과는 별개이다. DNS Wildcard Entry가 Route가 실행되는 노드의 IP를 찾아가도록 DNS가 미리 세팅이 되어 있어야 한다.
(*.cloud.example.com 이 Router가 설치되어 있는 Node의 IP로 연결되어야한다.)
Route는 simple-app.cloud.example.com에 대한 내부 Service를 찾아서 연결시켜준다.
Node의 호스트네임과 전혀 다른 도메인을 사용하는 경우도 해당 도메인에 대해서 별도로 등록하여 노드의 IP를 찾아가도록 미리 세팅이 되어 있어야 한다.
Routers
관리자가 Router 를 인프라 노드에 배포하면 개발자들은 외부 사용자들을 위해 route를 사용할 수 있다.
OpenShift Container Platform에서 Routing layer는 pluggable하고, 두가지 사용가능한 router plug-ins (HAProxy template router, F5 router )이 있다.
Router는 연결할 Service를 찾기 위하여 Service Selector를 사용한다.
Router 는 Service의 IP 변경사항을 감지할 수 있어 변경되면 자동으로 변경사항을 적용한다.
Router High Avalibility
Host Name을 찾기 위해 Router에 질의를 해야하는데, 현재 적용되는 방법은 wildcard DNS entry가 여러개의 Router VIP를 가르키는 Cloud Domain을 정의하는 것이다.
Cloud Domain 바깥의 Host Name과 Address를 사용하는 Route는 개별적인 DNS Entry가 필요하다.
Router 개수 보다 사용할 수 있는 VIP 개수가 적으면, VIP가 개수만큼은 Active로, 나머지는 Passive로 사용된다.
Passive Router는 hot-standby router로 알려져 있다. 예를 들어 2개의 VIP주소와 3개의 Router가 있다면, Active-Active-Passive 설정이 된다. See High Availability
Router Sharding
Route는 Router 사이에서 공유될 수 있다. 관리자는 전체 클러스터 측면에서 Sharding을 만들고 사용자는 프로젝트에서 Namespace로 Sharding을 설정할 수 있다.
Sharding을 통해 여러개의 Router 그룹을 만들 수 있다. 그룹의 각 Router는 전체 트래픽의 일부만 처리한다.
Router는 Host Name Mapping과 Service로의 요청에 대한 Load Balancing을 제공한다.
Port Binding
Router plug-ins은 기본적으로 80 (HTTP), 443 (HTTPS) 포트를 바인딩 하도록 되어 있다.
따라서 80과 443을 쓸 수 있는 Node에 Router plug-ins을 설치하는 것이 좋으며 그렇지 않은 경우는 환경변수 ROUTER_SERVICE_HTTP_PORT, ROUTER_SERVICE_HTTPS_PORT를 통해 변경할 수 있다.
Router는 Host의 포트에 바인딩이 되기 때문에 각 노드에 같은 포트로는 1개의 Router 만 사용이 가능하다.
Routers support the following protocols:
HTTP
HTTPS (with SNI)
WebSockets
TLS with SNI
Template Routers
Template Router는 기본 Router 구현체에 Infrastructure 정보를 제공하는 router의 한 종류이다.
Infrastructure 정보
- Endpoint 와 Route를 볼 수 있는 Wrapper
- 사용가능한 형태로 저장된 Endpoint 와 Route 데이터
- 설정 및 실행 가능한 템플릿으로 내부 상태를 전달가능
- Reload 스크립트 호출 가능
Available Router Plug-ins
HAProxy Template Router
HAProxy template router는 Template Router의 구현체이다.
openshift3/ose-haproxy-router 를 사용하여 HAProxy instance를 실행한다.
아래 그림은 master로 부터 plug-in과 HAProxy로 데이터가 어떻게 흘러가는지 보여준다.
Sticky Sessions
Sticky session는 사용자의 Traffic이 매번 같은 Pod를 향하도록 해주는 것으로써 Pod 내에 Cache 데이터 같은 것이 존재 할 때 효율적으로 사용할 수 있도록 해준다.
예를 들면, 전체 클러스터에 5개의 Pod와 2개의 load-balanced router 가 있을 때, 같은 웹 브라우져에서 항상 같은 Pod 로 트래픽이 가도록 하는 것이다.
하지만 항상 같은 Pod로 트래픽을 보내는 것이 완벽히 보장되지는 않는다. HTTP Header에 최종 연결했던 Pod를 결정할 수 있는 Cookie를 사용할 수도 있다.
어플리케이션 유저가 Router를 지날 때, 브라우저는 쿠키를 다시 보내고 트래픽을 어디로 갈지 알수 있게된다.
클러스터 관리자가 passthrough route에서는 Stickiness를 끌 수 있다.
기본으로는, default HAProxy router는 passthrough route를 사용한다면 Sticky Session은 기본 router 설정에서 source IP를 기반으로한 "balance source" 지시자로 구현된다.
다른 종류들은 "balance leastconn" 지시자를 사용한다. Cookie가 있다면 마지막에 갔던 Pod와 같은 Pod로 보내진다. Cookie가 없으면 새로운 세션으로 간주되므로 새로 Pod를 선택한다.
추가적으로, template router plug-in은 service name과 namespace를 기본 구현체에게 제공한다.
이것은 실제 Pod의 상태를 알수 있도록 stick-tables 을 구현하는것 처럼 좀더 상세한 설정을 할 수 있게 한다.
이 Router 구현체에 대한 설정은 haproxy-config.template 파일에 저장된다.
이 파일은 Router 컨테이너의 /var/lib/haproxy/conf 에 있다.
Configuration Parameters
Router에 대한 환경변수를 deployment config 를 통해 설정할 수 있다.
Route Host Names
Service 를 외부로 노출하려면 외부에서 접속 가능한 Host Name으로 연결시켜야 한다. 그러면 이 Host Name을 통해 외부 트래픽을 Service로 보낼 수 있다.
서로 다른 Namespace에서 여러개의 Route가 같은 Host Name을 사용하면 먼저 만들어진 Route가 우선이다.
같은 Namespace에서 다른 Path Field가 정의된 추가 Route가 존재하면 새로운 Path는 추가된다.
같은 Path로 여러개의 Route가 존재하면 먼저 생성된것이 작동한다.
결론적으로 하나의 Host Name에 대해서 A와 B 라는 2개의 Route가 존재하는 경우에,
다른 Namespace에 누군가 같은 Host Name으로 C를 시차상 A 와 B 사이에 만든 경우,
처음에는 해당 Host Name이 A를 통해 작동하다가 A 를 지우면 B가 아니라 C로 넘어가게 된다. (C가 순서상 빠르기 때문에)
이런 경우 C에 해당 Route가 존재하는지 모른다면 왜 B Route가 제대로 작동하지 않는지 알수가 없다.
router.default.svc.cluster.local 이 SubDomain이며 Cluster AdminL 이 변경가능하다.
Route Types
Router는 Secured 또는 Unsecured가 될 수 있다. Secure route는 Client 에게 Certificate를 제공하기위해 여러가지 형태의 TLS termination을 사용할 수 있다.
Router는 edge, passthrough, re-encryption termination 방식을 지원한다.
Unsecured routes는 key 또는 certificates 가 필요없으므로 간단하게 설정가능하다. 그러나 secured route는 보다 안전한 커넥션을 제공한다.
Path Based Routes
Path based route는 URL 과 비교가능한 path component를 지정한다. 여러 Route가 같은 Host Name으로 서비스 되지만 각 Route는 서로다른 Path를 가질 수 있다. Router는 Route가 지정된 Path에 맞는지 비교한다. 그러나 이것은 Router의 구현체에 따라서 조금씩 다를 수 있다. 아래 표는 Path에 따른 접근성을 보여준다.
Secured Routes
Secured routes는 route 의 TLS termination을 지정하고 key 와 certificate를 제공한다.
Secured routes 는 3가지 타입의 TLS termination 을 사용할 수 있다.
Edge Termination
TLS termination은 traffic 이 도달하는 목적지가 아니라 Router에서 이루어진다. TLS certificate는 router에서 제공되므로 Route에 설정되어 있어야 한다.
그렇지 않으면 Router의 Default Cetificate가 TLS Termination에 사용될 것이다.
TLS 가 Router에서 종료되므로, Router 부터 Endpoint까지는 암호화되지 않은 내부네트웍구간이다.
Edge-terminated route는 insecure schemes (HTTP
)에서는 트랙픽을 비활성화 또는 Redirect 해주는 insecureEdgeTerminationPolicy
를 지정할 수 있다.
지정가능한 값으로, 비활성화하는 경우 None
또는 empty를 지정하고, Allow 또는
Redirect
를 사용할 수 있다.
insecureEdgeTerminationPolicy
의 기본값은 insecure scheme에서는 traffic 을 disable 하는것이다.
기본적인 Use Case로는 content 를 기본적으로 secure scheme(HTTPS)로 서비스하고, images, CSS, JS 등은 insecure scheme(HTTP)로 서비스 하는 것이다.
Passthrough Termination
passthrough termination에서는 router에서 TLS termination을 제공하지 않으므로 encrypted traffic이 최종 목적지 까지 보내진다.
따라서 Route에서 key 와 certificate 가 필요하지 않는다.
최종 destination인 pod 는 자체적으로 certificate를 제공해야 한다.
그리고 이 방법은 클라이언트의 Certificate를 요구하는 two-way authentication을 유일하게 사용할 수 있다.
Re-encryption Termination
Re-encryption 은 Edge Termination에서 변화된 것이다. Router에서 TLS를 종료하고 Endpoint Pod까지 새로운 Certificate로 암호화 구간을 유지한다. 그리하여 내부 구간 까지 전구간을 암호화 할 수 있다. Router는 Host의 신뢰성을 결정하기위해 health check를 사용한다.
destinationCACertificate
항목은 router 와 destination 구간을 암호화하기위한, endpoint certificate를 확인하는 CA certificate를 지정한다. 이 항목은 오직 re-encryption 타입일 경우만 필요하다.
Router Sharding
각 Route는 metadata 항목에 Lable을 가질 수 있다.
Router는 Selector (selection expression)를 사용하여 전체 중에 서비스에 사용될 특정 Route의 Subset을 선택할 수 있다.
Selection Expression은 Route의 Namespace에서 Label을 포함할 수 있다.
이러한 Selected Route들이 Router Shard를 구성한다. 여러개의 Route로 부터 독립적으로 Router Shard를 만들거나 수정할 수 있다.
이것은 전통적인 Shrading을 지원한다. 전통적인 Sharding에서, Selection은 겹치지 않는 집합을 만들고 Route는 정확히 하나의 Shard에 속한다.
겹치는 Sharding에서는 겹치는 집합을 만들고 Route도 여러 Shard에 속할 수 있다.
예를 들면 Single Route는 SLA=high
Shard에 속할 수 있고(SLA=medium
or SLA=low
Shards에 속하지는 않음) 또한 geo=west
Shard에 속할 수 있다(geo=east
shard에는 속하지 않음).
겹치는 Sharding의 예로 Route의 Namespace에 기반하여 선택되는 Router 집합이 있다.
Router | Selection | Namespaces |
---|---|---|
router-1 |
|
|
router-2 |
|
|
router-3 |
|
|
router-2
와 router-3 은 공통적으로 namespaces
Q*
, R*
, S*
, T*에 속한 Route들을 서비스한다.
겹치지 않게 이 사례를 바꾸려면, router-2의 Selection을 K*
— P*로
변경하여 겹치는 부분을 제거할 수 있다.
Router가 여러개의 Shard로 나누어 질 때, 하나의 Route는 0 또는 여러개의 Router와 연결된다. Route Binding은 Shard내에서 Route의 고유성을 보장한다. (1개의 Shard에는 1개의 Route만 연결가능)
다만 1개의 route의 secure 와 non-secure versions이 하나의 Shard에 존재하는 것은 허용한다.
이것은 Route가 created - bound - active로 움직이는 life cycle을 가지고 있다는 것을 의미한다.
Sharding 환경에서는, Shard와 연결되는 첫번째 Route는 계속 연결될 수 있는 권한을 갖는다.
green/blue deployment 사이에는, Route는 여러 Router에 의해 선택될 수 있다.
관리자는 트래픽을 Old 버전에서 New 버전으로 바꾸고 Old 버전을 종료하는 경우가 생기는 것이다.
Sharding 은 클러스터 레벨에서 관리자에 의해 그리고 project/namespace레벨에서 User에 의해 진행될 수 있다.
namespace 레벨이 사용될 때, Router의 ServiceAccount는 namespace에서 Router가 Lable에 접근할 수 있는 cluster-reader
permission을 가져야 한다.
Route-specific Annotations
environment variables를 사용하여 router 모든 Route의 default option을 설정할 수 있다. 개별 route는 Annotaions을 사용하여 특정 설정을 제공함으로써 default option을 override 할 수 있다.
Route Annotations
route definition에서 Annotation을 설정할 수 있다.
Creating Routes Specifying a Wildcard Subdomain Policy
wildcard policy는 User가 domain 내의 모든 호스트를 Cover하는 Route를 정의할 수 있게 한다.
route 는 wildcardPolicy
를 사용하여 wildcard policy를 지정할 수 있다.
routes는 wildcard routes를 허용하는 Policy를 가지고 실행된다. wildcard routes는 wildcard policy를 기반으로 알맞게 Route를 노출한다.
Route Status
route status 항목은 router 에만 설정가능하다. 만약 Route가 변경되면, router 는 더이상 특정 route를 서비스하지 않고 status가 stale로 된다.
routers 는 Route Status 항목을 clear하지 않는다.
Route Status에 Stale Entry를 제거하려면, clear-route-status script 를 사용해라.
Denying or Allowing Certain Domains in Routes
Router는 특정 도메인의 Subset을 허용 또는 거부할 수 있도록 설정될 수 있다.
이와 관련된 환경변수는 ROUTER_DENIED_DOMAINS
와 ROUTER_ALLOWED_DOMAINS
이다.
| Domains listed are not allowed in any indicated routes. |
| Only the domains listed are allowed in any indicated routes. |
거부 목록의 Domain은 허용 목록의 Domain에 우선한다.
OpenShift Container Platform은 먼저 Deny List를 체크하고, Host Name이 Deny List에 없다면 Allow List를 체크한다.
그러나 Allow List가 더 제한적이다. 그리고 Router가 해당 List에 속한 호스트의 Route만 허용하는 것을 보장한다.
예를 들면 myrouter Route에서 [*.]open.header.test
, [*.]openshift.org
and [*.]block.it
routes를 거부하려면
허용목록 예시
거부목록 예시
다른방법으로 호스트 이름이 [*.]stickshift.org
또는 [*.]kates.net 으로 세팅되지 않은 Route 들을 Block하려면
허용목록 예시
거부목록 예시
Allow와 Deny 를 같이 사용하는 방법
거부목록 예시
허용목록 예시
Disabling the Namespace Ownership Check
Host 와 Subdomains은 처음에 생성된 Route의 Namespace에 속하게 된다. 같은 Namespace의 Route 들만 관련 Subdomain상에서 요청할 수 있다.
다른 모든 namespace들은 이미 요청된 Host와 Subdomain에 대한 요구를 할 수 없다. 해당 Host를 가지고 있는 Namespace는 그 Host와 관련된 모든 Path를 소유할 수 있다. (www.abc.xyz/path1
.)
예를 들면, host www.abc.xyz
가 Route에 의해 요청되지 않았다면, namespace ns1에서 Host
www.abc.xyz
으로 route r1을 생성하는 것은 namespace ns1을 host
www.abc.xyz
와 subdomain abc.xyz 의 Owner로 만드는 것이다. 만약 다른 namespace ns2 에서 route를 생성하고
www.abc.xyz/path1/path2
를 설정하면 그것은 Namespace ns1의 r1이 소유권을 가지고 있으므로 실패할 것이다.
Subdomain을 가진 Namespace는 그 Subdomain 내의 모든 Host를 소유하고 있다. 만약 Namespace가 Subdomain abc.xyz
를 소유하고 있으면, 다른 Namespace는 z.abc.xyz를 요청할 수 없다.
namespace ownership rule을 Disable함으로써 이런 제한사항을 없애고 다른 Namespace에서 필요한 Host 또는 Subdomain을 요청할 수 있다.
예를 들면, ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true 로 설정하고 namespace ns1에서 route
r1
www.abc.xyz
을 생성하면, 그것은 해당 Hostname과 Root Path만 소유하는 것이다. 다른 Namespace가 그 subdomain abc.xyz에서 wildcard route를 생성할 수 있고, 또 다른 Namespace가 non-wildcard overlapping hosts (예를들면, foo.abc.xyz
, bar.abc.xyz
, baz.abc.xyz
)를 가질 수 있다.
다른 Namespace(예를들면 ns2)가 route r2
www.abc.xyz/p1/p2
를 생성할 수 있다. 비슷하게 또 다른 Namespace ns3에서 subdomain wildcard policy를 가지는 Route wildthing.abc.xyz을 생성할 수 있다.
이 사례는 ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK=true 정책이 더 느슨하고 Namespace 사이에 요구를 허용하는것을 증명한다.
이번에는 ownership disabled namespace에서 host+path이 이미 요청되었을 때 Router가 Route를 거부하는 것을 보여준다.
예를들면, 새로운 Route rx가 www.abc.xyz/p1/p2
를 요청하려하면, route r2가 해당 host+path combination을 가지고 있으므로 거부될 것이다.
이것은 route rx
가 같은 Namespace 또는 다른 Namespace에 있어도 마찬가지이다.
이러한 설정은 Router 생성시 또는 Router 배포설정의 환경변수를 통해서 세팅될 수 있다.