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

federation: Updating KubeDNS to try finding a local service first for federation query #27708

Merged
merged 2 commits into from
Jun 24, 2016

Conversation

nikhiljindal
Copy link
Contributor

Ref #26762

Updating KubeDNS to try to find a local service first for federation query.
Without this change, KubeDNS always returns the DNS hostname, even if a local service exists.

Have updated the code to first remove federation name from path if it exists, so that the default search for local service happens. If we dont find a local service, then we try to find the DNS hostname.

Will appreciate a strong review since this is my first change to KubeDNS.
#25727 was the original PR that added federation support to KubeDNS.

cc @kubernetes/sig-cluster-federation @quinton-hoole @madhusudancs @bprashanth @mml

@nikhiljindal nikhiljindal added this to the v1.3 milestone Jun 20, 2016
@nikhiljindal nikhiljindal added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Jun 20, 2016
@k8s-github-robot k8s-github-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jun 20, 2016
path := strings.Split(trimmed, ".")
isFederationQuery := false
federationPath := []string{}
if !exact && kd.isFederationQuery(path) {
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 am not sure about this exact parameter.
Looking at the existing code, it seems that we should be checking !exact here.
Can remove it if its not required.

Copy link

Choose a reason for hiding this comment

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

@nikhiljindal See #25727 (comment) for context.

@ghost
Copy link

ghost commented Jun 20, 2016

Thanks @nikhiljindal - I'm going to review this now.

@@ -420,8 +420,20 @@ func (kd *KubeDNS) newHeadlessService(service *kapi.Service) error {
func (kd *KubeDNS) Records(name string, exact bool) (retval []skymsg.Service, err error) {
glog.Infof("Received DNS Request:%s, exact:%v", name, exact)
trimmed := strings.TrimRight(name, ".")
segments := strings.Split(trimmed, ".")
path := reverseArray(segments)
path := strings.Split(trimmed, ".")
Copy link
Contributor

Choose a reason for hiding this comment

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

Call this segments for terminology consistency. path is the reverse segments.

@madhusudancs
Copy link
Contributor

LGTM other than a minor nit. Feel free to apply the label after fixing it.

federationPath = append(federationPath, path...)
// To try local service, remove federation name from path.
// Federation name is 3rd in the path (after service name and namespace).
path = append(path[:2], path[3:]...)
Copy link

Choose a reason for hiding this comment

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

@nikhiljindal @madhusudancs I'm probably overlooking something, but its not clear to me where we ensure that we avoid returning the cluster IP of a local service that has no healthy endpoints backing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It works when there is no endpoint for the local service (I have a test for it).
But I just tried deleting endpoints from an existing service and it still returned me the endpoint (which I deleted). Am debugging that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well that was just an error in the way I was testing.
What I said above was only true for headless services. Updated the code to handle normal services as well (which is what federation will create)

@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jun 21, 2016
@nikhiljindal
Copy link
Contributor Author

Updated the code to check for endpoints of a service before returning its cluster IP for a federation query.
We return the DNS hostname instead if there are no endpoints.

Added tests as well.
I have also added a test for headless service (since I wrote that first), but realized that we wont be creating headless services in federation. So its not strictly required, but I have let it be.

PTAL

@ghost
Copy link

ghost commented Jun 21, 2016

This is a pretty substantial change that will need to be carefully reviewed and tested. If we break KubeDNS, the cluster is broken, so that's really bad. Do we understand why it appeared to work, at least in a limited fashion, before these changes?

To be clear, I've not reviewed to code extensively yet. But I'm very nervous about making changes to such a key component of every Kubernetes cluster so late before a major release, unless we are super-confident about the proposed changes.

Are we super-confident @nikhiljindal @madhusudancs ? @ArtfulCoder could you also please take a look? More eyes are better.

@ghost
Copy link

ghost commented Jun 21, 2016

PS: I would ideally like us to bang hard on this for a few days in a soak test cluster before declaring it good. I can assist in making that happen.

@nikhiljindal
Copy link
Contributor Author

Totally agree @quinton-hoole
This is the first time I am making a change to kubeDNS so I am definitely not super confident :)

I have restricted the changes to be only when the query is for federation service. And have added extensive tests. The existing code has good tests as well.
But yes, this is a critical component.

Will wait until someone familiar with this code has had a chance to take a look.
@bprashanth maybe?

@nikhiljindal
Copy link
Contributor Author

@k8s-bot node e2e test this issue: #27668

@nikhiljindal
Copy link
Contributor Author

cc @girishkalele who I am told is the new KubeDNS owner :)

@girishkalele girishkalele self-assigned this Jun 21, 2016
@nikhiljindal
Copy link
Contributor Author

Added a check to validate that federation names dont have dots '.' as per discussion with @ArtfulCoder and @madhusudancs

@ArtfulCoder
Copy link
Contributor

ArtfulCoder commented Jun 21, 2016

TODOs left in the PR:

  1. make sure its thread safe when the new map is accessed.
  2. removed the reverse lookup map
  3. ensure that federation name does not have dots.
  4. check for wildcard support and impact on wildcards with the new federation segment.
    Consider scenarios where the federation name could be an existing namespace/service name.

(I spoke with Nikhil and he knows what the above mean code-wise)..

k8s-github-robot pushed a commit that referenced this pull request Jun 22, 2016
Automatic merge from submit-queue

federation e2e: Adding retries to fetching secret in controller manager

Ref: #27708

Trying to fix the following failure in fed controller manager:
```
error in fetching secret: Get https://10.0.0.1:443/api/v1/namespaces/federation/secrets/federation-apiserver-secret: dial tcp 10.0.0.1:443: i/o timeout
```

I am not sure why that error is happening in the first place. kube-proxy should have been configured before fed controller manager pod comes up. I didnt find anything wrong in kube-proxy logs.
The request never reaches fed apiserver.
Lets see if adding retries helps.

cc @kubernetes/sig-cluster-federation @mml @colhom
@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 22, 2016
@ghost
Copy link

ghost commented Jun 22, 2016

@nikhiljindal Still needs rebase, and the verification error is below. Hopefully the rebase will sort that out too.

FAIL: changes needed but not made due to --verify
/go/src/k8s.io/kubernetes/docs/ is out of date. Please run hack/update-munge-docs.sh
FAILED   ./hack/../hack/verify-munge-docs.sh    2s

@@ -558,6 +637,9 @@ func getSkyMsg(ip string, port int) (*skymsg.Service, string) {
// 5. Fourth segment is exactly "svc"
// 6. The remaining segments match kd.domainPath.
// 7. And federation must be one of the listed federations in the config.
// Note: Because of the above conditions, this method will treat wildcard queries such as
// *.mysvc.myns.myfederation.svc.domain.path as non-federation queries.
// We can add support for wildcard queries later, if needed.
Copy link

@ghost ghost Jun 23, 2016

Choose a reason for hiding this comment

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

Yes, I would like us to support wildcard queries for federated services, as this will be an easy way for clients to discover all shards of a service globally, with a single DNS query. Pretty cool. Can wait until post-1.3.

Copy link
Contributor

@madhusudancs madhusudancs Jun 23, 2016

Choose a reason for hiding this comment

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

@quinton-hoole How are the clients expected to format the wildcard-names? Specifically, where do you expect them to put the *?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, what do you expect the KubeDNS response to be?

@nikhiljindal
Copy link
Contributor Author

Tests on this PR ran with the updated KubeDNS image (with my code changes). Great to see that they all passed.

Consider scenarios where the federation name could be an existing namespace/service name.

Yea. Need to think a bit more about the case when federation name is same as namespace name. Will get back on this.

I discussed this with @quinton-hoole and we discussed a few potential solutions, but decided not to fix it in 1.3. Have filed #27969 to keep track.

Also, @quinton-hoole suggested returning a CNAME record for the local service (if it exists) instead of the A records directly in response to a federation DNS query. Making that change now.

assert.Equal(t, a, records[0].Host)
}

// Verifies that quering KubeDNS for a headless federation service returns the DNS hostname when a local service does not exist and returns the endpoint IP when a local service exists.
Copy link

Choose a reason for hiding this comment

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

As discussed, for both headless and non-headless, we should return a CNAME (to the local service's DNS name if the service exists and has endoints, or to the zone-local DNS name if the local service has no endpoints).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@ghost ghost added the priority/critical-urgent Highest priority. Must be actively worked on as someone's top priority right now. label Jun 23, 2016
@yifan-gu
Copy link
Contributor

@nikhiljindal Could you update the manifest under cluster/gce/coreos/kube-manifest/addons as well? Thank you!

@nikhiljindal
Copy link
Contributor Author

Sure @yifan-gu done.

Update code as per comments. Added a commit to return the DNS hostname of local service rather than returning its endpoints directly. PTAL.

@nikhiljindal
Copy link
Contributor Author

Have also rebased to include other DNS changes, specifically: #27891, #27896 and #27960.

Pushed the updated image to gcr.io/google_containers/kubedns-amd64:1.5 to run tests

isFederationQuery := false
federationSegments := []string{}
if !exact && kd.isFederationQuery(segments) {
glog.Infof("federation service query: Received federation query. Going to try to find local service first")

Choose a reason for hiding this comment

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

Move this to a lower log level ? Seems chatty with no specific information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the information this gives is that this query was interpreted as a federation query.
I would like to keep it for debugging.
Note that we wont see this in the logs unless someone has federation enabled and is sending federation queries.

@nikhiljindal
Copy link
Contributor Author

I see a new GKE e2e here which is failing with some auth problems unrelated to this PR. I dont see any issue filed.
cc @fejta ?

@girishkalele
Copy link

@nikhiljindal

Both gke e2e seem to be known flakes.
Is this the kubernetes-e2e-gke-slow/5723 run ?

[Fail] [k8s.io] Pod Disks [It] should schedule a pod w/ a readonly PD on two hosts, then remove both. [Slow] 
/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/test/e2e/pd.go:172

or kubernetes-e2e-gke/9788 ?

[Fail] [k8s.io] Proxy version v1 [It] should proxy through a service and a pod [Conformance] 
/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/test/e2e/proxy.go:259

@girishkalele
Copy link

As far as I can tell, there is no non-federation functionality affected.
2 Major comments:

  1. Logs are very noisy, I ran against kubedns:1.5 and see very chatty logs. Please reduce log levels.
  2. Squash all commits.

@nikhiljindal
Copy link
Contributor Author

Squashed into 2 commits (dns changes and YAML file changes).
As discussed the logs are same as in 1.4

@girishkalele girishkalele added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 24, 2016
@girishkalele
Copy link

LGTM - lets get it in.

@nikhiljindal
Copy link
Contributor Author

thx @girishkalele

@k8s-bot
Copy link

k8s-bot commented Jun 24, 2016

GCE e2e build/test passed for commit 7be4293.

@k8s-github-robot
Copy link

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

@ghost
Copy link

ghost commented Jun 24, 2016

@nikhiljindal I suggest that you follow @girishkalele 's suggestions re logging verbosity. Rather log as glog.V(4) and set --v=4 on the binary while you're debugging? Will that work for you?

@ghost
Copy link

ghost commented Jun 24, 2016

@nikhiljindal @fejta PS that new GKE smoke test is failing on #27972 also.

@k8s-bot
Copy link

k8s-bot commented Jun 24, 2016

GCE e2e build/test passed for commit 7be4293.

@k8s-github-robot
Copy link

Automatic merge from submit-queue

@k8s-github-robot k8s-github-robot merged commit a27fd4b into kubernetes:master Jun 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/critical-urgent Highest priority. Must be actively worked on as someone's top priority right now. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants