<commit_before>= Deploying a Router
{product-author}
{product-version}
:data-uri:
:icons:
:experimental:
:toc: macro
:toc-title:
:prewrap!:

toc::[]

== Overview
The OpenShift link:../../architecture/core_concepts/routes.html[router] is the
ingress point for all external traffic destined for
link:../../architecture/core_concepts/pods_and_services.html#services[services]
in your OpenShift installation. OpenShift provides and supports the following
two router plug-ins:

- The
link:../../architecture/core_concepts/routes.html#haproxy-template-router[HAProxy
template router] is the default plug-in. It uses the
ifdef::openshift-enterprise[]
*openshift3/ose-haproxy-router*
endif::[]
ifdef::openshift-origin[]
*openshift/origin-haproxy-router*
endif::[]
 image to run an HAProxy instance alongside the template router plug-in inside a
container on OpenShift. It currently supports HTTP(S) traffic and TLS-enabled
traffic via SNI. The router's container listens on the host network interface,
unlike most containers that listen only on private IPs. The router proxies
external requests for route names to the IPs of actual pods identified by the
service associated with the route.

- The link:../../architecture/core_concepts/routes.html#f5-router[F5 router]
integrates with an existing *F5 BIG-IP®* system in your environment to
synchronize routes. *F5 BIG-IP®* version 11.4 or newer is required in order to
have the F5 iControl REST API.

ifdef::openshift-enterprise[]
[NOTE]
====
The F5 router plug-in is available starting in OpenShift Enterprise 3.0.2.
====
endif::[]

[[creating-the-router-service-account]]

== Creating the Router Service Account

ifdef::openshift-enterprise[]
Starting in OpenShift Enterprise 3.0.1.0, you
endif::[]
ifdef::openshift-origin[]
You
endif::[]
must first create a
link:../../architecture/core_concepts/projects_and_users.html[service account]
for the router before deploying. This service account must have permissions to a
link:../../architecture/additional_concepts/authorization.html#security-context-constraints[security
context constraint] (SCC) that allows it to specify host ports.

Create a service account, for example named *router*:

====
----
$ echo \
    '{"kind":"ServiceAccount","apiVersion":"v1","metadata":{"name":"router"}}' \
    | oc create -f -
----
====

Edit the *privileged* SCC:

====
----
$ oc edit scc privileged
----
====

Add the *router* service account in the form of
*system:serviceaccount:<project>:<name>* to the `*users*` section:

====
----
...
users:
- system:serviceaccount:openshift-infra:build-controller
- system:serviceaccount:default:router
----
====

[[haproxy-router]]
== Deploying the Default HAProxy Router
The `oadm router` command is provided with the administrator CLI to simplify the
tasks of setting up routers in a new installation. Just about every form of
communication between OpenShift components is secured by TLS and uses various
certificates and authentication methods. Use the `--credentials` option to
specify what credentials the router should use to contact the master.

First, ensure you have link:#creating-the-router-service-account[created the
router service account] before deploying a router.

To check if a default router, named *router*, already exists:

ifdef::openshift-enterprise[]
----
$ oadm router --dry-run \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router --credentials="$KUBECONFIG" --dry-run --service-account=router
----
endif::[]

To see what the default router would look like if created:

ifdef::openshift-enterprise[]
----
$ oadm router -o yaml \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router -o yaml --credentials="$KUBECONFIG" --service-account=router
----
endif::[]

To create a router if it does not exist:

ifdef::openshift-enterprise[]
----
$ oadm router <router_name> --replicas=<number> \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router <router_name> --replicas=<number> \
    --credentials="$KUBECONFIG" \
    --service-account=router
----
endif::[]

Multiple instances are created on different hosts according to the
link:../../admin_guide/scheduler.html[scheduler policy].

To use a different router image and view the router configuration that would be used:

ifdef::openshift-enterprise[]
----
$ oadm router <router_name> -o <format> --images=<image> \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router <router_name> -o <format> --images=<image> \
    --credentials="$KUBECONFIG" \
    --service-account=router
----
endif::[]

For example:

ifdef::openshift-enterprise[]
====
----
$ oadm router region-west -o yaml --images=myrepo/somerouter:mytag \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
====
endif::[]
ifdef::openshift-origin[]
====
----
$ oadm router region-west -o yaml --images=myrepo/somerouter:mytag \
    --credentials="$KUBECONFIG" \
    --service-account=router
----
====
endif::[]

=== High Availability
You can link:../../admin_guide/high_availability.html[set up a highly-available
router] on your OpenShift cluster using IP failover.

[[customizing-the-default-routing-subdomain]]

=== Customizing the Default Routing Subdomain

You can customize the suffix used as the default routing subdomain for your
environment using the
link:../../admin_guide/master_node_configuration.html#master-configuration-files[master
configuration file] (the *_/etc/openshift/master/master-config.yaml_* file by
default). The following example shows how you can set the configured suffix to
*v3.openshift.test*:

.Master Configuration Snippet
====

----
routingConfig:
  subdomain: v3.openshift.test
----
====

With the OpenShift master(s) running the above configuration, the
link:../../architecture/core_concepts/routes.html#route-hostnames[generated host
name] for the example of a host added to a namespace *mynamespace* would be:

.Generated Host Name
====

----
myroute-mynamespace.v3.openshift.test
----
====

[[using-wildcard-certificates]]

=== Using Wildcard Certificates

A TLS-enabled route that does not include a certificate uses the router's
default certificate instead. In most cases, this certificate should be provided by a
trusted certificate authority, but for convenience you can use the OpenShift CA
to create the certificate. For example:

====
----
$ CA=/etc/openshift/master
$ oadm ca create-server-cert --signer-cert=$CA/ca.crt \
      --signer-key=$CA/ca.key --signer-serial=$CA/ca.serial.txt \
      --hostnames='*.cloudapps.example.com' \
      --cert=cloudapps.crt --key=cloudapps.key
----
====

The router expects the certificate and key to be in PEM format in a single
file:

====
----
$ cat cloudapps.crt cloudapps.key $CA/ca.crt > cloudapps.router.pem
----
====

From there you can use the `--default-cert` flag:

====
----
$ oadm router --default-cert=cloudapps.router.pem \
    --credentials="$KUBECONFIG" --service-account=router
----
====

[NOTE]
====
Browsers only consider wildcards valid for subdomains one
level deep. So in this example, the certificate would be valid for
_a.cloudapps.example.com_ but not for _a.b.cloudapps.example.com_.
====

[[using-secured-routes]]

=== Using Secured Routes

Currently, password protected key files are not supported. HAProxy prompts
for a password upon starting and does not have a way to automate this process.
To remove a passphrase from a keyfile, you can run:

----
# openssl rsa -in <passwordProtectedKey.key> -out <new.key>
----

Here is an example of how to use a secure edge terminated route with TLS
termination occuring on the router before traffic is proxied to the
destination. The secure edge terminated route specifies the TLS certificate
and key information. The TLS certificate is served by the router front end.

First, start up a router instance:

----
# odm router --replicas=1 --credentials=$KUBECONFIG --service-account=router
----

Next, create a private key, csr and certificate for our edge secured route.
The instructions on how to do that would be specific to your certificate
authority and provider. For a simple self-signed certificate for a domain
named `www.example.test`, see the example shown below:

----
# sudo openssl genrsa -out example-test.key 2048
#
# sudo openssl req -new -key example-test.key -out example-test.csr  \
  -subj "/C=US/ST=CA/L=Mountain View/O=OS3/OU=Eng/CN=www.example.test"
#
# sudo openssl x509 -req -days 366 -in example-test.csr  \
      -signkey example-test.key -out example-test.crt
----

Generate a route configuration file using the above certificate and key.
Make sure to replace servicename `my-service` with the name of your service.

----<commit_msg>Fixes as per @bmeng review comments.<commit_after>= Deploying a Router
{product-author}
{product-version}
:data-uri:
:icons:
:experimental:
:toc: macro
:toc-title:
:prewrap!:

toc::[]

