Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions api/v1alpha1/httproute_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,24 @@ type HTTPRouteSpec struct {

// HTTPRouteHost is the configuration for a given host.
type HTTPRouteHost struct {
// Hostnames are a list of hosts names that match this host
// block.
// Hostname is the fully qualified domain name of a network host,
// as defined by RFC 3986. Note the following deviations from the
// "host" part of the URI as defined in the RFC:
//
// TODO: RFC link
Hostnames []string `json:"hostnames"`
// 1. IPs are not allowed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be simpler to say that the value must be a reg-name per RFC 3986?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think stating "IPs are not allowed" will make sense to most, if not all, users. I just spent a few minutes reviewing https://tools.ietf.org/html/rfc3986 and I still don't understand what a reg-name is. Maybe we can iterate on the godoc for this field to include reg-name?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is useful to state explicitly that IP addresses are prohibited, fair enough. I think referencing the specific syntax item is also useful. From the RFC:

 host          = IP-literal / IPv4address / reg-name
 reg-name      = *( unreserved / pct-encoded / sub-delims )
 pct-encoded   = "%" HEXDIG HEXDIG
 unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
 sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

// 2. The `:` delimiter is not respected because ports are not allowed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

port is in authority but not in host.

//
// Incoming requests are matched against Hostname before processing HTTPRoute
// rules. For example, if the request header contains host: foo.example.com,
// an HTTPRoute with hostname foo.example.com will match. However, an
// HTTPRoute with hostname example.com or bar.example.com will not match.
// If Hostname is unspecified, the Gateway routes all traffic based on
// the specified rules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Hostname need to be unique among HTTPRoute resources?

How does SNI fit in? I would guess that for a TLS connection, first some certificate must match, and then the ingress controller uses the first route that also matches?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Hostname need to be unique among HTTPRoute resources?

@Miciah this is a good point. @bowei do you agree that the value should be unique?. I don't see any mention of this in the ingress v1beta api docs.

How does SNI fit in? I would guess that for a TLS connection, first some certificate must match, and then the ingress controller uses the first route that also matches?

I would expect similar behavior as ingress v1beta1. From the ingress docs:

If the TLS configuration section in an Ingress specifies different hosts, they are multiplexed on the same port according to the hostname specified through the SNI TLS extension (provided the Ingress controller supports SNI).

Translating the above doc to ingress v2, I would expect the following flow for ingress https connections:

  1. The client initiates a connection to the HTTPRoute hostname.
  2. The client resolves the HTTPRoute hostname to an IP address of the binding Gateway.
  3. The connection hits the binding Gateway TLS listener (default 443).
  4. The Gateway uses the SNI hostname to match the correct HTTPRoute
  5. The Gateway processes the HTTPRoute rules and creates a corresponding connection to the backend service or endpoint associated to the service.

@bowei feel free to chime in if ^ is incorrect. It would also be helpful to understand if the Gateway implementation would forward directly to an endpoint to bypass kube-proxy or to the Service IP. Maybe this is up to the Gateway implementation?

Copy link

@szuecs szuecs Jan 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to singularize the hostname?
There’s a use case for having multiple hostnames in one endpoint, for example multi language site through example.TLD.
A client can select to one or the other hostname and the developer wants not to duplicate her Rules. If we singularize we need to duplicate the Rules.
I don’t see any blockers to not support it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be singular but no unique.
Some use-cases create multiple routes with the same hosts but different paths (or other HTTP metadata). And these routes can belong to different teams.

Translating the above doc to ingress v2, I would expect the following flow for ingress https connections:

TLS and Routing details should not be clubbed together. Although, there is leakage between the layers of the OSI model, they are largely different layers. @danehans, in your description, I think Step 2 and 3 should be changed. HTTPRoute can't be resolved until after TLS is done. One can use only the TLS config setting of a route, but shouldn't select that route. Route selection is based on other metadata in the HTTP reqeust.

Regarding, Sandor's point, I think this can be opened up to allow for prefix and suffix wildcards in future if there is a need for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of HTTPRoutes, the gateway can terminate TLS and then use HTTP to select a HTTPRoute, but in the case of a TCPRoute, HTTP headers are unavailable. So faced with an incoming TLS request, the gateway could first use SNI to build a set of candidate routes, which must comprise either multiple HTTPRoutes or a single TCPRoute, and then the gateway could either (a) terminate TLS and use HTTP metadata to select a single HTTPRoute or (b) use the TLSRoute.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Step 2 and 3 should be changed

@haiyanmeng I submitted #68 to doc a typical ingress request flow, ptal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference for uniqueness: #67

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm inclined to merge this and continue conversation about the wildcard on an issue specific to having wildcards.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I extracted the use case that @szuecs raised into #80.

//
// Support: Core
//
// +optional
Hostname string `json:"hostname,omitempty"`

// Rules are a list of HTTP matchers, filters and actions.
Rules []HTTPRouteRule `json:"rules"`
Expand Down
5 changes: 0 additions & 5 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 26 additions & 14 deletions config/crd/bases/networking.x.k8s.io_httproutes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,19 @@ spec:
- kind
- name
type: object
hostnames:
description: "Hostnames are a list of hosts names that match this
host block. \n TODO: RFC link"
items:
type: string
type: array
hostname:
description: "Hostname is the fully qualified domain name of a network
host, as defined by RFC 3986. Note the following deviations from
the \"host\" part of the URI as defined in the RFC: \n 1. IPs
are not allowed. 2. The `:` delimiter is not respected because
ports are not allowed. \n Incoming requests are matched against
Hostname before processing HTTPRoute rules. For example, if the
request header contains host: foo.example.com, an HTTPRoute with
hostname foo.example.com will match. However, an HTTPRoute with
hostname example.com or bar.example.com will not match. If Hostname
is unspecified, the Gateway routes all traffic based on the specified
rules. \n Support: Core"
type: string
rules:
description: Rules are a list of HTTP matchers, filters and actions.
items:
Expand Down Expand Up @@ -217,7 +224,6 @@ spec:
type: object
type: array
required:
- hostnames
- rules
type: object
hosts:
Expand Down Expand Up @@ -245,12 +251,19 @@ spec:
- kind
- name
type: object
hostnames:
description: "Hostnames are a list of hosts names that match this
host block. \n TODO: RFC link"
items:
type: string
type: array
hostname:
description: "Hostname is the fully qualified domain name of a
network host, as defined by RFC 3986. Note the following deviations
from the \"host\" part of the URI as defined in the RFC: \n
1. IPs are not allowed. 2. The `:` delimiter is not respected
because ports are not allowed. \n Incoming requests are matched
against Hostname before processing HTTPRoute rules. For example,
if the request header contains host: foo.example.com, an HTTPRoute
with hostname foo.example.com will match. However, an HTTPRoute
with hostname example.com or bar.example.com will not match.
If Hostname is unspecified, the Gateway routes all traffic based
on the specified rules. \n Support: Core"
type: string
rules:
description: Rules are a list of HTTP matchers, filters and actions.
items:
Expand Down Expand Up @@ -416,7 +429,6 @@ spec:
type: object
type: array
required:
- hostnames
- rules
type: object
type: array
Expand Down