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

node authorizer sets up access rules for dynamic config #60100

Merged

Conversation

mtaufen
Copy link
Contributor

@mtaufen mtaufen commented Feb 20, 2018

This PR makes the node authorizer automatically set up access rules for
dynamic Kubelet config.

I also added some validation to the node strategy, which I discovered we
were missing while writing this.

This PR is based on another WIP from @liggitt.

The node authorizer now automatically sets up rules for Node.Spec.ConfigSource when the DynamicKubeletConfig feature gate is enabled.

@mtaufen mtaufen added area/kubelet area/kubelet-api sig/node Categorizes an issue or PR as relevant to SIG Node. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Feb 20, 2018
@k8s-ci-robot k8s-ci-robot added 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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Feb 20, 2018
@mtaufen mtaufen force-pushed the node-authz-nodeconfigsource branch 5 times, most recently from f708dfd to fa553c1 Compare February 21, 2018 23:56
@mtaufen mtaufen changed the title (WIP) node authorizer sets up access rules for dynamic config node authorizer sets up access rules for dynamic config Feb 22, 2018
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 22, 2018
@mtaufen mtaufen removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Feb 22, 2018
@mtaufen mtaufen modified the milestones: next-candidate, v1.10 Feb 26, 2018
@mtaufen
Copy link
Contributor Author

mtaufen commented Feb 26, 2018

I sent pings trying to get this approved for 1.10 milestone, if it doesn't, so be it.