== Overview
The OpenShift link:../../architecture/core_concepts/routes.html[router] is the
ingress point for all external traffic destined for
link:../../architecture/core_concepts/pods_and_services.html#services[services]
in your OpenShift installation. OpenShift provides and supports the following
two router plug-ins:

- The
link:../../architecture/core_concepts/routes.html#haproxy-template-router[HAProxy
template router] is the default plug-in. It uses the
ifdef::openshift-enterprise[]
*openshift3/ose-haproxy-router*
endif::[]
ifdef::openshift-origin[]
*openshift/origin-haproxy-router*
endif::[]
 image to run an HAProxy instance alongside the template router plug-in inside a
container on OpenShift. It currently supports HTTP(S) traffic and TLS-enabled
traffic via SNI. The router's container listens on the host network interface,
unlike most containers that listen only on private IPs. The router proxies
external requests for route names to the IPs of actual pods identified by the
service associated with the route.

- The link:../../architecture/core_concepts/routes.html#f5-router[F5 router]
integrates with an existing *F5 BIG-IP®* system in your environment to
synchronize routes. *F5 BIG-IP®* version 11.4 or newer is required in order to
have the F5 iControl REST API.

ifdef::openshift-enterprise[]
[NOTE]
====
The F5 router plug-in is available starting in OpenShift Enterprise 3.0.2.
====
endif::[]

[[creating-the-router-service-account]]

== Creating the Router Service Account

ifdef::openshift-enterprise[]
Starting in OpenShift Enterprise 3.0.1.0, you
endif::[]
ifdef::openshift-origin[]
You
endif::[]
must first create a
link:../../architecture/core_concepts/projects_and_users.html[service account]
for the router before deploying. This service account must have permissions to a
link:../../architecture/additional_concepts/authorization.html#security-context-constraints[security
context constraint] (SCC) that allows it to specify host ports.

Create a service account, for example named *router*:

====
----
$ echo \
    '{"kind":"ServiceAccount","apiVersion":"v1","metadata":{"name":"router"}}' \
    | oc create -f -
----
====

Edit the *privileged* SCC:

====
----
$ oc edit scc privileged
----
====

Add the *router* service account in the form of
*system:serviceaccount:<project>:<name>* to the `*users*` section:

====
----
...
users:
- system:serviceaccount:openshift-infra:build-controller
- system:serviceaccount:default:router
----
====

[[haproxy-router]]
== Deploying the Default HAProxy Router
The `oadm router` command is provided with the administrator CLI to simplify the
tasks of setting up routers in a new installation. Just about every form of
communication between OpenShift components is secured by TLS and uses various
certificates and authentication methods. Use the `--credentials` option to
specify what credentials the router should use to contact the master.

First, ensure you have link:#creating-the-router-service-account[created the
router service account] before deploying a router.

To check if a default router, named *router*, already exists:

ifdef::openshift-enterprise[]
----
$ oadm router --dry-run \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router --credentials="$KUBECONFIG" --dry-run --service-account=router
----
endif::[]

To see what the default router would look like if created:

ifdef::openshift-enterprise[]
----
$ oadm router -o yaml \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router -o yaml --credentials="$KUBECONFIG" --service-account=router
----
endif::[]

To create a router if it does not exist:

ifdef::openshift-enterprise[]
----
$ oadm router <router_name> --replicas=<number> \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router <router_name> --replicas=<number> \
    --credentials="$KUBECONFIG" \
    --service-account=router
----
endif::[]

Multiple instances are created on different hosts according to the
link:../../admin_guide/scheduler.html[scheduler policy].

To use a different router image and view the router configuration that would be used:

ifdef::openshift-enterprise[]
----
$ oadm router <router_name> -o <format> --images=<image> \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
endif::[]
ifdef::openshift-origin[]
----
$ oadm router <router_name> -o <format> --images=<image> \
    --credentials="$KUBECONFIG" \
    --service-account=router
----
endif::[]

For example:

ifdef::openshift-enterprise[]
====
----
$ oadm router region-west -o yaml --images=myrepo/somerouter:mytag \
    --credentials='/etc/openshift/master/openshift-router.kubeconfig' \
    --service-account=router
