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

NodeRestriction admission plugin #45929

Merged
merged 3 commits into from
May 19, 2017

Conversation

liggitt
Copy link
Member

@liggitt liggitt commented May 17, 2017

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

The `NodeRestriction` admission plugin limits the `Node` and `Pod` objects a kubelet can modify. In order to be limited by this admission plugin, kubelets must use credentials in the `system:nodes` group, with a username in the form `system:node:<nodeName>`. Such kubelets will only be allowed to modify their own `Node` API object, and only modify `Pod` API objects that are bound to their node.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label May 17, 2017
@k8s-github-robot k8s-github-robot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label May 17, 2017
@k8s-github-robot k8s-github-robot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label May 17, 2017
@liggitt liggitt force-pushed the node-admission branch 2 times, most recently from 9b95102 to d38c74b Compare May 17, 2017 03:00
@liggitt
Copy link
Member Author

liggitt commented May 17, 2017

@kubernetes/sig-auth-pr-reviews @kubernetes/sig-node-pr-reviews

@k8s-ci-robot k8s-ci-robot added sig/auth Categorizes an issue or PR as relevant to SIG Auth. sig/node Categorizes an issue or PR as relevant to SIG Node. labels May 17, 2017
@liggitt liggitt added this to the v1.7 milestone May 17, 2017
@liggitt
Copy link
Member Author

liggitt commented May 17, 2017

@k8s-bot verify test this

@liggitt
Copy link
Member Author

liggitt commented May 17, 2017

@ericchiang @timstclair @deads2k PTAL

Copy link
Contributor

@ericchiang ericchiang left a 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"))
Copy link
Contributor

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)
Copy link
Contributor

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?

Copy link
Member Author

@liggitt liggitt May 18, 2017

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)

Copy link

@timstclair timstclair left a 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.

@@ -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 {

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)

Copy link
Member Author

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) {

Choose a reason for hiding this comment

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

&& len(trimmed) > 0

Copy link
Member Author

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 {
Copy link
Contributor

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?

Copy link
Member Author

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

Copy link
Member Author

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

@deads2k
Copy link
Contributor

deads2k commented May 18, 2017

question about just how generic this the node identification is. lgtm otherwise.

@timstclair
Copy link

LGTM from me

@k8s-github-robot k8s-github-robot removed the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label May 18, 2017
@k8s-github-robot k8s-github-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label May 18, 2017
@liggitt
Copy link
Member Author

liggitt commented May 18, 2017

what's the general strategy for testing this feature? e.g. how do we know this doesn't prevent some edge-case kubelet feature?

This is starting from the pod, pod/status, node, and node/status permissions granted in the system:node RBAC role, which is tested in CI. There are no known cases of nodes updating pods for other nodes (or unbound pods), or updating other node objects.

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)

@ericchiang
Copy link
Contributor

/approve

@timstclair
Copy link

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 18, 2017
@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 18, 2017
@liggitt
Copy link
Member Author

liggitt commented May 18, 2017

fixed lint error, retagging

@liggitt liggitt added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 18, 2017
@smarterclayton
Copy link
Contributor

/approve

based on approval of owners of the relevant areas

@k8s-github-robot
Copy link

[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 /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 18, 2017
@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 41535, 45985, 45929, 45948, 46056)

@k8s-github-robot k8s-github-robot merged commit a9fbeef into kubernetes:master May 19, 2017
@liggitt liggitt deleted the node-admission branch May 19, 2017 04:09
CaoShuFeng added a commit to CaoShuFeng/kubernetes.github.io that referenced this pull request Jun 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/security cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. 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. sig/auth Categorizes an issue or PR as relevant to SIG Auth. sig/node Categorizes an issue or PR as relevant to SIG Node. 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.

8 participants