-
Notifications
You must be signed in to change notification settings - Fork 797
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
tuning: revert values on delete #540
Conversation
Values changed by Tuning plugin should be changed only for pod, therefore should be reverted when NIC is being moved from pod back to host. Fixes issue containernetworking#493 Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
c837d7a
to
8e842c4
Compare
Any reason not to restore sysctls as well? |
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.
Tens of lines of cosmetic changes make a PR harder to review, so please take them out.
If you like, make a separate PR that is just those changes.
plugins/meta/tuning/tuning.go
Outdated
@@ -258,7 +405,7 @@ func cmdCheck(args *skel.CmdArgs) error { | |||
|
|||
// Parse previous result. | |||
if tuningConf.RawPrevResult == nil { | |||
return fmt.Errorf("Required prevResult missing") | |||
return fmt.Errorf("required prevResult missing") |
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.
cosmetic
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 believe I have deleted all the cosmetic changes.
plugins/meta/tuning/tuning.go
Outdated
if err != nil { | ||
return fmt.Errorf("failed to marshall data for %q: %v", ifName, err) | ||
} | ||
if err = ioutil.WriteFile(path.Join(backupDir, ifName+".json"), data, 0600); err != nil { |
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.
Is it a wise choice to cache something inside container? Or /var/lib/cni/
on host is a better place? which is just being used by IPAM plugin host-local
.
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.
Backup file is stored in host's filesystem (/var/lib/cni/tunig
by default). I think that storing backup in the container wouldn't be wise as container is not exactly persistent and might be for example deleted outside of the K8s. Additionally I think that if NIC is host's resource, therefore NIC's config should be stored on host itself.
Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
61b8acb
to
2ac93c3
Compare
@squeed I believe that sysctls are set per namespace so setting those in container does not affect the host's setup, therefore I think that it is not necessary to restore this settings in any way.
|
plugins/meta/tuning/tuning.go
Outdated
} | ||
} | ||
|
||
backupDir := path.Join(backupPath, containerID) |
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.
Rather than creating a directory per container, just join container id + ifname - that's what we do in other plugins.
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.
Done :)
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, I forgot about tests. Fixed.
Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
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.
Some thoughts below
plugins/meta/tuning/tuning.go
Outdated
@@ -205,6 +332,11 @@ func cmdAdd(args *skel.CmdArgs) error { | |||
} | |||
} | |||
|
|||
isTuned := (tuningConf.Mac != "" || tuningConf.Mtu != 0 || tuningConf.Promisc) | |||
if err = createBackup(args.IfName, args.ContainerID, tuningConf.DataDir, isTuned, tuningConf); err != nil { |
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.
could we just skip creating a backup if nothing was tuned?
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 initially though that it would be better to create a file even if nothing's changed just to avoid using the file existence check as indicator of whenever something has to be restored. However changed that as it seems that it may be more clear in general.
@@ -60,6 +66,14 @@ type IPAMArgs struct { | |||
Mtu *int `json:"mtu,omitempty"` | |||
} | |||
|
|||
// configToRestore will contain interface attributes that should be restored on cmdDel | |||
type configToRestore struct { |
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.
It strikes me that this struct could be a part of TuningConf
, which would remove the need to repeat all fields.
(and maybe part of IPAMArgs
?)
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.
@bboreham I've changed the code. Renamed configToRestore
to ifConfig
and made it a part of IPAMArgs
. I chose IPAMArgs
because Promisc
field in that structure is a pointer to bool same as in configToRestore
. In case of json, simple bool will be omitted if it's value will be false
and omitempty
were specified. And I believe that in case of future development or just to avoid ambiguity it would be better to save exact value of Promisc
in backup file whether it is true or false.
Which leads me to another question I was wondering regarding the Promisc bool
in TuningConf
. In original code of cmdAdd
there is
if tuningConf.Promisc != false {
if err = changePromisc(args.IfName, true); err != nil {
return err
}
}
So if user will have a NIC with promiscuous mode enabled, and would like to switch promisc off using tuning (by setting promisc to false), then tuning plugin will not disable the promiscuous mode on that NIC as the code inside if statement will not be executed. Is this an expected behaviour, e.g. linked to problems with some particular NIC or driver? If not, then Promisc bool
could be changed to pointer, alongside MAC and MTU variables, and therefore ifConfig
could be used in both IPAMArgs
and TuningConf
. I think that this shouldn't be a part of this PR anyway, so this question is just out of curiosity.
plugins/meta/tuning/README.md
Outdated
@@ -46,6 +46,8 @@ The parameters, "mac", "mtu" and "promisc", changes the interface attributes as | |||
} | |||
``` | |||
|
|||
All the interface attributes set by tuning plugin will be restored to original values on container's removal. |
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.
except sysctls?
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've made the info more precise.
Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
plugins/meta/tuning/tuning.go
Outdated
Promisc *bool `json:"promisc,omitempty"` | ||
Mtu *int `json:"mtu,omitempty"` | ||
SysCtl *map[string]string `json:"sysctl"` | ||
IfConfig *ifConfig `json:"ifConfig,omitempty"` |
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 would be changing the configuration format, which we shouldn't do. Do you just want to embed the IfConfig struct?
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 was changed because of @bboreham request: #540 (comment)
I have explained this under that comment. If you need any more explanation, don't hesitate to ask.
Should I revert this change?
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.
The explanation helps, but it does not override the point that we can't just make a breaking change to the API because you think it's nicer.
I did say "maybe"; if it can't be done, so be 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.
5739f37
to
16f2dd3
Compare
plugins/meta/tuning/tuning.go
Outdated
return fmt.Errorf("failed to remove file %v: %v", filePath, err) | ||
} | ||
|
||
if err = delDirIfEmpty(backupPath); err != nil { |
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.
Now that we are using a single data directory, there's probably no point in removing the directory at all.
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.
Removed delDirIfEmpty
and it's invocation.
plugins/meta/tuning/tuning.go
Outdated
@@ -37,9 +40,12 @@ import ( | |||
bv "github.com/containernetworking/plugins/pkg/utils/buildversion" | |||
) | |||
|
|||
const defaultDataDir = "/var/lib/cni/tuning" |
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 know we use /var/lib/cni
for lots of other plugins, but that was a mistake I'm trying to undo. Can you make the default directory /run/cni/tuning
please?
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.
By using /run
, we don't have to worry about cleaning up stale containers on reboot.
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.
Done :)
Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
plugins/meta/tuning/tuning.go
Outdated
|
||
config := configToRestore{} | ||
if err = json.Unmarshal([]byte(file), &config); err != nil { | ||
return fmt.Errorf("failed to unmarshall file %q: %v", filePath, 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.
If this fails, just log an error and return; we don't want to block deletion.
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.
How should be an error logged?
Returned nil for now.
plugins/meta/tuning/tuning.go
Outdated
|
||
_, err = netlink.LinkByName(ifName) | ||
if err != nil { | ||
return fmt.Errorf("failed to get %q: %v", ifName, 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.
Log here and return; the interface is clearly deleted :-)
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.
Same as above - just returned nil for now.
plugins/meta/tuning/tuning.go
Outdated
|
||
if config.Mtu != 0 { | ||
if err = changeMtu(ifName, config.Mtu); err != nil { | ||
err = fmt.Errorf("failed to restore MAC address: %v", 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.
"failed to restore MTU"
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 :)
plugins/meta/tuning/tuning.go
Outdated
return err | ||
} | ||
|
||
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) 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.
now that I think about it, do we want to block deletion at all if this fails? When would there be an error that could be recoverable on retry?
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.
OK, I think you're right. Changed this to return always nil at the end, same as the 'stub' function that was here previously.
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.
Should this
tuningConf, err := parseConf(args.StdinData, args.Args)
if err != nil {
return err
}
also be forced to return nil?
Signed-off-by: Patryk Strusiewicz-Surmacki <patrykx.strusiewicz-surmacki@intel.com>
looks good to me. |
This PR will introduce NIC's attributes restoration as described in Issue #493: Tuning Plugin: Revert Values on Delete.
Currently when NIC's attributes (MAC, promiscuous mode, MTU) are changed by Tuning plugin, they remain as set even when pod is deleted and NIC is moved back to host's networking namespace. With this PR, JSON-based backup file will be created in
dataDir
(defaults to:/var/lib/cni/tuning
), and it will be used to restore the NIC's attributes to original ones on pod deletion.Readme and tests were updated as well to reflect those changes.