-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Kubelet API Certificate #3125
Kubelet API Certificate #3125
Conversation
Hi @gambol99. Thanks for your PR. I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
5db7f6e
to
578a9c8
Compare
docs/security.md
Outdated
anonymousAuth: false | ||
``` | ||
|
||
**Note** on a existing cluster with 'anonymousAuth' unset you would need to first roll out the masters and then update the pools. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think by "pools" you mean "nodes" or "node instance groups" (?)
docs/security.md
Outdated
## Kubernetes API | ||
|
||
(this section is a work in progress) | ||
|
||
Kubernetes has a number of authentication mechanisms: | ||
|
||
## Kubelet API | ||
|
||
By default AnonymousAuth on the kubelet is off and so communication between kube-apiserver and kubelet api is not authenticated. In order to switch on authentication; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean "by default AnonymousAuth on the kubelet is on..."
nodeup/pkg/model/context.go
Outdated
|
||
// @check if we have anything specific to master kubelet | ||
if c.IsMaster { | ||
if cluster.MasterKubelet != nil && cluster.MasterKubelet.AnonymousAuth != nil && *cluster.MasterKubelet.AnonymousAuth == true { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean == false
at the end here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you :-) .. and fixed
|
||
// UseSecureKubelet checks if the kubelet api should be protected by a client certificate. Note: the settings are be | ||
// in one of three section, master specific kubelet, cluster wide kubelet or the InstanceGroup. Though arguably is | ||
// doesn't make much sense to unset this on a per InstanceGroup level, but hey :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it doesn't really make a difference, because it doesn't make any sense to mix this setting, but I feel like the logic should be:
if instancegroup anonymousauth != nil, return that value
if master and masterkubelet anonymousauth != nil, return that value
if kubelet anonymousauth != nil, return that value
i.e. most specific to least specific, and you can set anonymousauth explicitly to true on the instancegroup and override (though this is silly in practice)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep .. that make's a lot sense
nodeup/pkg/model/kubeapiserver.go
Outdated
@@ -70,6 +71,19 @@ func (b *KubeAPIServerBuilder) Build(c *fi.ModelBuilderContext) error { | |||
c.AddTask(t) | |||
} | |||
|
|||
// @check if we are using secure client certificates for kubelet and grab the certificates | |||
{ | |||
if b.UseSecureKubelet() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a big fan of using { ... }
to group blocks of code, but here I think we can use the natural block defined by if b.UseSecureKubelet()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh... and mixing this setting is really not going to go well, if the apiserver doesn't have the cert but the nodes are expecting it :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed ... i'm not a fan of bracketed code either, but i wanted to stay consistent and everything else else bracketed, so i felt the peer pressure :-)
nodeup/pkg/model/kubeapiserver.go
Outdated
} | ||
|
||
return fmt.Errorf("Unrecognized authentication config %v", b.Cluster.Spec.Authentication) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW the main reason I like not having this as a fall-through is that then it is a compilation error if you forget to return nil
in one of the branches, if each of the branches is expected to exit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess the a idiom would to be return early ... i.e. b.Cluster.Spec.Authentication.Kopeio == nil then return the error .. else everything continues
nodeup/pkg/model/kubeapiserver.go
Outdated
kubeAPIServer.BasicAuthFile = filepath.Join(b.PathSrvKubernetes(), "basic_auth.csv") | ||
kubeAPIServer.TokenAuthFile = filepath.Join(b.PathSrvKubernetes(), "known_tokens.csv") | ||
|
||
// @check if we are using secure kubelet client certificates | ||
if b.UseSecureKubelet() { | ||
// @note we are making assumption we are using the one's created by the pki model, not custom defined ones |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to call this out. This is tricky actually. In some places we haven't mapped the flag in the model, and we just directly add the flag to the arguments. But that feels sort of hacky in that then we aren't using the flag code we've worked so hard on!
Realistically, eventually with componentconfig in k8s these will move out of flags (either to secrets or to dynamically generated and locally stored certificates, using the CertificateSigningRequest API). But we aren't there yet.
One option could be to glog.Warningf
if the values are not empty. But this is fine I think... setting the kubelet / kubeapiserver config flags directly is "expert mode" kops and it is then possible/easy to break things (for typical usage we prefer setting options which set these flags, which is how kops continues to work across k8s versions even if the underlying flags or flag semantics change).
@@ -265,6 +268,12 @@ func (b *KubeletBuilder) buildKubeletConfigSpec() (*kops.KubeletConfigSpec, erro | |||
utils.JsonMergeStruct(c, b.Cluster.Spec.Kubelet) | |||
} | |||
|
|||
// @check if we are using secure kubelet <-> api settings | |||
if b.UseSecureKubelet() { | |||
// @TODO these filenames need to be a constant somewhere |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One option is to put them into a helper function in NodeupModelContext
.
/ok-to-test Looks great. I think it would be great to figure out a top level cluster option which controls this configuration. One option is just to automatically enable it for k8s 1.8, but it would be nice to have this available for earlier versions as well I suspect. On the other hand, the flags you have right now do work, and so we can continue building these options out and then see if we want an overarching "secureTraffic" mode or similar. In other words, not a blocker to this PR merging :-) |
@gambol99 PR needs rebase |
- fixed the various issues highlighted in kubernetes#3125 - changed the docuementation to make more sense - changed the logic of the UseSecureKubelet to return early
- fixed the various issues highlighted in kubernetes#3125 - changed the docuementation to make more sense - changed the logic of the UseSecureKubelet to return early
- fixed the various issues highlighted in kubernetes#3125 - changed the docuementation to make more sense - changed the logic of the UseSecureKubelet to return early
LGTM - ready for merge? |
hi @justinsb ... yep, good to merge :-) |
@gambol99 PR needs rebase |
A while back options to permit secure kube-apiserver to kubelet api was kubernetes#2831 using the server.cert and server.key as testing grouns. This PR formalizes the options and generates a client certificate on their behalf (note, the server{.cert,key} can no longer be used post 1.7 as the certificate usage is checked i.e. it's not using a client cert). The users now only need to add anonymousAuth: false to enable secure api to kubelet. I'd like to make this default to all new builds i'm not sure where to place it. - updated the security.md to reflect the changes - issue a new client kubelet-api certificate used to secure authorize comms between api and kubelet - fixed any formatting issues i came across on the journey
- fixed the various issues highlighted in kubernetes#3125 - changed the docuementation to make more sense - changed the logic of the UseSecureKubelet to return early
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: gambol99, justinsb The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
/test all [submit-queue is verifying that this PR is safe to merge] |
Automatic merge from submit-queue |
- fixed the various issues highlighted in kubernetes#3125 - changed the docuementation to make more sense - changed the logic of the UseSecureKubelet to return early
A while back options to permit secure kube-apiserver to kubelet api was PR2381 using the server.cert and server.key as testing grounds. This PR formalizes the options and generates a client certificate on their behalf (note, the server{.cert,key} can no longer be used post 1.7 as the certificate usage is checked i.e. it's not using a client cert). The users now only need to add anonymousAuth: false to enable secure api to kubelet. I'd like to make this default to all new builds i'm not sure where to place it.