github.com/projectcontour/contour@v1.28.2/site/content/docs/v1.8.0/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 (which replaces the now-removed 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 tenant 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. Delegation works for both HTTPProxy and Ingress resources. 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. 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 HTTPProxy 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][12] and shows how you might create a namespace called `root-httproxy`. 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 [12]: {{< param github_url >}}/tree/{{page.version}}/examples/root-rbac 1420