-
Notifications
You must be signed in to change notification settings - Fork 39.8k
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
NodeRestriction admission plugin #45929
Conversation
9b95102
to
d38c74b
Compare
@kubernetes/sig-auth-pr-reviews @kubernetes/sig-node-pr-reviews |
@k8s-bot verify test this |
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 don't think this was covered in the proposal, but what's the general strategy for testing this feature? e.g. how do we know this doesn't prevent some edge-case kubelet feature?
case "status": | ||
return c.admitPodStatus(nodeName, a) | ||
default: | ||
return admission.NewForbidden(a, fmt.Errorf("unexpected pod subresource")) |
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.
nit: include the subresource in the error message?
// get the existing pod | ||
existingPod, err := c.podsGetter.Pods(a.GetNamespace()).Get(a.GetName(), v1.GetOptions{ResourceVersion: "0"}) | ||
if err != nil { | ||
return admission.NewForbidden(a, err) |
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.
nit: This could be an internal error like "doesn't exist". By including the error in the response, couldn't we be leaking information about what other nodes exist?
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.
this is actually an error about looking up the pod... for now, I'd rather surface the error (remember nodes can still list/watch all pods, and even if they couldn't, they could see if a specific pod already existed by trying to create a mirror pod with the same name and seeing if they get an AlreadyExists error)
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.
Just a couple small comments.
pkg/api/pod/util.go
Outdated
@@ -25,7 +25,7 @@ import ( | |||
// referenced by the pod spec. If visitor returns false, visiting is short-circuited. | |||
// Transitive references (e.g. pod -> pvc -> pv -> secret) are not visited. | |||
// Returns true if visiting completed, false if visiting was short-circuited. | |||
func VisitPodSecretNames(pod *api.Pod, visitor func(string) bool) bool { | |||
func VisitPodSecretNames(pod *api.Pod, visitor func(string) (shouldContinue bool)) bool { |
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.
nit: declare a type for the visitor?
type Visitor func(name string) (shouldContinue bool)
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.
fixed
|
||
userName := u.GetName() | ||
nodeName := "" | ||
if trimmed := strings.TrimPrefix(userName, "system:node:"); len(trimmed) != len(userName) { |
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.
&& len(trimmed) > 0
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.
&& len(trimmed) > 0
so we don't overwrite "" with ""? :)
// NewDefaultNodeIdentifier returns a default NodeIdentifier implementation, | ||
// which returns isNode=true if the user groups contain the system:nodes group, | ||
// and populates nodeName if isNode is true, and the user name is in the format system:node:<nodeName> | ||
func NewDefaultNodeIdentifier() NodeIdentifier { |
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.
Why is this going into the generic API server? Realistically, this is specific to kube-apiserver
since the kubelet can only be coded against core resources, right?
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 don't feel strongly... NodesGroup = "system:nodes"
is in a peer package under k8s.io/apiserver
but I can move this if you have an alternate preferred location
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.
moved out of k8s.io/apiserver
back under the main package
question about just how generic this the node identification is. lgtm otherwise. |
LGTM from me |
This is starting from the pod, pod/status, node, and node/status permissions granted in the I'm willing to say that if we find a case like that, we would consider it a kubelet action we would want to prevent, and anyone blocked until the usage is fixed can stop using this admission plugin in the meantime (since the whole point of the plugin is to prevent cross-node/pod mutations) |
/approve |
/lgtm |
fixed lint error, retagging |
/approve based on approval of owners of the relevant areas |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ericchiang, liggitt, smarterclayton, timstclair
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
Automatic merge from submit-queue (batch tested with PRs 41535, 45985, 45929, 45948, 46056) |
Adds an optional
NodeRestriction
admission plugin that limits identifiable kubelets to mutating their own Node object, and Pod objects bound to their node.This is the admission portion of https://github.com/kubernetes/community/blob/master/contributors/design-proposals/kubelet-authorizer.md and kubernetes/enhancements#279