github.com/projectcontour/contour@v1.28.2/site/content/docs/v1.8.2/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 ##### Envoy Client Certificate 353 354 Contour can be configured with a `namespace/name` in the [Contour configuration file][11] of a Kubernetes secret which Envoy uses as a client certificate when upstream TLS is configured for the backend. 355 Envoy will send the certificate during TLS handshake when the backend applications request the client to present its certificate. 356 Backend applications can validate the certificate to ensure that the connection is coming from Envoy. 357 358 ##### Error conditions 359 360 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. 361 This helps prevent the case of proxying to an upstream where validation is requested, but not yet available. 362 363 ```yaml 364 Status: 365 Current Status: invalid 366 Description: route "/": service "tls-nginx": upstreamValidation requested but secret not found or misconfigured 367 ``` 368 369 #### TLS Certificate Delegation 370 371 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. 372 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. 373 374 The `TLSCertificateDelegation` resource defines a set of `delegations` in the `spec`. 375 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. 376 If all namespaces should be able to reference the secret, then set `"*"` as the value of `targetNamespaces` (see example below). 377 378 ```yaml 379 apiVersion: projectcontour.io/v1 380 kind: TLSCertificateDelegation 381 metadata: 382 name: example-com-wildcard 383 namespace: www-admin 384 spec: 385 delegations: 386 - secretName: example-com-wildcard 387 targetNamespaces: 388 - example-com 389 - secretName: another-com-wildcard 390 targetNamespaces: 391 - "*" 392 --- 393 apiVersion: projectcontour.io/v1 394 kind: HTTPProxy 395 metadata: 396 name: www 397 namespace: example-com 398 spec: 399 virtualhost: 400 fqdn: foo2.bar.com 401 tls: 402 secretName: www-admin/example-com-wildcard 403 routes: 404 - services: 405 - name: s1 406 port: 80 407 ``` 408 409 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. 410 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. 411 412 ### Conditions 413 414 Each Route entry in a HTTPProxy **may** contain one or more conditions. 415 These conditions are combined with an AND operator on the route passed to Envoy. 416 417 Conditions can be either a `prefix` or a `header` condition. 418 419 #### Prefix conditions 420 421 For `prefix`, this adds a path prefix. 422 423 Up to one prefix condition may be present in any condition block. 424 425 Prefix conditions **must** start with a `/` if they are present. 426 427 #### Header conditions 428 429 For `header` conditions there is one required field, `name`, and five operator fields: `present`, `contains`, `notcontains`, `exact`, and `notexact`. 430 431 - `present` is a boolean and checks that the header is present. The value will not be checked. 432 433 - `contains` is a string, and checks that the header contains the string. `notcontains` similarly checks that the header does *not* contain the string. 434 435 - `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. 436 437 ### Routes 438 439 HTTPProxy must have at least one route or include defined. 440 Paths defined are matched using prefix conditions. 441 In this example, any requests to `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` will be routed to the Service `s2`. 442 All other requests to the host `multi-path.bar.com` will be routed to the Service `s1`. 443 444 ```yaml 445 # httpproxy-multiple-paths.yaml 446 apiVersion: projectcontour.io/v1 447 kind: HTTPProxy 448 metadata: 449 name: multiple-paths 450 namespace: default 451 spec: 452 virtualhost: 453 fqdn: multi-path.bar.com 454 routes: 455 - conditions: 456 - prefix: / # matches everything else 457 services: 458 - name: s1 459 port: 80 460 - conditions: 461 - prefix: /blog # matches `multi-path.bar.com/blog` or `multi-path.bar.com/blog/*` 462 services: 463 - name: s2 464 port: 80 465 ``` 466 467 In the following example, we match on headers and send to different services, with a default route if those do not match. 468 469 ```yaml 470 # httpproxy-multiple-headers.yaml 471 apiVersion: projectcontour.io/v1 472 kind: HTTPProxy 473 metadata: 474 name: multiple-paths 475 namespace: default 476 spec: 477 virtualhost: 478 fqdn: multi-path.bar.com 479 routes: 480 - conditions: 481 - header: 482 name: x-os 483 contains: ios 484 services: 485 - name: s1 486 port: 80 487 - conditions: 488 - header: 489 name: x-os 490 contains: android 491 services: 492 - name: s2 493 port: 80 494 - services: 495 - name: s3 496 port: 80 497 ``` 498 499 #### Multiple Upstreams 500 501 One of the key HTTPProxy features is the ability to support multiple services for a given path: 502 503 ```yaml 504 # httpproxy-multiple-upstreams.yaml 505 apiVersion: projectcontour.io/v1 506 kind: HTTPProxy 507 metadata: 508 name: multiple-upstreams 509 namespace: default 510 spec: 511 virtualhost: 512 fqdn: multi.bar.com 513 routes: 514 - services: 515 - name: s1 516 port: 80 517 - name: s2 518 port: 80 519 ``` 520 521 In this example, requests for `multi.bar.com/` will be load balanced across two Kubernetes Services, `s1`, and `s2`. 522 This is helpful when you need to split traffic for a given URL across two different versions of an application. 523 524 #### Upstream Weighting 525 526 Building on multiple upstreams is the ability to define relative weights for upstream Services. 527 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. 528 529 ```yaml 530 # httpproxy-weight-shfiting.yaml 531 apiVersion: projectcontour.io/v1 532 kind: HTTPProxy 533 metadata: 534 name: weight-shifting 535 namespace: default 536 spec: 537 virtualhost: 538 fqdn: weights.bar.com 539 routes: 540 - services: 541 - name: s1 542 port: 80 543 weight: 10 544 - name: s2 545 port: 80 546 weight: 90 547 ``` 548 549 In this example, we are sending 10% of the traffic to Service `s1`, while Service `s2` receives the remaining 90% of traffic. 550 551 HTTPProxy weighting follows some specific rules: 552 553 - If no weights are specified for a given route, it's assumed even distribution across the Services. 554 - 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). 555 - 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. 556 557 #### Request and Response Header Policies 558 559 Manipulating headers is also supported per-Service or per-Route. Headers can be set or 560 removed from the request or response as follows: 561 562 per-Service: 563 564 ```yaml 565 apiVersion: projectcontour.io/v1 566 kind: HTTPProxy 567 metadata: 568 name: header-manipulation 569 namespace: default 570 spec: 571 virtualhost: 572 fqdn: headers.bar.com 573 routes: 574 - services: 575 - name: s1 576 port: 80 577 requestHeadersPolicy: 578 set: 579 - name: X-Foo 580 value: bar 581 remove: 582 - X-Baz 583 responseHeadersPolicy: 584 set: 585 - name: X-Service-Name 586 value: s1 587 remove: 588 - X-Internal-Secret 589 ``` 590 591 per-Route: 592 593 ```yaml 594 apiVersion: projectcontour.io/v1 595 kind: HTTPProxy 596 metadata: 597 name: header-manipulation 598 namespace: default 599 spec: 600 virtualhost: 601 fqdn: headers.bar.com 602 routes: 603 - services: 604 - name: s1 605 port: 80 606 requestHeadersPolicy: 607 set: 608 - name: X-Foo 609 value: bar 610 remove: 611 - X-Baz 612 responseHeadersPolicy: 613 set: 614 - name: X-Service-Name 615 value: s1 616 remove: 617 - X-Internal-Secret 618 ``` 619 620 In these examples we are setting the header `X-Foo` with value `baz` on requests 621 and stripping `X-Baz`. We are then setting `X-Service-Name` on the response with 622 value `s1`, and removing `X-Internal-Secret`. 623 624 #### Traffic mirroring 625 626 Per route a service can be nominated as a mirror. 627 The mirror service will receive a copy of the read traffic sent to any non mirror service. 628 The mirror traffic is considered _read only_, any response by the mirror will be discarded. 629 630 This service can be useful for recording traffic for later replay or for smoke testing new deployments. 631 632 ```yaml 633 apiVersion: projectcontour.io/v1 634 kind: HTTPProxy 635 metadata: 636 name: traffic-mirror 637 namespace: default 638 spec: 639 virtualhost: 640 fqdn: www.example.com 641 routes: 642 - conditions: 643 - prefix: / 644 services: 645 - name: www 646 port: 80 647 - name: www-mirror 648 port: 80 649 mirror: true 650 ``` 651 652 #### Response Timeout 653 654 Each Route can be configured to have a timeout policy and a retry policy as shown: 655 656 ```yaml 657 # httpproxy-response-timeout.yaml 658 apiVersion: projectcontour.io/v1 659 kind: HTTPProxy 660 metadata: 661 name: response-timeout 662 namespace: default 663 spec: 664 virtualhost: 665 fqdn: timeout.bar.com 666 routes: 667 - timeoutPolicy: 668 response: 1s 669 idle: 10s 670 retryPolicy: 671 count: 3 672 perTryTimeout: 150ms 673 services: 674 - name: s1 675 port: 80 676 ``` 677 678 In this example, requests to `timeout.bar.com/` will have a response timeout policy of 1s. 679 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. 680 681 - `timeoutPolicy.response` This field can be any positive time period or "infinity". 682 This timeout covers the time from the *end of the client request* to the *end of the upstream response*. 683 By default, Envoy has a 15 second value for this timeout. 684 More information can be found in [Envoy's documentation][4]. 685 Note that a value of **0s** will be treated as if the field were not set, i.e. by using Envoy's default behavior. 686 - `timeoutPolicy.idle` This field can be any positive time period or "infinity". 687 By default, there is no per-route idle timeout. 688 Note that the default connection manager idle timeout of 5 minutes will apply if this is not set. 689 More information can be found in [Envoy's documentation][6]. 690 Note that a value of **0s** will be treated as if the field were not set, i.e. by using Envoy's default behavior. 691 692 TimeoutPolicy durations are expressed as per the format specified in the [ParseDuration documentation][5]. 693 Example input values: "300ms", "5s", "1m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". 694 The string 'infinity' is also a valid input and specifies no timeout. 695 696 - `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. 697 - `retryPolicy.count` specifies the maximum number of retries allowed. This parameter is optional and defaults to 1. 698 - `retryPolicy.perTryTimeout` specifies the timeout per retry. If this field is greater than the request timeout, it is ignored. This parameter is optional. 699 If left unspecified, `timeoutPolicy.request` will be used. 700 701 #### Load Balancing Strategy 702 703 Each route can have a load balancing strategy applied to determine which of its Endpoints is selected for the request. 704 The following list are the options available to choose from: 705 706 - `RoundRobin`: Each healthy upstream Endpoint is selected in round robin order (Default strategy if none selected). 707 - `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. 708 - `Random`: The random strategy selects a random healthy Endpoints. 709 710 More information on the load balancing strategy can be found in [Envoy's documentation][7]. 711 712 The following example defines the strategy for the route `/` as `WeightedLeastRequest`. 713 714 ```yaml 715 # httpproxy-lb-strategy.yaml 716 apiVersion: projectcontour.io/v1 717 kind: HTTPProxy 718 metadata: 719 name: lb-strategy 720 namespace: default 721 spec: 722 virtualhost: 723 fqdn: strategy.bar.com 724 routes: 725 - conditions: 726 - prefix: / 727 services: 728 - name: s1-strategy 729 port: 80 730 - name: s2-strategy 731 port: 80 732 loadBalancerPolicy: 733 strategy: WeightedLeastRequest 734 ``` 735 736 #### Session Affinity 737 738 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. 739 Contour supports session affinity on a per route basis with `loadBalancerPolicy` `strategy: Cookie`. 740 741 ```yaml 742 # httpproxy-sticky-sessions.yaml 743 apiVersion: projectcontour.io/v1 744 kind: HTTPProxy 745 metadata: 746 name: httpbin 747 namespace: default 748 spec: 749 virtualhost: 750 fqdn: httpbin.davecheney.com 751 routes: 752 - services: 753 - name: httpbin 754 port: 8080 755 loadBalancerPolicy: 756 strategy: Cookie 757 ``` 758 759 ##### Limitations 760 761 Session affinity is based on the premise that the backend servers are robust, do not change ordering, or grow and shrink according to load. 762 None of these properties are guaranteed by a Kubernetes cluster and will be visible to applications that rely heavily on session affinity. 763 764 Any perturbation in the set of pods backing a service risks redistributing backends around the hash ring. 765 766 #### Per route health checking 767 768 Active health checking can be configured on a per route basis. 769 Contour supports HTTP health checking and can be configured with various settings to tune the behavior. 770 771 During HTTP health checking Envoy will send an HTTP request to the upstream Endpoints. 772 It expects a 200 response if the host is healthy. 773 The upstream host can return 503 if it wants to immediately notify Envoy to no longer forward traffic to it. 774 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. 775 776 ```yaml 777 # httpproxy-health-checks.yaml 778 apiVersion: projectcontour.io/v1 779 kind: HTTPProxy 780 metadata: 781 name: health-check 782 namespace: default 783 spec: 784 virtualhost: 785 fqdn: health.bar.com 786 routes: 787 - conditions: 788 - prefix: / 789 healthCheckPolicy: 790 path: /healthy 791 intervalSeconds: 5 792 timeoutSeconds: 2 793 unhealthyThresholdCount: 3 794 healthyThresholdCount: 5 795 services: 796 - name: s1-health 797 port: 80 798 - name: s2-health 799 port: 80 800 ``` 801 802 Health check configuration parameters: 803 804 - `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. 805 - `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. 806 - `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set. 807 - `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. 808 - `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. 809 - `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. 810 811 #### WebSocket Support 812 813 WebSocket support can be enabled on specific routes using the `enableWebsockets` field: 814 815 ```yaml 816 # httpproxy-websockets.yaml 817 apiVersion: projectcontour.io/v1 818 kind: HTTPProxy 819 metadata: 820 name: chat 821 namespace: default 822 spec: 823 virtualhost: 824 fqdn: chat.example.com 825 routes: 826 - services: 827 - name: chat-app 828 port: 80 829 - conditions: 830 - prefix: /websocket 831 enableWebsockets: true # Setting this to true enables websocket for all paths that match /websocket 832 services: 833 - name: chat-app 834 port: 80 835 ``` 836 837 #### Permit Insecure 838 839 A HTTPProxy can be configured to permit insecure requests to specific Routes. 840 In this example, any request to `foo2.bar.com/blog` will not receive a 301 redirect to HTTPS, but the `/` route will: 841 842 ```yaml 843 apiVersion: projectcontour.io/v1 844 kind: HTTPProxy 845 metadata: 846 name: tls-example-insecure 847 namespace: default 848 spec: 849 virtualhost: 850 fqdn: foo2.bar.com 851 tls: 852 secretName: testsecret 853 routes: 854 - services: 855 - name: s1 856 port: 80 857 - conditions: 858 - prefix: /blog 859 permitInsecure: true 860 services: 861 - name: s2 862 port: 80 863 ``` 864 865 #### Path Rewriting 866 867 HTTPProxy supports rewriting the HTTP request URL path prior to delivering the request to the backend service. 868 Rewriting is performed after a routing decision has been made, and never changes the request destination. 869 870 The `pathRewritePolicy` field specifies how the path prefix should be rewritten. 871 The `replacePrefix` rewrite policy specifies a replacement string for a HTTP request path prefix match. 872 When this field is present, the path prefix that the request matched is replaced by the text specified in the `replacement` field. 873 If the HTTP request path is longer than the matched prefix, the remainder of the path is unchanged. 874 875 ```yaml 876 apiVersion: projectcontour.io/v1 877 kind: HTTPProxy 878 metadata: 879 name: rewrite-example 880 namespace: default 881 spec: 882 virtualhost: 883 fqdn: rewrite.bar.com 884 routes: 885 - services: 886 - name: s1 887 port: 80 888 pathRewritePolicy: 889 replacePrefix: 890 - replacement: /new/prefix 891 ``` 892 893 The `replacePrefix` field accepts an array of possible replacements. 894 When more than one `replacePrefix` array element is present, the `prefix` field can be used to disambiguate which replacement to apply. 895 896 If no `prefix` field is present, the replacement is applied to all prefix matches made against the route. 897 If a `prefix` field is present, the replacement is applied only to routes that have an exactly matching [prefix condition](#prefix-conditions). 898 Specifying more than one `replacePrefix` entry is mainly useful when a HTTPProxy document is included into multiple parent documents. 899 900 ```yaml 901 apiVersion: projectcontour.io/v1 902 kind: HTTPProxy 903 metadata: 904 name: rewrite-example 905 namespace: default 906 spec: 907 virtualhost: 908 fqdn: rewrite.bar.com 909 routes: 910 - services: 911 - name: s1 912 port: 80 913 conditions: 914 - prefix: /v1/api 915 pathRewritePolicy: 916 replacePrefix: 917 - prefix: /v1/api 918 replacement: /app/api/v1 919 - prefix: / 920 replacement: /app 921 ``` 922 923 ### Header Policy 924 925 HTTPProxy supports rewriting HTTP request and response headers. 926 The `Set` operation sets a HTTP header value, creating it if it doesn't already exist or overwriting it if it does. 927 The `Remove` operation removes a HTTP header. 928 The `requestHeadersPolicy` field is used to rewrite headers on a HTTP request, and the `responseHeadersPolicy` is used to rewrite headers on a HTTP response. 929 These fields can be specified on a route or on a specific service, depending on the rewrite granularity you need. 930 931 932 ```yaml 933 apiVersion: projectcontour.io/v1 934 kind: HTTPProxy 935 metadata: 936 name: header-rewrite-example 937 spec: 938 virtualhost: 939 fqdn: header.bar.com 940 routes: 941 - services: 942 - name: s1 943 port: 80 944 requestHeadersPolicy: 945 set: 946 - name: Host 947 value: external.dev 948 remove: 949 - Some-Header 950 - Some-Other-Header 951 ``` 952 953 ### ExternalName 954 955 HTTPProxy supports routing traffic to `ExternalName` service types. 956 Contour looks at the `spec.externalName` field of the service and configures the route to use that DNS name instead of utilizing EDS. 957 958 There's nothing specific in the HTTPProxy object that needs to be configured other than referencing a service of type `ExternalName`. 959 HTTPProxy supports the `requestHeadersPolicy` field to rewrite the `Host` header after first handling a request and before proxying to an upstream service. 960 This field can be used to ensure that the forwarded HTTP request contains the hostname that the external resource is expecting. 961 962 NOTE: The ports are required to be specified. 963 964 ```yaml 965 # httpproxy-externalname.yaml 966 apiVersion: v1 967 kind: Service 968 metadata: 969 labels: 970 run: externaldns 971 name: externaldns 972 namespace: default 973 spec: 974 externalName: foo-basic.bar.com 975 ports: 976 - name: http 977 port: 80 978 protocol: TCP 979 targetPort: 80 980 type: ExternalName 981 ``` 982 983 #### Proxy to external resource 984 985 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`. 986 Then define a `requestHeadersPolicy` which replaces the `Host` header with the value of the external name service defined previously. 987 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`. 988 989 ## HTTPProxy inclusion 990 991 HTTPProxy permits the splitting of a system's configuration into separate HTTPProxy instances using **inclusion**. 992 993 Inclusion, as the name implies, allows for one HTTPProxy object to be included in another, optionally with some conditions inherited from the parent. 994 Contour reads the inclusion tree and merges the included routes into one big object internally before rendering Envoy config. 995 Importantly, the included HTTPProxy objects do not have to be in the same namespace. 996 997 Each tree of HTTPProxy starts with a root, the top level object of the configuration for a particular virtual host. 998 Each root HTTPProxy defines a `virtualhost` key, which describes properties such as the fully qualified name of the virtual host, TLS configuration, etc. 999 1000 HTTPProxies included from the root must not contain a virtualhost key. 1001 Root objects cannot include other roots either transitively or directly. 1002 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. 1003 Because the path is not necessarily used as the only key, the route space can be multi-dimensional. 1004 1005 ### Conditions and Inclusion 1006 1007 Like Routes, Inclusion may specify a set of [conditions][8]. 1008 These conditions are added to any conditions on the routes included. 1009 This process is recursive. 1010 1011 Conditions are sets of individual condition statements, for example `prefix: /blog` is the condition that the matching request's path must start with `/blog`. 1012 When conditions are combined through inclusion Contour merges the conditions inherited via inclusion with any conditions specified on the route. 1013 This may result in duplicates, for example two `prefix:` conditions, or two header match conditions with the same name and value. 1014 To resolve this Contour applies the following logic. 1015 1016 - `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. 1017 - 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. 1018 1019 ### Configuring inclusion 1020 1021 Inclusion is a top-level part of the HTTPProxy `spec` element. 1022 It requires one field, `name`, and has two optional fields: 1023 1024 - `namespace`. This will assume the included HTTPProxy is in the same namespace if it's not specified. 1025 - a `conditions` block. 1026 1027 #### Within the same namespace 1028 1029 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. 1030 Note that `includes` is a list, and so it must use the YAML list construct. 1031 1032 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). 1033 It's important to note that `service2` HTTPProxy has not defined a `virtualhost` property as it is NOT a root HTTPProxy. 1034 1035 ```yaml 1036 # httpproxy-inclusion-samenamespace.yaml 1037 apiVersion: projectcontour.io/v1 1038 kind: HTTPProxy 1039 metadata: 1040 name: include-root 1041 namespace: default 1042 spec: 1043 virtualhost: 1044 fqdn: root.bar.com 1045 includes: 1046 # Includes the /service2 path from service2 in the same namespace 1047 - name: service2 1048 namespace: default 1049 conditions: 1050 - prefix: /service2 1051 routes: 1052 - conditions: 1053 - prefix: / 1054 services: 1055 - name: s1 1056 port: 80 1057 --- 1058 apiVersion: projectcontour.io/v1 1059 kind: HTTPProxy 1060 metadata: 1061 name: service2 1062 namespace: default 1063 spec: 1064 routes: 1065 - services: # matches /service2 1066 - name: s2 1067 port: 80 1068 - conditions: 1069 - prefix: /blog # matches /service2/blog 1070 services: 1071 - name: blog 1072 port: 80 1073 ``` 1074 1075 #### Virtualhost aliases 1076 1077 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. 1078 1079 ```yaml 1080 # httpproxy-inclusion-multipleroots.yaml 1081 --- 1082 apiVersion: projectcontour.io/v1 1083 kind: HTTPProxy 1084 metadata: 1085 name: multiple-root 1086 namespace: default 1087 spec: 1088 virtualhost: 1089 fqdn: bar.com 1090 includes: 1091 - name: main 1092 namespace: default 1093 --- 1094 apiVersion: projectcontour.io/v1 1095 kind: HTTPProxy 1096 metadata: 1097 name: multiple-root-www 1098 namespace: default 1099 spec: 1100 virtualhost: 1101 fqdn: www.bar.com 1102 includes: 1103 - name: main 1104 namespace: default 1105 --- 1106 apiVersion: projectcontour.io/v1 1107 kind: HTTPProxy 1108 metadata: 1109 name: main 1110 namespace: default 1111 spec: 1112 routes: 1113 - services: 1114 - name: s2 1115 port: 80 1116 ``` 1117 1118 #### Across namespaces 1119 1120 Inclusion can also happen across Namespaces by specifying a `namespace` in the `inclusion`. 1121 This is a particularly powerful paradigm for enabling multi-team Ingress management. 1122 1123 In this example, the root HTTPProxy has included configuration for paths matching `/blog` to the `blog` HTTPProxy object in the `marketing` namespace. 1124 1125 ```yaml 1126 # httpproxy-inclusion-across-namespaces.yaml 1127 --- 1128 apiVersion: projectcontour.io/v1 1129 kind: HTTPProxy 1130 metadata: 1131 name: namespace-include-root 1132 namespace: default 1133 spec: 1134 virtualhost: 1135 fqdn: ns-root.bar.com 1136 includes: 1137 # delegate the subpath, `/blog` to the HTTPProxy object in the marketing namespace with the name `blog` 1138 - name: blog 1139 namespace: marketing 1140 conditions: 1141 - prefix: /blog 1142 routes: 1143 - services: 1144 - name: s1 1145 port: 80 1146 1147 --- 1148 apiVersion: projectcontour.io/v1 1149 kind: HTTPProxy 1150 metadata: 1151 name: blog 1152 namespace: marketing 1153 spec: 1154 routes: 1155 - services: 1156 - name: s2 1157 port: 80 1158 ``` 1159 1160 ### Orphaned HTTPProxy children 1161 1162 It is possible for HTTPProxy objects to exist that have not been delegated to by another HTTPProxy. 1163 These objects are considered "orphaned" and will be ignored by Contour in determining ingress configuration. 1164 1165 ### Restricted root namespaces 1166 1167 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. 1168 Contour has an enforcing mode which accepts a list of namespaces where root HTTPProxy are valid. 1169 Only users permitted to operate in those namespaces can therefore create HTTPProxy with the `virtualhost` field. 1170 1171 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`). 1172 1173 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. 1174 1175 Additionally, when defined, Contour will only watch for Kubernetes secrets in these namespaces ignoring changes in all other namespaces. 1176 Proper RBAC rules should also be created to restrict what namespaces Contour has access matching the namespaces passed to the command line flag. 1177 An example of this is included in the [examples directory][12] and shows how you might create a namespace called `root-httproxy`. 1178 1179 > **NOTE: The restricted root namespace feature is only supported for HTTPProxy CRDs. 1180 > `--root-namespaces` does not affect the operation of `v1beta1.Ingress` objects** 1181 1182 ## TCP Proxying 1183 1184 HTTPProxy supports proxying of TLS encapsulated TCP sessions. 1185 1186 _Note_: The TCP session must be encrypted with TLS. 1187 This is necessary so that Envoy can use SNI to route the incoming request to the correct service. 1188 1189 ### TLS Termination at the edge 1190 1191 If `spec.virtualhost.tls.secretName` is present then that secret will be used to decrypt the TCP traffic at the edge. 1192 1193 ```yaml 1194 # httpproxy-tls-termination.yaml 1195 apiVersion: projectcontour.io/v1 1196 kind: HTTPProxy 1197 metadata: 1198 name: example 1199 namespace: default 1200 spec: 1201 virtualhost: 1202 fqdn: tcp.example.com 1203 tls: 1204 secretName: secret 1205 tcpproxy: 1206 services: 1207 - name: tcpservice 1208 port: 8080 1209 - name: otherservice 1210 port: 9999 1211 weight: 20 1212 ``` 1213 1214 The `spec.tcpproxy` key indicates that this _root_ HTTPProxy will forward the de-encrypted TCP traffic to the backend service. 1215 1216 ### TLS passthrough to the backend service 1217 1218 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. 1219 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. 1220 1221 ```yaml 1222 # httpproxy-tls-passthrough.yaml 1223 apiVersion: projectcontour.io/v1 1224 kind: HTTPProxy 1225 metadata: 1226 name: example 1227 namespace: default 1228 spec: 1229 virtualhost: 1230 fqdn: tcp.example.com 1231 tls: 1232 passthrough: true 1233 tcpproxy: 1234 services: 1235 - name: tcpservice 1236 port: 8080 1237 - name: otherservice 1238 port: 9999 1239 weight: 20 1240 ``` 1241 1242 ### TCPProxy delegation 1243 1244 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. 1245 HTTPProxy authors can delegate the configuration of a TCPProxy to the TCPProxy configuration defined in a HTTPProxy child object. 1246 1247 ```yaml 1248 # httpproxy-parent-termination.yaml 1249 apiVersion: projectcontour.io/v1 1250 kind: HTTPProxy 1251 metadata: 1252 name: parent 1253 namespace: default 1254 spec: 1255 virtualhost: 1256 fqdn: tcp.example.com 1257 tls: 1258 secretName: secret 1259 tcpproxy: 1260 include: 1261 name: child 1262 namespace: app 1263 --- 1264 # httpproxy-child-termination.yaml 1265 apiVersion: projectcontour.io/v1 1266 kind: HTTPProxy 1267 metadata: 1268 name: child 1269 namespace: app 1270 spec: 1271 tcpproxy: 1272 services: 1273 - name: tcpservice 1274 port: 8080 1275 - name: otherservice 1276 port: 9999 1277 weight: 20 1278 ``` 1279 In this example `default/parent` delegates the configuration of the TCPProxy services to `app/child`. 1280 1281 #### TCP Proxy health checking 1282 1283 Active health checking can be configured on a per route basis. 1284 Contour supports TCP health checking and can be configured with various settings to tune the behavior. 1285 1286 During TCP health checking Envoy will send a connect-only health check to the upstream Endpoints. 1287 It is important to note that these are health checks which Envoy implements and are separate from any 1288 other system such as those that exist in Kubernetes. 1289 1290 ```yaml 1291 apiVersion: projectcontour.io/v1 1292 kind: HTTPProxy 1293 metadata: 1294 name: tcp-health-check 1295 namespace: default 1296 spec: 1297 virtualhost: 1298 fqdn: health.bar.com 1299 tcpproxy: 1300 healthCheckPolicy: 1301 intervalSeconds: 5 1302 timeoutSeconds: 2 1303 unhealthyThresholdCount: 3 1304 healthyThresholdCount: 5 1305 services: 1306 - name: s1-health 1307 port: 80 1308 - name: s2-health 1309 port: 80 1310 ``` 1311 1312 TCP Health check policy configuration parameters: 1313 1314 - `intervalSeconds`: The interval (seconds) between health checks. Defaults to 5 seconds if not set. 1315 - `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. 1316 - `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. 1317 - `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. 1318 1319 ## Upstream Validation 1320 1321 When defining upstream services on a route, it's possible to configure the connection from Envoy to the backend endpoint to communicate over TLS. 1322 Two configuration items are required, a CA certificate and a `SubjectName` which are both used to verify the backend endpoint's identity. 1323 1324 The CA certificate bundle for the backend service should be supplied in a Kubernetes Secret. 1325 The referenced Secret must be of type "Opaque" and have a data key named `ca.crt`. 1326 This data value must be a PEM-encoded certificate bundle. 1327 1328 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]) 1329 1330 _Note: This annotation is applied to the Service not the Ingress or HTTPProxy object._ 1331 1332 ```yaml 1333 apiVersion: projectcontour.io/v1 1334 kind: HTTPProxy 1335 metadata: 1336 name: blog 1337 namespace: marketing 1338 spec: 1339 routes: 1340 - services: 1341 - name: s2 1342 port: 80 1343 validation: 1344 caSecret: foo-ca-cert 1345 subjectName: foo.marketing 1346 ``` 1347 1348 ## Client Certificate Validation 1349 1350 It is possible to protect the backend service from unauthorized external clients by requiring the client to present a valid TLS certificate. 1351 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. 1352 Only those requests with a valid client certificate will be accepted and forwarded to the backend service. 1353 1354 ```yaml 1355 apiVersion: projectcontour.io/v1 1356 kind: HTTPProxy 1357 metadata: 1358 name: with-client-auth 1359 spec: 1360 virtualhost: 1361 fqdn: www.example.com 1362 tls: 1363 secretName: secret 1364 clientValidation: 1365 caSecret: client-root-ca 1366 routes: 1367 - services: 1368 - name: s1 1369 port: 80 1370 ``` 1371 1372 The preceding example enables validation by setting the optional `clientValidation` attribute. 1373 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`. 1374 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. 1375 1376 ## Status Reporting 1377 1378 There are many misconfigurations that could cause an HTTPProxy or delegation to be invalid. 1379 To aid users in resolving these issues, Contour updates a `status` field in all HTTPProxy objects. 1380 In the current specification, invalid HTTPProxy are ignored by Contour and will not be used in the ingress routing configuration. 1381 1382 If an HTTPProxy object is valid, it will have a status property that looks like this: 1383 1384 ```yaml 1385 status: 1386 currentStatus: valid 1387 description: valid HTTPProxy 1388 ``` 1389 1390 If the HTTPProxy is invalid, the `currentStatus` field will be `invalid` and the `description` field will provide a description of the issue. 1391 1392 As an example, if an HTTPProxy object has specified a negative value for weighting, the HTTPProxy status will be: 1393 1394 ```yaml 1395 status: 1396 currentStatus: invalid 1397 description: "route '/foo': service 'home': weight must be greater than or equal to zero" 1398 ``` 1399 1400 Some examples of invalid configurations that Contour provides statuses for: 1401 1402 - Negative weight provided in the route definition. 1403 - Invalid port number provided for service. 1404 - Prefix in parent does not match route in delegated route. 1405 - Root HTTPProxy created in a namespace other than the allowed root namespaces. 1406 - A given Route of an HTTPProxy both delegates to another HTTPProxy and has a list of services. 1407 - Orphaned route. 1408 - Delegation chain produces a cycle. 1409 - Root HTTPProxy does not specify fqdn. 1410 - Multiple prefixes cannot be specified on the same set of route conditions. 1411 - Multiple header conditions of type "exact match" with the same header key. 1412 - Contradictory header conditions on a route, e.g. a "contains" and "notcontains" condition for the same header and value. 1413 1414 [1]: https://kubernetes.io/docs/concepts/services-networking/ingress/ 1415 [2]: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md 1416 [3]: {{< param github_url >}}/tree/{{page.version}}/examples/example-workload/httpproxy 1417 [4]: https://www.envoyproxy.io/docs/envoy/v1.14.2/api-v2/api/v2/route/route_components.proto#envoy-api-field-route-routeaction-timeout 1418 [5]: https://godoc.org/time#ParseDuration 1419 [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 1420 [7]: https://www.envoyproxy.io/docs/envoy/v1.14.2/intro/arch_overview/upstream/load_balancing/overview 1421 [8]: #conditions 1422 [9]: {% link docs/{{page.version}}/annotations.md %} 1423 [10]: /docs/{{page.version}}/api/#projectcontour.io/v1.Service 1424 [11]: configuration.md#fallback-certificate 1425 [12]: {{< param github_url >}}/tree/{{page.version}}/examples/root-rbac