path := "nil"
if node.Spec.ConfigSource != nil {
path = fmt.Sprintf("/api/v1/namespaces/%s/configmaps/%s", namespace, name)
Copy link
Member

Choose a reason for hiding this comment

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

just log %s/%s namespace/name, no need to make the API 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.

will do

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

@liggitt
Copy link
Member

liggitt commented Mar 22, 2018

add a positive and negative test case to the auth/node integration test as well

if ref := source.ConfigMapRef; ref != nil {
count++
// name, namespace, and UID must all be non-empty for ConfigMapRef
if ref.Name == "" || ref.Namespace == "" || string(ref.UID) == "" {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has been a requirement of dynamic Kubelet config since the original proposal, to require users to be completely explicit (time and space) about which ConfigMap to use. If the UID in the config source doesn't match the UID of the ConfigMap, the Kubelet currently rejects it.

IIRC there were concerns along the lines of ConfigMaps being deleted and recreated with the same name but different content... though this is less of an issue today now that we have the --append-hash option in kubectl (obviously the potential for in-place ConfigMap mutation still exists, but if users are using --append-hash I wouldn't expect them to mutate the ConfigMap after creation).

The Kubelet also checkpoints by UID, so it was convenient to already have this specified in the object ref, though I guess if we relaxed this requirement it could just resolve the UID and stick it in the local copy of the config source when it first downloads the ConfigMap.

I can't remember other reasons to require UID, if any.

We should probably discuss this in parallel to this PR; if we relax the UID requirement there is other code that needs to change too, and I'd like to make all those changes in a single, isolated PR. I'm glad you brought this up; having this discussion prior to DKC beta was on my todo list.


path := "nil"
if node.Spec.ConfigSource != nil {
path = fmt.Sprintf("/api/v1/namespaces/%s/configmaps/%s", namespace, name)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

will do

defer g.lock.Unlock()

// nothing to do if we don't have a node
if len(nodeName) > 0 {
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 guess I wouldn't expect us to get a node with an empty name, but would we catch such a case earlier than this?

// must be called under write lock
// deletes edges from a given vertex type to a given vertex type
// will also delete the "from" nodes if they are orphaned, but will not delete the "to" node
func (g *Graph) deleteEdges_locked(fromType, toType vertexType, toNamespace, toName string) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree wrt tests, will add
pretty much indifferent on whether we make this a generic graph method

g.deleteEdges_locked(configMapVertexType, nodeVertexType, "", nodeName)

// establish new edges if we have a real ConfigMap to reference
if len(configMapName) > 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

note to self, also handle empty namespace?

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, now we also skip if the namespace is an empty string

func (g *Graph) DeleteNode(nodeName string) {
g.lock.Lock()
defer g.lock.Unlock()
if len(nodeName) > 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this check probably also unnecessary wrt @liggitt's comment above

Copy link
Member

Choose a reason for hiding this comment

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

I think this whole function is not needed (and was weird anyway, since it didn't actually delete the node)

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


func (g *graphPopulator) deleteNode(obj interface{}) {
node := obj.(*api.Node)
g.graph.DeleteNode(node.Name)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, since we don't actually delete the Node from the graph anyway, that sounds like it'd work.

@mtaufen mtaufen force-pushed the node-authz-nodeconfigsource branch from 2c870de to 1311235 Compare March 23, 2018 22:23
Copy link
Contributor Author

@mtaufen mtaufen left a comment

Choose a reason for hiding this comment

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

Updated, still have to add the integration test cases.


path := "nil"
if node.Spec.ConfigSource != nil {
path = fmt.Sprintf("/api/v1/namespaces/%s/configmaps/%s", namespace, name)
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

defer g.lock.Unlock()

// nothing to do if we don't have a node
if len(nodeName) > 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's a similar len(nodeName) check in this file in AddVolumeAttachment, is there a reason for this one?

g.deleteEdges_locked(configMapVertexType, nodeVertexType, "", nodeName)

// establish new edges if we have a real ConfigMap to reference
if len(configMapName) > 0 {
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, now we also skip if the namespace is an empty string

func (g *Graph) DeleteNode(nodeName string) {
g.lock.Lock()
defer g.lock.Unlock()
if len(nodeName) > 0 {
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


func (g *graphPopulator) deleteNode(obj interface{}) {
node := obj.(*api.Node)
g.graph.DeleteNode(node.Name)
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

// must be called under write lock
// deletes edges from a given vertex type to a given vertex type
// will also delete the "from" nodes if they are orphaned, but will not delete the "to" node
func (g *Graph) deleteEdges_locked(fromType, toType vertexType, toNamespace, toName string) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

added some test cases

@mtaufen mtaufen force-pushed the node-authz-nodeconfigsource branch 3 times, most recently from 56e65a4 to 8069d89 Compare March 23, 2018 23:23
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 23, 2018
@mtaufen mtaufen force-pushed the node-authz-nodeconfigsource branch 7 times, most recently from 8e6fdcb to 105e546 Compare March 24, 2018 03:30
@mtaufen mtaufen force-pushed the node-authz-nodeconfigsource branch 2 times, most recently from 4ef3454 to 7bb2e74 Compare March 27, 2018 15:48
This PR makes the node authorizer automatically set up access rules for
dynamic Kubelet config.

I also added some validation to the node strategy, which I discovered we
were missing while writing this.
@mtaufen mtaufen force-pushed the node-authz-nodeconfigsource branch from 7bb2e74 to ab8dc12 Compare March 27, 2018 15:49
@mtaufen
Copy link
Contributor Author

mtaufen commented Mar 29, 2018

/retest

Name: "myconfigmapconfigsource",
// validation just requires UID to be non-empty and it isn't necessary for GET,
// so we just use a bogus one for the test
UID: "uid",
Copy link
Member

Choose a reason for hiding this comment

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

if you have valid data from creating the configmap above, go ahead and set it here

@liggitt
Copy link
Member

liggitt commented Mar 29, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 29, 2018
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: liggitt, mtaufen

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 29, 2018
@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 61829, 61908, 61307, 61872, 60100). If you want to cherry-pick this change to another branch, please follow the instructions here.

@k8s-github-robot k8s-github-robot merged commit 5ae7bba into kubernetes:master Mar 30, 2018
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/kubelet area/kubelet-api cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/node Categorizes an issue or PR as relevant to SIG Node. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants