Status: Accepted
This document looks to allow Contour to process Kubernetes service types ExternalName
so that traffic can be proxied to dns hosts rather than only pod endpoints.
- Allow for Contour to proxy traffic via Envoy to external dns endpoints
- Utilize built-in Kubernetes object types (i.e. ExternalName service)
externalIPs
will not be used, users who want to proxy to custom IP's should build their own service/endpoint object- Utilize a new CRD or ConfigMap style mapping
- Only support HTTP at the moment, TCP will be addressed in a further design doc
Contour currently watches Kubernetes services and endpoints, streaming them to via Envoy xDS CDS & EDS endpoints. Kubernetes pods are identified by their presence in the Endpoint document and streamed to Envoy via EDS. Requests to envoy are routed directly to Kubernetes pods (i.e. endpoints). This proposal looks to add a second way to identify the members of a Envoy clustr object, using a DNS entry to supply the cluster members rather than EDS.
Contour will need to watch for and process Kubernetes service types of ExternalName
(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#servicespec-v1-core).
When configuring a Route, Contour will use the contents of the spec.externalName
of the service as well as the port from the spec.ports
section of the Kubernetes service.
If ports are not supplied for the Kubernetes service, then the IngressRoute status will be set accordingly with an error message.
Allowing for TLS proxying and validation should still be applied as it exists already so users can proxy to a TLS upstream as well as validate the certificate+subject alt name of the upstream service.
- The
TCPService
struct ininternal/dag/dag.go
will have a newexternalName string
field added. - When services are added in
internal/dag/builder.go
, ifsvc.Spec.Type == v1.ServiceTypeExternalName
then the value ofsvc.Spec.ExternalName
will be set to the TCPService struct'sexternalName
. - Since the service does not have any Kubernetes Endpoints, we cannot rely on having an EDS cluster to reference from the CDS cluster.
For this type of service (i.e.
ExternalName
) when creating the cluster ininternal/envoy/cluster.go
, instead of setting aEdsClusterConfig
, we'll configure aLoadAssignment
which should allow us to specify the endpoint defined inexternalName
dynamically.
Potentially, we could avoid using a Service of type ExternalName
by simply just extending the IngressRoute
CRD as proposed here: #825 (comment)
The downside to this approach is it couldn't be used with Ingress resources.
Potentially someone could use an ExternalName
service to reference services in another namespace by setting the externalName
(ex: other-service.namespace-other.svc.cluster.local
).
This scenario exists in a cluster regardless if Contour is deployed or not, other security restrictions should be applied if users want to avoid this from happening.