Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Service type "ExternalName" which results in CNAME DNS #30599

Merged
merged 1 commit into from
Aug 20, 2016

Conversation

therc
Copy link
Member

@therc therc commented Aug 14, 2016

ExternalName allows kubedns to return CNAME records for external
services. No proxying is involved.

First step for kubernetes/enhancements#33

See original issue at
#13748

No release note yet, that will come with the kubedns change.

NONE

This change is Reviewable

@therc
Copy link
Member Author

therc commented Aug 14, 2016

I also changed the comments a bit to make the two types.go files use the same wording for the same fields.

@k8s-github-robot k8s-github-robot added kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. release-note-label-needed labels Aug 14, 2016
@therc
Copy link
Member Author

therc commented Aug 14, 2016

cc @kubernetes/kube-api

@therc
Copy link
Member Author

therc commented Aug 15, 2016

I assume that it'd be a good idea to also have defaulting and validation in. :-) Feel free to reassign to @smarterclayton, @thockin or both, since they are the feature shepherds.

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 16, 2016
@@ -100,6 +100,14 @@ func ValidateDNS1123Label(value string, fldPath *field.Path) field.ErrorList {
return allErrs
}

func ValidateDNS1123Subdomain(value string, fldPath *field.Path) field.ErrorList {
Copy link
Contributor

Choose a reason for hiding this comment

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

Godoc on this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@smarterclayton
Copy link
Contributor

Given that this is alpha, we generally implement this as an annotation. In this case the type is the new thing, so we should probably call it "AlphaExternalName". The only concern there would be that because this is an enum that we'd potentially have services stored in the db without an enum, which could cause breaks.

@k8s-github-robot k8s-github-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Aug 16, 2016
@thockin
Copy link
Member

thockin commented Aug 17, 2016

Review status: 0 of 15 files reviewed at latest revision, 5 unresolved discussions, some commit checks failed.


pkg/api/types.go, line 1742 [r3] (raw file):

// ServiceSpec describes the attributes that a user creates on a service
type ServiceSpec struct {
  // Type determines how to expose the service. Defaults to ClusterIP and only

This makes it sound like "type" does not apply if clusterIP == "none", but type=ExternalName doesn't need clusterIP ?


pkg/api/v1/defaults.go, line 117 [r3] (raw file):

      obj.Type = ServiceTypeClusterIP
  } else if obj.Type == ServiceTypeExternalName {
      obj.ClusterIP = ClusterIPNone

I don't think you should default this here. It should instead be a validation error if type is externalName but clusterIP != ""

Uggh, but that is in the REST path, isn't it? By the time you get here, an IP has been allocated. If you override this, you will leak. Or did I get the sequence wrong?


Comments from Reviewable

@thockin
Copy link
Member

thockin commented Aug 17, 2016

yeah, I am nervous about how to extend an enum like this. Can we do i
t as an annotation and say that they annotation is only considered if type=ClusterIP and clusterIP==None ?


Review status: 0 of 15 files reviewed at latest revision, 5 unresolved discussions, some commit checks failed.


Comments from Reviewable

@erictune erictune assigned thockin and unassigned erictune Aug 17, 2016
@smarterclayton
Copy link
Contributor

We should maybe discuss the annotation thing on the api machinery call today.

@thockin
Copy link
Member

thockin commented Aug 17, 2016

I don't know if there's a general answer to extending arbitrary enums with alpha values, especially when some platforms don't want to enable alpha features. I think it has to be case-by-case. In this case, define the requirement as the most innocuous setting + an alpha override.

Also, alpha features have to be gateable. Do we need a --enable-alpha-annotations flag for apiserver that everyone can check?


Reviewed 1 of 5 files at r2, 14 of 14 files at r3.
Review status: all files reviewed at latest revision, 5 unresolved discussions, some commit checks failed.


Comments from Reviewable

@therc
Copy link
Member Author

therc commented Aug 17, 2016

I might be able to join in the second half of the API meeting, but I'm at IDF16, so I'm not sure if I'll be able to find a corner quiet enough.

@smarterclayton
Copy link
Contributor

We don't have anything gating alpha features today consistently. Partially
that's because external components don't have shared global config. I'd
probably argue that any alpha feature represented in the API needs to be
controlled by the API server, which potentially means filtering annotations
on both input and output. The security issues with annotations are also
problematic - since annotations aren't discoverable (you can't discover
which alpha features exist) lots of implementers don't realize they need to
support / defend against annotations, and since annotations are one big
bucket there's no way to limit which annotations can get set by which users
short of admission control.

On Wed, Aug 17, 2016 at 12:02 PM, Tim Hockin notifications@github.com
wrote:

I don't know if there's a general answer to extending arbitrary enums with
alpha values, especially when some platforms don't want to enable alpha
features. I think it has to be case-by-case. In this case, define the
requirement as the most innocuous setting + an alpha override.

Also, alpha features have to be gateable. Do we need a

--enable-alpha-annotations flag for apiserver that everyone can check?

Reviewed 1 of 5 files at r2, 14 of 14 files at r3.
Review status: all files reviewed at latest revision, 5 unresolved

discussions, some commit checks failed.

Comments from Reviewable
https://reviewable.kubernetes.io:443/reviews/kubernetes/kubernetes/30599#-:-KPODGKPpnN9zTDv13NA:b6hsbzf


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#30599 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABG_p7cq6guBLlA2K8MqUUx-4TqEXAJ_ks5qgzCYgaJpZM4JkAx2
.

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 17, 2016
@thockin
Copy link
Member

thockin commented Aug 17, 2016

Something we DIDN'T do for this is open a feature bug. @therc should do that. Given your unavailability this week, and the lack of a corresponding DNS change, I have very little confidence it will make the 1.4 window. :(

@thockin
Copy link
Member

thockin commented Aug 17, 2016

It seems I am wrong, and we DO have a feature bug, but maybe have not been updating it.

@therc
Copy link
Member Author

therc commented Aug 17, 2016

I mentioned the feature at the top. I can't update it, though.Oh, Github. :-)

I'm trying to finish the DNS change today.

@thockin
Copy link
Member

thockin commented Aug 18, 2016

So the open issues are:

  1. Was this all in vain because it needs to be an annotation
  2. Where's the corresponding kube-dns change
  3. e2e
  4. docs

Reviewed 1 of 1 files at r4, 10 of 10 files at r5.
Review status: all files reviewed at latest revision, 5 unresolved discussions, some commit checks failed.


pkg/api/types.go, line 1742 [r3] (raw file):

Previously, therc (Rudi C) wrote…

I reworded it, but it's still a bit clumsy.

How about:

// Type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the clusterIP


pkg/api/v1/defaults.go, line 117 [r3] (raw file):

Previously, therc (Rudi C) wrote…

I thought that defaults happened before validation, but I think they happen before CREATION instead. pkg/api/rest/create.go:BeforeCreate calls Validate. And pkg/registry/service/rest:Create calls BeforeCreate, then allocates a VIP. The VIP is allocated only if clusterIP == "". I changed IsServiceIPRequested to short-circuit to False for ExternalName services so thatthey don't trigger an allocation, either, then I changed the check to make sure that clusterIP == "".

I have also removed the default.

Ahh yes, gooooood

Comments from Reviewable

@therc
Copy link
Member Author

therc commented Aug 18, 2016

I was up until almost 1 last night, I must have forgotten to press Submit. :-( #30931 implements the kube-dns change, along with simple unit tests and e2e.


Review status: all files reviewed at latest revision, 5 unresolved discussions, some commit checks failed.


Comments from Reviewable

@therc
Copy link
Member Author

therc commented Aug 19, 2016

Review status: 1 of 15 files reviewed at latest revision, 5 unresolved discussions.


pkg/api/types.go, line 1742 [r3] (raw file):

Previously, thockin (Tim Hockin) wrote…

How about:

// Type determines how the Service is exposed. Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
// "ExternalName" maps to the specified externalName.
// "ClusterIP" allocates a cluster-internal IP address for load-balancing to endpoints. Endpoints are determined by the selector or if that is not specified, by manual construction of an Endpoints object. If clusterIP is "None", no virtual IP is allocated and the endpoints are published as a set of endpoints rather than a stable IP.
// "NodePort" builds on ClusterIP and allocates a port on every node which routes to the clusterIP.
// "LoadBalancer" builds on NodePort and creates an external load-balancer (if supported in the current cloud) which routes to the clusterIP

Done.

Comments from Reviewable

@k8s-github-robot k8s-github-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Aug 19, 2016
@thockin
Copy link
Member

thockin commented Aug 19, 2016

Code LGTM.

I discussed this with a few folks and I think we can move this through without the usual beta cycle. Rationale: it's already opt-in (no change unless users explicitly activate it), the implementation is simple, test coverage should be sufficient, and the crater is relatively small.

I picked a couple nits, so I can't quite LGTM this - fix those and ping me. The subsequent DNS change also LGTM. Needs docs and final steps from the feature checklist. I'll also re-title it for relnote

+lgtm


Reviewed 5 of 15 files at r6.
Review status: 5 of 15 files reviewed at latest revision, 4 unresolved discussions.


pkg/api/validation/validation.go, line 2232 [r6] (raw file):

          allErrs = append(allErrs, ValidateDNS1123Subdomain(service.Spec.ExternalName, specPath.Child("externalName"))...)
      } else {
          allErrs = append(allErrs, field.Invalid(specPath.Child("externalName"), service.Spec.ExternalName, "externalName must not be empty"))

error string should not repeat field name

This should be handled as field.Required() - see elsewhere


Comments from Reviewable

@thockin thockin added lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note-label-needed labels Aug 19, 2016
@thockin thockin changed the title Add ExternalName to ServiceSpec Add Service type "ExternalName" which results in CNAME DNS Aug 19, 2016
ExternalName allows kubedns to return CNAME records for external
services. No proxying is involved.

See original issue at
kubernetes#13748

Feature tracking at
kubernetes/enhancements#33
@therc
Copy link
Member Author

therc commented Aug 19, 2016

Review status: 4 of 15 files reviewed at latest revision, 4 unresolved discussions.


pkg/api/validation/validation.go, line 2232 [r6] (raw file):

Previously, thockin (Tim Hockin) wrote…

error string should not repeat field name

This should be handled as field.Required() - see elsewhere

Done.

Comments from Reviewable

@k8s-bot
Copy link

k8s-bot commented Aug 19, 2016

GCE e2e build/test passed for commit 88fdb96.

@thockin thockin added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 19, 2016
@thockin
Copy link
Member

thockin commented Aug 19, 2016

LGTM +lgtm


Reviewed 1 of 1 files at r7.
Review status: 5 of 15 files reviewed at latest revision, 3 unresolved discussions.


Comments from Reviewable

@therc
Copy link
Member Author

therc commented Aug 19, 2016

@thockin could you add the milestone so it doesn't end up at the very bottom of the submit queue? I also don't know if the fact that it's an API change makes it any higher than a P3.

@thockin thockin added this to the v1.4 milestone Aug 20, 2016
@thockin thockin added the priority/backlog Higher priority than priority/awaiting-more-evidence. label Aug 20, 2016
@k8s-github-robot
Copy link

@k8s-bot test this [submit-queue is verifying that this PR is safe to merge]

@k8s-bot
Copy link

k8s-bot commented Aug 20, 2016

GCE e2e build/test passed for commit 88fdb96.

@k8s-github-robot
Copy link

Automatic merge from submit-queue

@k8s-github-robot k8s-github-robot merged commit 1aecaf2 into kubernetes:master Aug 20, 2016
k8s-github-robot pushed a commit that referenced this pull request Aug 26, 2016
Automatic merge from submit-queue

Add ExternalName kube-dns e2e test

ExternalName allows kubedns to return CNAME records for external
services. No proxying is involved.

Built on top of and includes #30599 

See original issue at
#13748

Feature tracking at
kubernetes/enhancements#33

The e2e test is at least as comprehensive as the one for headless services (namely, only to some degree)

```release-note
Add ExternalName services as CNAME references to external ones
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/backlog Higher priority than priority/awaiting-more-evidence. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants