github.com/projectcontour/contour@v1.28.2/site/content/docs/v1.6.1/httpproxy.md (about)

     1  # HTTPProxy Reference
     2  
     3  <div id="toc" class="navigation"></div>
     4  
     5  The [Ingress][1] object was added to Kubernetes in version 1.1 to describe properties of a cluster-wide reverse HTTP proxy.
     6  Since that time, the Ingress object has not progressed beyond the beta stage, and its stagnation inspired an [explosion of annotations][2] to express missing properties of HTTP routing.
     7  
     8  The goal of the HTTPProxy (previously `IngressRoute`) Custom Resource Definition (CRD) is to expand upon the functionality of the Ingress API to allow for a richer user experience as well addressing the limitations of the latter's use in multi tenent environments.
     9  
    10  ## Key HTTPProxy Benefits
    11  
    12  - Safely supports multi-team Kubernetes clusters, with the ability to limit which Namespaces may configure virtual hosts and TLS credentials.
    13  - Enables including of routing configuration for a path or domain from another HTTPProxy, possibly in another Namespace.
    14  - Accepts multiple services within a single route and load balances traffic across them.
    15  - Natively allows defining service weighting and load balancing strategy without annotations.
    16  - Validation of HTTPProxy objects at creation time and status reporting for post-creation validity.
    17  
    18  ## Ingress to HTTPProxy
    19  
    20  A minimal Ingress object might look like:
    21  
    22  ```yaml
    23  # ingress.yaml
    24  apiVersion: networking.k8s.io/v1beta1
    25  kind: Ingress
    26  metadata:
    27    name: basic
    28  spec:
    29    rules:
    30    - host: foo-basic.bar.com
    31      http:
    32        paths:
    33        - backend:
    34            serviceName: s1
    35            servicePort: 80
    36  ```
    37  
    38  This Ingress object, named `basic`, will route incoming HTTP traffic with a `Host:` header for `foo-basic.bar.com` to a Service named `s1` on port `80`.
    39  Implementing similar behavior using an HTTPProxy looks like this:
    40  
    41  {% highlight yaml linenos %}
    42  # httpproxy.yaml
    43  apiVersion: projectcontour.io/v1
    44  kind: HTTPProxy
    45  metadata:
    46    name: basic
    47  spec:
    48    virtualhost:
    49      fqdn: foo-basic.bar.com
    50    routes:
    51      - conditions:
    52        - prefix: /
    53        services:
    54          - name: s1
    55            port: 80
    56  {% endhighlight %}
    57  
    58  **Lines 1-5**: As with all other Kubernetes objects, an HTTPProxy needs apiVersion, kind, and metadata fields.
    59  
    60  **Lines 7-8**: The presence of the `virtualhost` field indicates that this is a root HTTPProxy that is the top level entry point for this domain.
    61  The `fqdn` field specifies the fully qualified domain name that will be used to match against `Host:` HTTP headers.
    62  
    63  **Lines 9-14**: Each HTTPProxy **must** have one or more routes, each of which **must** have one or more services which will handle the HTTP traffic. In addition, each route **may** have one or more conditions to match against.
    64  
    65  **Lines 12-14**: The `services` field is an array of named Service & Port combinations that will be used for this HTTPProxy path.
    66  HTTP traffic will be sent directly to the Endpoints corresponding to the Service.
    67  
    68  ## Interacting with HTTPProxies
    69  
    70  As with all Kubernetes objects, you can use `kubectl` to create, list, describe, edit, and delete HTTPProxy CRDs.
    71  
    72  Creating an HTTPProxy:
    73  
    74  ```bash
    75  $ kubectl create -f basic.httpproxy.yaml
    76  httpproxy "basic" created
    77  ```
    78  
    79  Listing HTTPProxies:
    80  
    81  ```bash
    82  $ kubectl get httpproxy
    83  NAME      AGE
    84  basic     24s
    85  ```
    86  
    87  Describing HTTPProxy:
    88  
    89  ```bash
    90  $ kubectl describe httpproxy basic
    91  Name:         basic
    92  Namespace:    default
    93  Labels:       <none>
    94  API Version:  projectcontour.io/v1
    95  Kind:         HTTPProxy
    96  Metadata:
    97    Cluster Name:
    98    Creation Timestamp:  2019-07-05T19:26:54Z
    99    Resource Version:    19373717
   100    Self Link:           /apis/projectcontour.io/v1/namespaces/default/httpproxy/basic
   101    UID:                 6036a9d7-8089-11e8-ab00-f80f4182762e
   102  Spec:
   103    Routes:
   104      Conditions:
   105        Prefix: /
   106      Services:
   107        Name:  s1
   108        Port:  80
   109    Virtualhost:
   110      Fqdn:  foo-basic.bar.com
   111  Events:    <none>
   112  ```
   113  
   114  Deleting HTTPProxies:
   115  
   116  ```bash
   117  $ kubectl delete httpproxy basic
   118  httpproxy "basic" deleted
   119  ```
   120  
   121  ## HTTPProxy API Specification
   122  
   123  There are a number of [working examples][3] of HTTPProxy objects in the `examples/example-workload` directory.
   124  
   125  We will use these examples as a mechanism to describe HTTPProxy API functionality.
   126  
   127  ### Virtual Host Configuration
   128  
   129  #### Fully Qualified Domain Name
   130  
   131  Similar to Ingress, HTTPProxy support name-based virtual hosting.
   132  Name-based virtual hosts use multiple host names with the same IP address.
   133  
   134  ```
   135  foo.bar.com --|                 |-> foo.bar.com s1:80
   136                | 178.91.123.132  |
   137  bar.foo.com --|                 |-> bar.foo.com s2:80
   138  ```
   139  
   140  Unlike Ingress, HTTPProxy only support a single root domain per HTTPProxy object.
   141  As an example, this Ingress object:
   142  
   143  ```yaml
   144  # ingress-name.yaml
   145  apiVersion: extensions/v1beta1
   146  kind: Ingress
   147  metadata:
   148    name: name-example
   149  spec:
   150    rules:
   151    - host: foo1.bar.com
   152      http:
   153        paths:
   154        - backend:
   155            serviceName: s1
   156            servicePort: 80
   157    - host: bar1.bar.com
   158      http:
   159        paths:
   160        - backend:
   161            serviceName: s2
   162            servicePort: 80
   163  ```
   164  
   165  must be represented by two different HTTPProxy objects:
   166  
   167  ```yaml
   168  # httpproxy-name.yaml
   169  apiVersion: projectcontour.io/v1
   170  kind: HTTPProxy
   171  metadata:
   172    name: name-example-foo
   173    namespace: default
   174  spec:
   175    virtualhost:
   176      fqdn: foo1.bar.com
   177    routes:
   178      - services:
   179        - name: s1
   180          port: 80
   181  ---
   182  apiVersion: projectcontour.io/v1
   183  kind: HTTPProxy
   184  metadata:
   185    name: name-example-bar
   186    namespace: default
   187  spec:
   188    virtualhost:
   189      fqdn: bar1.bar.com
   190    routes:
   191      - services:
   192          - name: s2
   193            port: 80
   194  ```
   195  
   196  #### TLS
   197  
   198  HTTPProxy follows a similar pattern to Ingress for configuring TLS credentials.
   199  
   200  You can secure a HTTPProxy by specifying a Secret that contains TLS private key and certificate information.
   201  If multiple HTTPProxies utilize the same Secret, the certificate must include the necessary Subject Authority Name (SAN) for each fqdn.
   202  
   203  Contour (via Envoy) requires that clients send the Server Name Indication (SNI) TLS extension so that requests can be routed to the correct virtual host.
   204  Virtual hosts are strongly bound to SNI names.
   205  This means that the Host header in HTTP requests must match the SNI name that was sent at the start of the TLS session.
   206  
   207  Contour also follows a "secure first" approach.
   208  When TLS is enabled for a virtual host, any request to the insecure port is redirected to the secure interface with a 301 redirect.
   209  Specific routes can be configured to override this behavior and handle insecure requests by enabling the `spec.routes.permitInsecure` parameter on a Route.
   210  
   211  The TLS secret must contain keys named tls.crt and tls.key that contain the certificate and private key to use for TLS, e.g.:
   212  
   213  ```yaml
   214  # ingress-tls.secret.yaml
   215  apiVersion: v1
   216  data:
   217    tls.crt: base64 encoded cert
   218    tls.key: base64 encoded key
   219  kind: Secret
   220  metadata:
   221    name: testsecret
   222    namespace: default
   223  type: kubernetes.io/tls
   224  ```
   225  
   226  The HTTPProxy can be configured to use this secret using `tls.secretName` property:
   227  
   228  ```yaml
   229  # httpproxy-tls.yaml
   230  apiVersion: projectcontour.io/v1
   231  kind: HTTPProxy
   232  metadata:
   233    name: tls-example
   234    namespace: default
   235  spec:
   236    virtualhost:
   237      fqdn: foo2.bar.com
   238      tls:
   239        secretName: testsecret
   240    routes:
   241      - services:
   242          - name: s1
   243            port: 80
   244  ```
   245  
   246  If the `tls.secretName` property contains a slash, eg. `somenamespace/somesecret` then, subject to TLS Certificate Delegation, the TLS certificate will be read from `somesecret` in `somenamespace`.
   247  See TLS Certificate Delegation below for more information.
   248  
   249  The TLS **Minimum Protocol Version** a vhost should negotiate can be specified by setting the `spec.virtualhost.tls.minimumProtocolVersion`:
   250  
   251  - 1.3
   252  - 1.2
   253  - 1.1 (Default)
   254  
   255  ##### Fallback Certificate
   256  
   257  Contour provides virtual host based routing, so that any TLS request is routed to the appropriate service based on both the server name requested by the TLS client and the HOST header in the HTTP request. 
   258  
   259  As the HOST Header is encrypted during TLS handshake, it can’t be used for virtual host based routing unless the client sends HTTPS requests specifying hostname using the TLS server name, or the request is first decrypted using a default TLS certificate.
   260  
   261  Some legacy TLS clients do not send the server name, so Envoy does not know how to select the right certificate. A fallback certificate is needed for these clients.
   262  
   263  _Note: The minimum TLS protocol version for any fallback request is defined by the `minimum TLS protocol version` set in the Contour configuration file. Enabling the fallback certificate is not compatible with TLS client authentication._
   264  
   265  ###### Configuration
   266  
   267  First define the `namespace/name` in the [Contour configuration file][11] of a Kubernetes secret which will be used as the fallback certificate.
   268  Any HTTPProxy which enables fallback certificate delegation must have the fallback certificate delegated to the namespace in which the HTTPProxy object resides.
   269  
   270  To do that, configure `TLSCertificateDelegation` to delegate the fallback certificate to specific or all namespaces (e.g. `*`) which should be allowed to enable the fallback certificate.
   271  Finally, for each root HTTPProxy, set the `Spec.TLS.enableFallbackCertificate` parameter to allow that HTTPProxy to opt-in to the fallback certificate routing.
   272  
   273  ```yaml
   274  apiVersion: projectcontour.io/v1
   275  kind: HTTPProxy
   276  metadata:
   277    name: fallback-tls-example
   278    namespace: defaultub
   279  spec:
   280    virtualhost:
   281      fqdn: fallback.bar.com
   282      tls:
   283        secretName: testsecret
   284        enableFallbackCertificate: true
   285    routes:
   286      - services:
   287          - name: s1
   288            port: 80
   289  ---
   290  apiVersion: projectcontour.io/v1
   291  kind: TLSCertificateDelegation
   292  metadata:
   293    name: fallback-delegation
   294    namespace: www-admin
   295  spec:
   296    delegations:
   297      - secretName: fallback-secret-name
   298        targetNamespaces:
   299        - "*"
   300  ```
   301  
   302  
   303  
   304  #### Upstream TLS
   305  
   306  A HTTPProxy can proxy to an upstream TLS connection by annotating the upstream Kubernetes Service or by specifying the upstream protocol in the HTTPProxy [`services`][10] field.
   307  Applying the `projectcontour.io/upstream-protocol.tls` annotation to a Service object tells Contour that TLS should be enabled and which port should be used for the TLS connection.
   308  The same configuration can be specified by setting the protocol name in the `spec.routes.services[].protocol` field on the HTTPProxy object.
   309  If both the annotation and the protocol field are specified, the protocol field takes precedence.
   310  By default, the upstream TLS server certificate will not be validated, but validation can be requested by setting the `spec.routes.services[].validation` field.
   311  This field has mandatory `caSecret` and `subjectName` fields, which specify the trusted root certificates with which to validate the server certificate and the expected server name.
   312  
   313  _Note: If `spec.routes.services[].validation` is present, `spec.routes.services[].{name,port}` must point to a Service with a matching `projectcontour.io/upstream-protocol.tls` Service annotation._
   314  
   315  In the example below, the upstream service is named `secure-backend` and uses port `8443`:
   316  
   317  ```yaml
   318  # httpproxy-example.yaml
   319  apiVersion: projectcontour.io/v1
   320  kind: HTTPProxy
   321  metadata:
   322    name: example
   323  spec:
   324    virtualhost:
   325      fqdn: www.example.com
   326    routes:
   327    - services:
   328      - name: secure-backend
   329        port: 8443
   330        validation:
   331          caSecret: my-certificate-authority
   332          subjectName: backend.example.com
   333  ```
   334  
   335  ```yaml
   336  # service-secure-backend.yaml
   337  apiVersion: v1
   338  kind: Service
   339  metadata:
   340    name: secure-backend
   341    annotations:
   342      projectcontour.io/upstream-protocol.tls: "8443"
   343  spec:
   344    ports:
   345    - name: https
   346      port: 8443
   347    selector:
   348      app: secure-backend
   349  
   350  ```
   351  
   352  ##### Error conditions
   353  
   354  If the `validation` spec is defined on a service, but the secret which it references does not exist, Contour will reject the update and set the status of the HTTPProxy object accordingly.
   355  This helps prevent the case of proxying to an upstream where validation is requested, but not yet available.
   356  
   357  ```yaml
   358  Status:
   359    Current Status:  invalid
   360    Description:     route "/": service "tls-nginx": upstreamValidation requested but secret not found or misconfigured
   361  ```
   362  
   363  #### TLS Certificate Delegation
   364  
   365  In order to support wildcard certificates, TLS certificates for a `*.somedomain.com`, which are stored in a namespace controlled by the cluster administrator, Contour supports a facility known as TLS Certificate Delegation.
   366  This facility allows the owner of a TLS certificate to delegate, for the purposes of referencing the TLS certificate, permission to Contour to read the Secret object from another namespace.
   367  
   368  The `TLSCertificateDelegation` resource defines a set of `delegations` in the `spec`.
   369  Each delegation references a `secretName` from the namespace where the `TLSCertificateDelegation` is created as well as describing a set of `targetNamespaces` in which the certificate can be referenced.
   370  If all namespaces should be able to reference the secret, then set `"*"` as the value of `targetNamespaces` (see example below).
   371  
   372  ```yaml
   373  apiVersion: projectcontour.io/v1
   374  kind: TLSCertificateDelegation
   375  metadata:
   376    name: example-com-wildcard
   377    namespace: www-admin
   378  spec:
   379    delegations:
   380      - secretName: example-com-wildcard
   381        targetNamespaces:
   382        - example-com
   383      - secretName: another-com-wildcard
   384        targetNamespaces:
   385        - "*"
   386  ---
   387  apiVersion: projectcontour.io/v1
   388  kind: HTTPProxy
   389  metadata:
   390    name: www
   391    namespace: example-com
   392  spec:
   393    virtualhost:
   394      fqdn: foo2.bar.com
   395      tls:
   396        secretName: www-admin/example-com-wildcard
   397    routes:
   398      - services:
   399          - name: s1
   400            port: 80
   401  ```
   402  
   403  In this example, the permission for Contour to reference the Secret `example-com-wildcard` in the `admin` namespace has been delegated to HTTPProxy objects in the `example-com` namespace.
   404  Also, the permission for Contour to reference the Secret `another-com-wildcard` from all namespaces has been delegated to all HTTPProxy objects in the cluster.
   405  
   406  ### Conditions
   407  
   408  Each Route entry in a HTTPProxy **may** contain one or more conditions.
   409  These conditions are combined with an AND operator on the route passed to Envoy.
   410  
   411  Conditions can be either a `prefix` or a `header` condition.
   412  
   413  #### Prefix conditions
   414  
   415  For `prefix`, this adds a path prefix.
   416  
   417  Up to one prefix condition may be present in any condition block.
   418  
   419  Prefix conditions **must** start with a `/` if they are present.
   420  
   421  #### Header conditions
   422  
   423  For `header` conditions there is one required field, `name`, and five operator fields: `present`, `contains`, `notcontains`, `exact`, and `notexact`.
   424  
   425  - `present` is a boolean and checks that the header is present. The value will not be checked.
   426  
   427  - `contains` is a string, and checks that the header contains the string. `notcontains` similarly checks that the header does *not* contain the string.
   428  
   429  - `exact` is a string, and checks that the header exactly matches the whole string. `notexact` checks that the header does *not* exactly match the whole string.
   430  
   431  ### Routes
   432  
   433  HTTPProxy must have at least one route or include defined.
   434  Paths defined are matched using prefix conditions.
   435  In this example, any requests to `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` will be routed to the Service `s2`.
   436  All other requests to the host `multi-path.bar.com` will be routed to the Service `s1`.
   437  
   438  ```yaml
   439  # httpproxy-multiple-paths.yaml
   440  apiVersion: projectcontour.io/v1
   441  kind: HTTPProxy
   442  metadata:
   443    name: multiple-paths
   444    namespace: default
   445  spec:
   446    virtualhost:
   447      fqdn: multi-path.bar.com
   448    routes:
   449      - conditions:
   450        - prefix: / # matches everything else
   451        services:
   452          - name: s1
   453            port: 80
   454      - conditions:
   455        - prefix: /blog # matches `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*`
   456        services:
   457          - name: s2
   458            port: 80
   459  ```
   460  
   461  In the following example, we match on headers and send to different services, with a default route if those do not match.
   462  
   463  ```yaml
   464  # httpproxy-multiple-headers.yaml
   465  apiVersion: projectcontour.io/v1
   466  kind: HTTPProxy
   467  metadata:
   468    name: multiple-paths
   469    namespace: default
   470  spec:
   471    virtualhost:
   472      fqdn: multi-path.bar.com
   473    routes:
   474      - conditions:
   475        - header:
   476            name: x-os
   477            contains: ios
   478        services:
   479          - name: s1
   480            port: 80
   481      - conditions:
   482        - header:
   483            name: x-os
   484            contains: android
   485        services:
   486          - name: s2
   487            port: 80
   488      - services:
   489          - name: s3
   490            port: 80
   491  ```
   492  
   493  #### Multiple Upstreams
   494  
   495  One of the key HTTPProxy features is the ability to support multiple services for a given path:
   496  
   497  ```yaml
   498  # httpproxy-multiple-upstreams.yaml
   499  apiVersion: projectcontour.io/v1
   500  kind: HTTPProxy
   501  metadata:
   502    name: multiple-upstreams
   503    namespace: default
   504  spec:
   505    virtualhost:
   506      fqdn: multi.bar.com
   507    routes:
   508      - services:
   509          - name: s1
   510            port: 80
   511          - name: s2
   512            port: 80
   513  ```
   514  
   515  In this example, requests for `multi.bar.com/` will be load balanced across two Kubernetes Services, `s1`, and `s2`.
   516  This is helpful when you need to split traffic for a given URL across two different versions of an application.
   517  
   518  #### Upstream Weighting
   519  
   520  Building on multiple upstreams is the ability to define relative weights for upstream Services.
   521  This is commonly used for canary testing of new versions of an application when you want to send a small fraction of traffic to a specific Service.
   522  
   523  ```yaml
   524  # httpproxy-weight-shfiting.yaml
   525  apiVersion: projectcontour.io/v1
   526  kind: HTTPProxy
   527  metadata:
   528    name: weight-shifting
   529    namespace: default
   530  spec:
   531    virtualhost:
   532      fqdn: weights.bar.com
   533    routes:
   534      - services:
   535          - name: s1
   536            port: 80
   537            weight: 10
   538          - name: s2
   539            port: 80
   540            weight: 90
   541  ```
   542  
   543  In this example, we are sending 10% of the traffic to Service `s1`, while Service `s2` receives the remaining 90% of traffic.
   544  
   545  HTTPProxy weighting follows some specific rules:
   546  
   547  - If no weights are specified for a given route, it's assumed even distribution across the Services.
   548  - Weights are relative and do not need to add up to 100. If all weights for a route are specified, then the "total" weight is the sum of those specified. As an example, if weights are 20, 30, 20 for three upstreams, the total weight would be 70. In this example, a weight of 30 would receive approximately 42.9% of traffic (30/70 = .4285).
   549  - If some weights are specified but others are not, then it's assumed that upstreams without weights have an implicit weight of zero, and thus will not receive traffic.
   550  
   551  #### Request and Response Header Policies
   552  
   553  Manipulating headers is also supported per-Service or per-Route.  Headers can be set or
   554  removed from the request or response as follows:
   555  
   556  per-Service:
   557  
   558  ```yaml
   559  apiVersion: projectcontour.io/v1
   560  kind: HTTPProxy
   561  metadata:
   562    name: header-manipulation
   563    namespace: default
   564  spec:
   565    virtualhost:
   566      fqdn: headers.bar.com
   567    routes:
   568      - services:
   569          - name: s1
   570            port: 80
   571            requestHeadersPolicy:
   572              set:
   573                - name: X-Foo
   574                  value: bar
   575              remove:
   576                - X-Baz
   577            responseHeadersPolicy:
   578              set:
   579                - name: X-Service-Name
   580                  value: s1
   581              remove:
   582                - X-Internal-Secret
   583  ```
   584  
   585  per-Route:
   586  
   587  ```yaml
   588  apiVersion: projectcontour.io/v1
   589  kind: HTTPProxy
   590  metadata:
   591    name: header-manipulation
   592    namespace: default
   593  spec:
   594    virtualhost:
   595      fqdn: headers.bar.com
   596    routes:
   597      - services:
   598          - name: s1
   599            port: 80
   600        requestHeadersPolicy:
   601          set:
   602            - name: X-Foo
   603              value: bar
   604          remove:
   605            - X-Baz
   606        responseHeadersPolicy:
   607          set:
   608            - name: X-Service-Name
   609              value: s1
   610          remove:
   611            - X-Internal-Secret
   612  ```
   613  
   614  In these examples we are setting the header `X-Foo` with value `baz` on requests
   615  and stripping `X-Baz`.  We are then setting `X-Service-Name` on the response with
   616  value `s1`, and removing `X-Internal-Secret`.
   617  
   618  #### Traffic mirroring
   619  
   620  Per route a service can be nominated as a mirror.
   621  The mirror service will receive a copy of the read traffic sent to any non mirror service.
   622  The mirror traffic is considered _read only_, any response by the mirror will be discarded.
   623  
   624  This service can be useful for recording traffic for later replay or for smoke testing new deployments.
   625  
   626  ```yaml
   627  apiVersion: projectcontour.io/v1
   628  kind: HTTPProxy
   629  metadata:
   630    name: traffic-mirror
   631    namespace: default
   632  spec:
   633    virtualhost:
   634      fqdn: www.example.com
   635    routes:
   636      - conditions:
   637        - prefix: /
   638        services:
   639          - name: www
   640            port: 80
   641          - name: www-mirror
   642            port: 80
   643            mirror: true
   644  ```
   645  
   646  #### Response Timeout
   647  
   648  Each Route can be configured to have a timeout policy and a retry policy as shown:
   649  
   650  ```yaml
   651  # httpproxy-response-timeout.yaml
   652  apiVersion: projectcontour.io/v1
   653  kind: HTTPProxy
   654  metadata:
   655    name: response-timeout
   656    namespace: default
   657  spec:
   658    virtualhost:
   659      fqdn: timeout.bar.com
   660    routes:
   661    - timeoutPolicy:
   662        response: 1s
   663        idle: 10s
   664      retryPolicy:
   665        count: 3
   666        perTryTimeout: 150ms
   667      services:
   668      - name: s1
   669        port: 80
   670  ```
   671  
   672  In this example, requests to `timeout.bar.com/` will have a response timeout policy of 1s.
   673  This refers to the time that spans between the point at which complete client request has been processed by the proxy, and when the response from the server has been completely processed.
   674  
   675  - `timeoutPolicy.response` This field can be any positive time period or "infinity".
   676  This timeout covers the time from the *end of the client request* to the *end of the upstream response*.
   677  By default, Envoy has a 15 second value for this timeout.
   678  More information can be found in [Envoy's documentation][4].
   679  Note that a value of **0s** will be treated as if the field were not set, i.e. by using Envoy's default behavior.
   680  - `timeoutPolicy.idle` This field can be any positive time period or "infinity".
   681  By default, there is no per-route idle timeout.
   682  Note that the default connection manager idle timeout of 5 minutes will apply if this is not set.
   683  More information can be found in [Envoy's documentation][6].
   684  Note that a value of **0s** will be treated as if the field were not set, i.e. by using Envoy's default behavior.
   685  
   686  TimeoutPolicy durations are expressed as per the format specified in the [ParseDuration documentation][5].
   687  Example input values: "300ms", "5s", "1m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
   688  The string 'infinity' is also a valid input and specifies no timeout.
   689  
   690  - `retryPolicy`: A retry will be attempted if the server returns an error code in the 5xx range, or if the server takes more than `retryPolicy.perTryTimeout` to process a request.
   691    - `retryPolicy.count` specifies the maximum number of retries allowed. This parameter is optional and defaults to 1.
   692    - `retryPolicy.perTryTimeout` specifies the timeout per retry. If this field is greater than the request timeout, it is ignored. This parameter is optional.
   693    If left unspecified, `timeoutPolicy.request` will be used.
   694  
   695  #### Load Balancing Strategy
   696  
   697  Each route can have a load balancing strategy applied to determine which of its Endpoints is selected for the request.
   698  The following list are the options available to choose from:
   699  
   700  - `RoundRobin`: Each healthy upstream Endpoint is selected in round robin order (Default strategy if none selected).
   701  - `WeightedLeastRequest`: The least request strategy uses an O(1) algorithm which selects two random healthy Endpoints and picks the Endpoint which has fewer active requests. Note: This algorithm is simple and sufficient for load testing. It should not be used where true weighted least request behavior is desired.
   702  - `Random`: The random strategy selects a random healthy Endpoints.
   703  
   704  More information on the load balancing strategy can be found in [Envoy's documentation][7].
   705  
   706  The following example defines the strategy for the route `/` as `WeightedLeastRequest`.
   707  
   708  ```yaml
   709  # httpproxy-lb-strategy.yaml
   710  apiVersion: projectcontour.io/v1
   711  kind: HTTPProxy
   712  metadata:
   713    name: lb-strategy
   714    namespace: default
   715  spec:
   716    virtualhost:
   717      fqdn: strategy.bar.com
   718    routes:
   719      - conditions:
   720        - prefix: /
   721        services:
   722          - name: s1-strategy
   723            port: 80
   724          - name: s2-strategy
   725            port: 80
   726        loadBalancerPolicy:
   727          strategy: WeightedLeastRequest
   728  ```
   729  
   730  #### Session Affinity
   731  
   732  Session affinity, also known as _sticky sessions_, is a load balancing strategy whereby a sequence of requests from a single client are consistently routed to the same application backend.
   733  Contour supports session affinity on a per route basis with `loadBalancerPolicy` `strategy: Cookie`.
   734  
   735  ```yaml
   736  # httpproxy-sticky-sessions.yaml
   737  apiVersion: projectcontour.io/v1
   738  kind: HTTPProxy
   739  metadata:
   740    name: httpbin
   741    namespace: default
   742  spec:
   743    virtualhost:
   744      fqdn: httpbin.davecheney.com
   745    routes:
   746    - services:
   747      - name: httpbin
   748        port: 8080
   749      loadBalancerPolicy:
   750        strategy: Cookie
   751  ```
   752  
   753  ##### Limitations
   754  
   755  Session affinity is based on the premise that the backend servers are robust, do not change ordering, or grow and shrink according to load.
   756  None of these properties are guaranteed by a Kubernetes cluster and will be visible to applications that rely heavily on session affinity.
   757  
   758  Any perturbation in the set of pods backing a service risks redistributing backends around the hash ring.
   759  
   760  #### Per route health checking
   761  
   762  Active health checking can be configured on a per route basis.
   763  Contour supports HTTP health checking and can be configured with various settings to tune the behavior.
   764  
   765  During HTTP health checking Envoy will send an HTTP request to the upstream Endpoints.
   766  It expects a 200 response if the host is healthy.
   767  The upstream host can return 503 if it wants to immediately notify Envoy to no longer forward traffic to it.
   768  It is important to note that these are health checks which Envoy implements and are separate from any other system such as those that exist in Kubernetes.
   769  
   770  ```yaml
   771  # httpproxy-health-checks.yaml
   772  apiVersion: projectcontour.io/v1
   773  kind: HTTPProxy
   774  metadata:
   775    name: health-check
   776    namespace: default
   777  spec:
   778    virtualhost:
   779      fqdn: health.bar.com
   780    routes:
   781    - conditions:
   782      - prefix: /
   783      healthCheckPolicy:
   784        path: /healthy
   785        intervalSeconds: 5
   786        timeoutSeconds: 2
   787        unhealthyThresholdCount: 3
   788        healthyThresholdCount: 5
   789      services:
   790        - name: s1-health
   791          port: 80
   792        - name: s2-health
   793          port: 80
   794  ```
   795  
   796  Health check configuration parameters:
   797  
   798  - `path`: HTTP endpoint used to perform health checks on upstream service (e.g. `/healthz`). It expects a 200 response if the host is healthy. The upstream host can return 503 if it wants to immediately notify downstream hosts to no longer forward traffic to it.
   799  - `host`: The value of the host header in the HTTP health check request. If left empty (default value), the name "contour-envoy-healthcheck" will be used.
   800  - `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set.
   801  - `timeoutSeconds`: The time to wait (seconds) for a health check response. If the timeout is reached the health check attempt will be considered a failure. Defaults to 2 seconds if not set.
   802  - `unhealthyThresholdCount`: The number of unhealthy health checks required before a host is marked unhealthy. Note that for http health checking if a host responds with 503 this threshold is ignored and the host is considered unhealthy immediately. Defaults to 3 if not defined.
   803  - `healthyThresholdCount`: The number of healthy health checks required before a host is marked healthy. Note that during startup, only a single successful health check is required to mark a host healthy.
   804  
   805  #### WebSocket Support
   806  
   807  WebSocket support can be enabled on specific routes using the `enableWebsockets` field:
   808  
   809  ```yaml
   810  # httpproxy-websockets.yaml
   811  apiVersion: projectcontour.io/v1
   812  kind: HTTPProxy
   813  metadata:
   814    name: chat
   815    namespace: default
   816  spec:
   817    virtualhost:
   818      fqdn: chat.example.com
   819    routes:
   820      - services:
   821          - name: chat-app
   822            port: 80
   823      - conditions:
   824        - prefix: /websocket
   825        enableWebsockets: true # Setting this to true enables websocket for all paths that match /websocket
   826        services:
   827          - name: chat-app
   828            port: 80
   829  ```
   830  
   831  #### Permit Insecure
   832  
   833  A HTTPProxy can be configured to permit insecure requests to specific Routes.
   834  In this example, any request to `foo2.bar.com/blog` will not receive a 301 redirect to HTTPS, but the `/` route will:
   835  
   836  ```yaml
   837  apiVersion: projectcontour.io/v1
   838  kind: HTTPProxy
   839  metadata:
   840    name: tls-example-insecure
   841    namespace: default
   842  spec:
   843    virtualhost:
   844      fqdn: foo2.bar.com
   845      tls:
   846        secretName: testsecret
   847    routes:
   848      - services:
   849          - name: s1
   850            port: 80
   851      - conditions:
   852        - prefix: /blog
   853        permitInsecure: true
   854        services:
   855          - name: s2
   856            port: 80
   857  ```
   858  
   859  #### Path Rewriting
   860  
   861  HTTPProxy supports rewriting the HTTP request URL path prior to delivering the request to the backend service.
   862  Rewriting is performed after a routing decision has been made, and never changes the request destination.
   863  
   864  The `pathRewritePolicy` field specifies how the path prefix should be rewritten.
   865  The `replacePrefix` rewrite policy specifies a replacement string for a HTTP request path prefix match.
   866  When this field is present, the path prefix that the request matched is replaced by the text specified in the `replacement` field.
   867  If the HTTP request path is longer than the matched prefix, the remainder of the path is unchanged.
   868  
   869  ```yaml
   870  apiVersion: projectcontour.io/v1
   871  kind: HTTPProxy
   872  metadata:
   873    name: rewrite-example
   874    namespace: default
   875  spec:
   876    virtualhost:
   877      fqdn: rewrite.bar.com
   878    routes:
   879    - services:
   880      - name: s1
   881        port: 80
   882      pathRewritePolicy:
   883        replacePrefix:
   884        - replacement: /new/prefix
   885  ```
   886  
   887  The `replacePrefix` field accepts an array of possible replacements.
   888  When more than one `replacePrefix` array element is present, the `prefix` field can be used to disambiguate which replacement to apply.
   889  
   890  If no `prefix` field is present, the replacement is applied to all prefix matches made against the route.
   891  If a `prefix` field is present, the replacement is applied only to routes that have an exactly matching [prefix condition](#prefix-conditions).
   892  Specifying more than one `replacePrefix` entry is mainly useful when a HTTPProxy document is included into multiple parent documents.
   893  
   894  ```yaml
   895  apiVersion: projectcontour.io/v1
   896  kind: HTTPProxy
   897  metadata:
   898    name: rewrite-example
   899    namespace: default
   900  spec:
   901    virtualhost:
   902      fqdn: rewrite.bar.com
   903    routes:
   904    - services:
   905      - name: s1
   906        port: 80
   907      conditions:
   908      - prefix: /v1/api
   909      pathRewritePolicy:
   910        replacePrefix:
   911        - prefix: /v1/api
   912          replacement: /app/api/v1
   913        - prefix: /
   914          replacement: /app
   915  ```
   916  
   917  ### Header Policy
   918  
   919  HTTPProxy supports rewriting HTTP request and response headers.
   920  The `Set` operation sets a HTTP header value, creating it if it doesn't already exist or overwriting it if it does.
   921  The `Remove` operation removes a HTTP header.
   922  The `requestHeadersPolicy` field is used to rewrite headers on a HTTP request, and the `responseHeadersPolicy` is used to rewrite headers on a HTTP response.
   923  These fields can be specified on a route or on a specific service, depending on the rewrite granularity you need.
   924  
   925  
   926  ```yaml
   927  apiVersion: projectcontour.io/v1
   928  kind: HTTPProxy
   929  metadata:
   930    name: header-rewrite-example
   931  spec:
   932    virtualhost:
   933      fqdn: header.bar.com
   934    routes:
   935    - services:
   936      - name: s1
   937        port: 80
   938      requestHeadersPolicy:
   939        set:
   940        - name: Host
   941          value: external.dev
   942        remove:
   943        - Some-Header
   944        - Some-Other-Header
   945  ```
   946  
   947  ### ExternalName
   948  
   949  HTTPProxy supports routing traffic to `ExternalName` service types.
   950  Contour looks at the `spec.externalName` field of the service and configures the route to use that DNS name instead of utilizing EDS.
   951  
   952  There's nothing specific in the HTTPProxy object that needs to be configured other than referencing a service of type `ExternalName`.
   953  HTTPProxy supports the `requestHeadersPolicy` field to rewrite the `Host` header after first handling a request and before proxying to an upstream service.
   954  This field can be used to ensure that the forwarded HTTP request contains the hostname that the external resource is expecting.
   955  
   956  NOTE: The ports are required to be specified.
   957  
   958  ```yaml
   959  # httpproxy-externalname.yaml
   960  apiVersion: v1
   961  kind: Service
   962  metadata:
   963    labels:
   964      run: externaldns
   965    name: externaldns
   966    namespace: default
   967  spec:
   968    externalName: foo-basic.bar.com
   969    ports:
   970    - name: http
   971      port: 80
   972      protocol: TCP
   973      targetPort: 80
   974    type: ExternalName
   975  ```
   976  
   977  #### Proxy to external resource
   978  
   979  To proxy to another resource outside the cluster (e.g. A hosted object store bucket for example), configure that external resource in a service type `externalName`.
   980  Then define a `requestHeadersPolicy` which replaces the `Host` header with the value of the external name service defined previously.
   981  Finally, if the upstream service is served over TLS, set the `protocol` field on the service to `tls` or annotate the external name service with: `projectcontour.io/upstream-protocol.tls: 443,https` assuming your service had a port 443 and name `https`.
   982  
   983  ## HTTPProxy inclusion
   984  
   985  HTTPProxy permits the splitting of a system's configuration into separate HTTPProxy instances using **inclusion**.
   986  
   987  Inclusion, as the name implies, allows for one HTTPProxy object to be included in another, optionally with some conditions inherited from the parent.
   988  Contour reads the inclusion tree and merges the included routes into one big object internally before rendering Envoy config.
   989  Importantly, the included HTTPProxy objects do not have to be in the same namespace, so this is functionally the same as the delegation feature of the now-deprecated IngressRoute.
   990  
   991  Each tree of HTTPProxy starts with a root, the top level object of the configuration for a particular virtual host.
   992  Each root HTTPProxy defines a `virtualhost` key, which describes properties such as the fully qualified name of the virtual host, TLS configuration, etc.
   993  
   994  HTTPProxies included from the root must not contain a virtualhost key.
   995  Root objects cannot include other roots either transitively or directly.
   996  This permits the owner of an HTTPProxy root to allow the inclusion of a portion of the route space inside a virtual host, and to allow that route space to be further subdivided with inclusions.
   997  Because the path is not necessarily used as the only key, the route space can be multi-dimensional.
   998  
   999  ### Conditions and Inclusion
  1000  
  1001  Like Routes, Inclusion may specify a set of [conditions][8].
  1002  These conditions are added to any conditions on the routes included.
  1003  This process is recursive.
  1004  
  1005  Conditions are sets of individual condition statements, for example `prefix: /blog` is the condition that the matching request's path must start with `/blog`.
  1006  When conditions are combined through inclusion Contour merges the conditions inherited via inclusion with any conditions specified on the route.
  1007  This may result in duplicates, for example two `prefix:` conditions, or two header match conditions with the same name and value.
  1008  To resolve this Contour applies the following logic.
  1009  
  1010  - `prefix:` conditions are concatenated together in the order they were applied from the root object. For example the conditions, `prefix: /api`, `prefix: /v1` becomes a single `prefix: /api/v1` conditions. Note: Multiple prefixes cannot be supplied on a single set of Route conditions.
  1011  - Proxies with repeated identical `header:` conditions of type "exact match" (the same header keys exactly) are marked as "Invalid" since they create an un-routable configuration.
  1012  
  1013  ### Configuring inclusion
  1014  
  1015  Inclusion is a top-level part of the HTTPProxy `spec` element.
  1016  It requires one field, `name`, and has two optional fields:
  1017  
  1018  - `namespace`. This will assume the included HTTPProxy is in the same namespace if it's not specified.
  1019  - a `conditions` block.
  1020  
  1021  #### Within the same namespace
  1022  
  1023  HTTPProxies can include other HTTPProxy objects in the namespace by specifying the name of the object and its namespace in the top-level `includes` block.
  1024  Note that `includes` is a list, and so it must use the YAML list construct.
  1025  
  1026  In this example, the HTTPProxy `include-root` has included the configuration for paths matching `/service2` from the HTTPProxy named `service2` in the same namespace as `include-root` (the `default` namespace).
  1027  It's important to note that `service2` HTTPProxy has not defined a `virtualhost` property as it is NOT a root HTTPProxy.
  1028  
  1029  ```yaml
  1030  # httpproxy-inclusion-samenamespace.yaml
  1031  apiVersion: projectcontour.io/v1
  1032  kind: HTTPProxy
  1033  metadata:
  1034    name: include-root
  1035    namespace: default
  1036  spec:
  1037    virtualhost:
  1038      fqdn: root.bar.com
  1039    includes:
  1040    # Includes the /service2 path from service2 in the same namespace
  1041    - name: service2
  1042      namespace: default
  1043      conditions:
  1044      - prefix: /service2
  1045    routes:
  1046      - conditions:
  1047        - prefix: /
  1048        services:
  1049          - name: s1
  1050            port: 80
  1051  ---
  1052  apiVersion: projectcontour.io/v1
  1053  kind: HTTPProxy
  1054  metadata:
  1055    name: service2
  1056    namespace: default
  1057  spec:
  1058    routes:
  1059      - services: # matches /service2
  1060          - name: s2
  1061            port: 80
  1062      - conditions:
  1063        - prefix: /blog # matches /service2/blog
  1064        services:
  1065          - name: blog
  1066            port: 80
  1067  ```
  1068  
  1069  #### Virtualhost aliases
  1070  
  1071  To present the same set of routes under multiple dns entries, for example www.example.com and example.com, including a service with a `prefix` condition of `/` can be used.
  1072  
  1073  ```yaml
  1074  # httpproxy-inclusion-multipleroots.yaml
  1075  ---
  1076  apiVersion: projectcontour.io/v1
  1077  kind: HTTPProxy
  1078  metadata:
  1079    name: multiple-root
  1080    namespace: default
  1081  spec:
  1082    virtualhost:
  1083      fqdn: bar.com
  1084    includes:
  1085    - name: main
  1086      namespace: default
  1087  ---
  1088  apiVersion: projectcontour.io/v1
  1089  kind: HTTPProxy
  1090  metadata:
  1091    name: multiple-root-www
  1092    namespace: default
  1093  spec:
  1094    virtualhost:
  1095      fqdn: www.bar.com
  1096    includes:
  1097    - name: main
  1098      namespace: default
  1099  ---
  1100  apiVersion: projectcontour.io/v1
  1101  kind: HTTPProxy
  1102  metadata:
  1103    name: main
  1104    namespace: default
  1105  spec:
  1106    routes:
  1107    - services:
  1108      - name: s2
  1109        port: 80
  1110  ```
  1111  
  1112  #### Across namespaces
  1113  
  1114  Inclusion can also happen across Namespaces by specifying a `namespace` in the `inclusion`.
  1115  This is a particularly powerful paradigm for enabling multi-team Ingress management.
  1116  
  1117  In this example, the root HTTPProxy has included configuration for paths matching `/blog` to the `blog` HTTPProxy object in the `marketing` namespace.
  1118  
  1119  ```yaml
  1120  # httpproxy-inclusion-across-namespaces.yaml
  1121  ---
  1122  apiVersion: projectcontour.io/v1
  1123  kind: HTTPProxy
  1124  metadata:
  1125    name: namespace-include-root
  1126    namespace: default
  1127  spec:
  1128    virtualhost:
  1129      fqdn: ns-root.bar.com
  1130    includes:
  1131    # delegate the subpath, `/blog` to the IngressRoute object in the marketing namespace with the name `blog`
  1132    - name: blog
  1133      namespace: marketing
  1134      conditions:
  1135      - prefix: /blog
  1136    routes:
  1137      - services:
  1138          - name: s1
  1139            port: 80
  1140  
  1141  ---
  1142  apiVersion: projectcontour.io/v1
  1143  kind: HTTPProxy
  1144  metadata:
  1145    name: blog
  1146    namespace: marketing
  1147  spec:
  1148    routes:
  1149      - services:
  1150          - name: s2
  1151            port: 80
  1152  ```
  1153  
  1154  ### Orphaned HTTPProxy children
  1155  
  1156  It is possible for HTTPProxy objects to exist that have not been delegated to by another HTTPProxy.
  1157  These objects are considered "orphaned" and will be ignored by Contour in determining ingress configuration.
  1158  
  1159  ### Restricted root namespaces
  1160  
  1161  HTTPProxy inclusion allows for Administrators to limit which users/namespaces may configure routes for a given domain, but it does not restrict where root HTTPProxy may be created.
  1162  Contour has an enforcing mode which accepts a list of namespaces where root HTTPProxy are valid.
  1163  Only users permitted to operate in those namespaces can therefore create HTTPProxy with the `virtualhost` field.
  1164  
  1165  This restricted mode is enabled in Contour by specifying a command line flag, `--root-namespaces`, which will restrict Contour to only searching the defined namespaces for root HTTPProxy. This CLI flag accepts a comma separated list of namespaces where HTTPProxy are valid (e.g. `--root-namespaces=default,kube-system,my-admin-namespace`).
  1166  
  1167  HTTPProxy with a defined `virtualhost` field that are not in one of the allowed root namespaces will be flagged as `invalid` and will be ignored by Contour.
  1168  
  1169  Additionally, when defined, Contour will only watch for Kubernetes secrets in these namespaces ignoring changes in all other namespaces.
  1170  Proper RBAC rules should also be created to restrict what namespaces Contour has access matching the namespaces passed to the command line flag.
  1171  An example of this is included in the [examples directory][1] and shows how you might create a namespace called `root-httproxies`.
  1172  
  1173  > **NOTE: The restricted root namespace feature is only supported for HTTPProxy CRDs.
  1174  > `--root-namespaces` does not affect the operation of `v1beta1.Ingress` objects**
  1175  
  1176  ## TCP Proxying
  1177  
  1178  HTTPProxy supports proxying of TLS encapsulated TCP sessions.
  1179  
  1180  _Note_: The TCP session must be encrypted with TLS.
  1181  This is necessary so that Envoy can use SNI to route the incoming request to the correct service.
  1182  
  1183  ### TLS Termination at the edge
  1184  
  1185  If `spec.virtualhost.tls.secretName` is present then that secret will be used to decrypt the TCP traffic at the edge.
  1186  
  1187  ```yaml
  1188  # httpproxy-tls-termination.yaml
  1189  apiVersion: projectcontour.io/v1
  1190  kind: HTTPProxy
  1191  metadata:
  1192    name: example
  1193    namespace: default
  1194  spec:
  1195    virtualhost:
  1196      fqdn: tcp.example.com
  1197      tls:
  1198        secretName: secret
  1199    tcpproxy:
  1200      services:
  1201      - name: tcpservice
  1202        port: 8080
  1203      - name: otherservice
  1204        port: 9999
  1205        weight: 20
  1206  ```
  1207  
  1208  The `spec.tcpproxy` key indicates that this _root_ HTTPProxy will forward the de-encrypted TCP traffic to the backend service.
  1209  
  1210  ### TLS passthrough to the backend service
  1211  
  1212  If you wish to handle the TLS handshake at the backend service set `spec.virtualhost.tls.passthrough: true` indicates that once SNI demuxing is performed, the encrypted connection will be forwarded to the backend service.
  1213  The backend service is expected to have a key which matches the SNI header received at the edge, and be capable of completing the TLS handshake. This is called SSL/TLS Passthrough.
  1214  
  1215  ```yaml
  1216  # httpproxy-tls-passthrough.yaml
  1217  apiVersion: projectcontour.io/v1
  1218  kind: HTTPProxy
  1219  metadata:
  1220    name: example
  1221    namespace: default
  1222  spec:
  1223    virtualhost:
  1224      fqdn: tcp.example.com
  1225      tls:
  1226        passthrough: true
  1227    tcpproxy:
  1228      services:
  1229      - name: tcpservice
  1230        port: 8080
  1231      - name: otherservice
  1232        port: 9999
  1233        weight: 20
  1234  ```
  1235  
  1236  ### TCPProxy delegation
  1237  
  1238  There can be at most one TCPProxy stanza per root HTTPProxy, however that TCPProxy does not need to be defined in the root HTTPProxy object.
  1239  HTTPProxy authors can delegate the configuration of a TCPProxy to the TCPProxy configuration defined in a HTTPProxy child object.
  1240  
  1241  ```yaml
  1242  # httpproxy-parent-termination.yaml
  1243  apiVersion: projectcontour.io/v1
  1244  kind: HTTPProxy
  1245  metadata:
  1246    name: parent
  1247    namespace: default
  1248  spec:
  1249    virtualhost:
  1250      fqdn: tcp.example.com
  1251      tls:
  1252        secretName: secret
  1253    tcpproxy:
  1254      include:
  1255        name: child
  1256        namespace: app
  1257  ---
  1258  # httpproxy-child-termination.yaml
  1259  apiVersion: projectcontour.io/v1
  1260  kind: HTTPProxy
  1261  metadata:
  1262    name: child
  1263    namespace: app
  1264  spec:
  1265    tcpproxy:
  1266      services:
  1267      - name: tcpservice
  1268        port: 8080
  1269      - name: otherservice
  1270        port: 9999
  1271        weight: 20
  1272  ```
  1273  In this example `default/parent` delegates the configuration of the TCPProxy services to `app/child`.
  1274  
  1275  #### TCP Proxy health checking
  1276  
  1277  Active health checking can be configured on a per route basis.
  1278  Contour supports TCP health checking and can be configured with various settings to tune the behavior.
  1279  
  1280  During TCP health checking Envoy will send a connect-only health check to the upstream Endpoints.
  1281  It is important to note that these are health checks which Envoy implements and are separate from any
  1282  other system such as those that exist in Kubernetes.
  1283  
  1284  ```yaml
  1285  apiVersion: projectcontour.io/v1
  1286  kind: HTTPProxy
  1287  metadata:
  1288    name: tcp-health-check
  1289    namespace: default
  1290  spec:
  1291    virtualhost:
  1292      fqdn: health.bar.com
  1293    tcpproxy:
  1294      healthCheckPolicy:
  1295        intervalSeconds: 5
  1296        timeoutSeconds: 2
  1297        unhealthyThresholdCount: 3
  1298        healthyThresholdCount: 5
  1299      services:
  1300        - name: s1-health
  1301          port: 80
  1302        - name: s2-health
  1303          port: 80
  1304  ```
  1305  
  1306  TCP Health check policy configuration parameters:
  1307  
  1308  - `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set.
  1309  - `timeoutSeconds`: The time to wait (seconds) for a health check response. If the timeout is reached the health check attempt will be considered a failure. Defaults to 2 seconds if not set.
  1310  - `unhealthyThresholdCount`: The number of unhealthy health checks required before a host is marked unhealthy. Note that for http health checking if a host responds with 503 this threshold is ignored and the host is considered unhealthy immediately. Defaults to 3 if not defined.
  1311  - `healthyThresholdCount`: The number of healthy health checks required before a host is marked healthy. Note that during startup, only a single successful health check is required to mark a host healthy.
  1312  
  1313  ## Upstream Validation
  1314  
  1315  When defining upstream services on a route, it's possible to configure the connection from Envoy to the backend endpoint to communicate over TLS.
  1316  Two configuration items are required, a CA certificate and a `SubjectName` which are both used to verify the backend endpoint's identity.
  1317  
  1318  The CA certificate bundle for the backend service should be supplied in a Kubernetes Secret.
  1319  The referenced Secret must be of type "Opaque" and have a data key named `ca.crt`.
  1320  This data value must be a PEM-encoded certificate bundle.
  1321  
  1322  In addition to the CA certificate and the subject name, the Kubernetes service must also be annotated with a Contour specific annotation: `projectcontour.io/upstream-protocol.tls: <port>` ([see annotations section][9])
  1323  
  1324  _Note: This annotation is applied to the Service not the Ingress or HTTPProxy object._
  1325  
  1326  ```yaml
  1327  apiVersion: projectcontour.io/v1
  1328  kind: HTTPProxy
  1329  metadata:
  1330    name: blog
  1331    namespace: marketing
  1332  spec:
  1333    routes:
  1334      - services:
  1335          - name: s2
  1336            port: 80
  1337            validation:
  1338              caSecret: foo-ca-cert
  1339              subjectName: foo.marketing
  1340  ```
  1341  
  1342  ## Client Certificate Validation
  1343  
  1344  It is possible to protect the backend service from unauthorized external clients by requiring the client to present a valid TLS certificate.
  1345  Envoy will validate the client certificate by verifying that it is not expired and that a chain of trust can be established to the configured trusted root CA certificate.
  1346  Only those requests with a valid client certificate will be accepted and forwarded to the backend service.
  1347  
  1348  ```yaml
  1349  apiVersion: projectcontour.io/v1
  1350  kind: HTTPProxy
  1351  metadata:
  1352    name: with-client-auth
  1353  spec:
  1354    virtualhost:
  1355      fqdn: www.example.com
  1356      tls:
  1357        secretName: secret
  1358        clientValidation:
  1359          caSecret: client-root-ca
  1360    routes:
  1361      - services:
  1362          - name: s1
  1363            port: 80
  1364  ```
  1365  
  1366  The preceding example enables validation by setting the optional `clientValidation` attribute.
  1367  Its mandatory attribute `caSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have a data key named `ca.crt`.
  1368  The data value of the key `ca.crt` must be a PEM-encoded certificate bundle and it must contain all the trusted CA certificates that are to be used for validating the client certificate.
  1369  
  1370  ## Status Reporting
  1371  
  1372  There are many misconfigurations that could cause an HTTPProxy or delegation to be invalid.
  1373  To aid users in resolving these issues, Contour updates a `status` field in all HTTPProxy objects.
  1374  In the current specification, invalid HTTPProxy are ignored by Contour and will not be used in the ingress routing configuration.
  1375  
  1376  If an HTTPProxy object is valid, it will have a status property that looks like this:
  1377  
  1378  ```yaml
  1379  status:
  1380    currentStatus: valid
  1381    description: valid HTTPProxy
  1382  ```
  1383  
  1384  If the HTTPProxy is invalid, the `currentStatus` field will be `invalid` and the `description` field will provide a description of the issue.
  1385  
  1386  As an example, if an HTTPProxy object has specified a negative value for weighting, the HTTPProxy status will be:
  1387  
  1388  ```yaml
  1389  status:
  1390    currentStatus: invalid
  1391    description: "route '/foo': service 'home': weight must be greater than or equal to zero"
  1392  ```
  1393  
  1394  Some examples of invalid configurations that Contour provides statuses for:
  1395  
  1396  - Negative weight provided in the route definition.
  1397  - Invalid port number provided for service.
  1398  - Prefix in parent does not match route in delegated route.
  1399  - Root HTTPProxy created in a namespace other than the allowed root namespaces.
  1400  - A given Route of an HTTPProxy both delegates to another HTTPProxy and has a list of services.
  1401  - Orphaned route.
  1402  - Delegation chain produces a cycle.
  1403  - Root HTTPProxy does not specify fqdn.
  1404  - Multiple prefixes cannot be specified on the same set of route conditions.
  1405  - Multiple header conditions of type "exact match" with the same header key.
  1406  - Contradictory header conditions on a route, e.g. a "contains" and "notcontains" condition for the same header and value.
  1407  
  1408   [1]: https://kubernetes.io/docs/concepts/services-networking/ingress/
  1409   [2]: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md
  1410   [3]: {{< param github_url >}}/tree/{{page.version}}/examples/example-workload/httpproxy
  1411   [4]: https://www.envoyproxy.io/docs/envoy/v1.14.2/api-v2/api/v2/route/route_components.proto#envoy-api-field-route-routeaction-timeout
  1412   [5]: https://godoc.org/time#ParseDuration
  1413   [6]: https://www.envoyproxy.io/docs/envoy/v1.14.2/api-v2/api/v2/route/route_components.proto#envoy-api-field-route-routeaction-idle-timeout
  1414   [7]: https://www.envoyproxy.io/docs/envoy/v1.14.2/intro/arch_overview/upstream/load_balancing/overview
  1415   [8]: #conditions
  1416   [9]: {% link docs/{{page.version}}/annotations.md %}
  1417   [10]: /docs/{{page.version}}/api/#projectcontour.io/v1.Service
  1418   [11]: configuration.md#fallback-certificate
  1419