----
====
endif::[]
ifdef::openshift-origin[]
====
----
$ oadm router region-west -o yaml --images=myrepo/somerouter:mytag \
    --credentials="$KUBECONFIG" \
    --service-account=router
----
====
endif::[]

=== High Availability
You can link:../../admin_guide/high_availability.html[set up a highly-available
router] on your OpenShift cluster using IP failover.

[[customizing-the-default-routing-subdomain]]

=== Customizing the Default Routing Subdomain

You can customize the suffix used as the default routing subdomain for your
environment using the
link:../../admin_guide/master_node_configuration.html#master-configuration-files[master
configuration file] (the *_/etc/openshift/master/master-config.yaml_* file by
default). The following example shows how you can set the configured suffix to
*v3.openshift.test*:

.Master Configuration Snippet
====

----
routingConfig:
  subdomain: v3.openshift.test
----
====

With the OpenShift master(s) running the above configuration, the
link:../../architecture/core_concepts/routes.html#route-hostnames[generated host
name] for the example of a host added to a namespace *mynamespace* would be:

.Generated Host Name
====

----
myroute-mynamespace.v3.openshift.test
----
====

[[using-wildcard-certificates]]

=== Using Wildcard Certificates

A TLS-enabled route that does not include a certificate uses the router's
default certificate instead. In most cases, this certificate should be provided by a
trusted certificate authority, but for convenience you can use the OpenShift CA
to create the certificate. For example:

====
----
$ CA=/etc/openshift/master
$ oadm ca create-server-cert --signer-cert=$CA/ca.crt \
      --signer-key=$CA/ca.key --signer-serial=$CA/ca.serial.txt \
      --hostnames='*.cloudapps.example.com' \
      --cert=cloudapps.crt --key=cloudapps.key
----
====

The router expects the certificate and key to be in PEM format in a single
file:

====
----
$ cat cloudapps.crt cloudapps.key $CA/ca.crt > cloudapps.router.pem
----
====

From there you can use the `--default-cert` flag:

====
----
$ oadm router --default-cert=cloudapps.router.pem \
    --credentials="$KUBECONFIG" --service-account=router
----
====

[NOTE]
====
Browsers only consider wildcards valid for subdomains one
level deep. So in this example, the certificate would be valid for
_a.cloudapps.example.com_ but not for _a.b.cloudapps.example.com_.
====

[[using-secured-routes]]

=== Using Secured Routes

Currently, password protected key files are not supported. HAProxy prompts
for a password upon starting and does not have a way to automate this process.
To remove a passphrase from a keyfile, you can run:

----
# openssl rsa -in <passwordProtectedKey.key> -out <new.key>
----

Here is an example of how to use a secure edge terminated route with TLS
termination occuring on the router before traffic is proxied to the
destination. The secure edge terminated route specifies the TLS certificate
and key information. The TLS certificate is served by the router front end.

First, start up a router instance:

----
# oadm router --replicas=1 --credentials=$KUBECONFIG --service-account=router
----

Next, create a private key, csr and certificate for our edge secured route.
The instructions on how to do that would be specific to your certificate
authority and provider. For a simple self-signed certificate for a domain
named `www.example.test`, see the example shown below:

----
# sudo openssl genrsa -out example-test.key 2048
#
# sudo openssl req -new -key example-test.key -out example-test.csr  \
  -subj "/C=US/ST=CA/L=Mountain View/O=OS3/OU=Eng/CN=www.example.test"
#
# sudo openssl x509 -req -days 366 -in example-test.csr  \
      -signkey example-test.key -out example-test.crt
----

Generate a route configuration file using the above certificate and key.
Make sure to replace servicename `my-service` with the name of your service.

----
{'fraction_non_alphanumeric': 0.13259790402647545, 'fraction_numerical': 0.0036403750689464973, 'mean_word_length': 4.023829315599889, 'pattern_counts': {'":': 8, '<': 31, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1548082', 'n_tokens_mistral': 5582, 'n_tokens_neox': 5342, 'n_words': 1787}