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

Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment #39

Merged
merged 4 commits into from
Mar 2, 2021

Conversation

Mmduh-483
Copy link
Contributor

@Mmduh-483 Mmduh-483 commented Jan 7, 2021

This PR introduces new changes to support changing E-switch mode for vanilla Kubernetes

  • Introduce service package to maintain services on vanilla Kubernetes, this is needed as an alternative for Openshift MCO
  • Move bindata/manifests/machine-config to bindata/manifests/switchdev-config, to avoid confuion of Openshift MCO
  • Introduce Kubernetes plugin to maintain services for switchdev
  • Add documention for hardware offload

@Mmduh-483 Mmduh-483 changed the title [WIP] Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Jan 10, 2021
@Mmduh-483 Mmduh-483 changed the title Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment [WIP] Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Jan 17, 2021
@Mmduh-483 Mmduh-483 force-pushed the switchdev-k8s branch 2 times, most recently from 60a0192 to 9a50ee9 Compare January 18, 2021 10:51
@Mmduh-483 Mmduh-483 changed the title [WIP] Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Jan 18, 2021
@Mmduh-483 Mmduh-483 changed the title Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment [WIP] Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Jan 25, 2021
@Mmduh-483 Mmduh-483 force-pushed the switchdev-k8s branch 2 times, most recently from 5fa8518 to b863730 Compare January 25, 2021 16:18
}

// ServiceAppend appends missing fields of serviceB into serviceA
func ServiceAppend(serviceA, serviceB *Service) (*Service, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you can change to ServiceAppend(serviceA *Service, contentToAppend)((*Service, error)
Why do you need the serviceB?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also maybe change to AppendToService to be same as RemoveFromService

return false, nil
}

// CompareServices compare 2 service and return true if serviceA has all the fields of serviceB
Copy link
Collaborator

Choose a reason for hiding this comment

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

update comment

}
}

if !found {
Copy link
Collaborator

Choose a reason for hiding this comment

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

so after reading about the break label I think what you did first with the outer was better to break from both loops.

return cmd.Run()
}

func (sm *serviceManager) isServiceLoaded(servicePath string) (bool, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

What do you mean by loaded?
Do you mean if the Service is activate? start? and why checking the file is good enough ?

}

// DisableService disables service with systemctl disable and removes service file
func (sm *serviceManager) DisableService(service *Service) error {
Copy link
Collaborator

Choose a reason for hiding this comment

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

are you using all the serviceManager apis? if not just keep the ones that you are currently use.


if updateTarget.networkManager {
nmService, err := serviceManager.ReadService(networkManagerService.Path)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

were is the ovs service?

@Mmduh-483 Mmduh-483 force-pushed the switchdev-k8s branch 2 times, most recently from 66035f1 to d6aebc4 Compare January 26, 2021 06:31
var (
Plugin K8sPlugin

serviceManager service.ServiceManager
Copy link
Collaborator

Choose a reason for hiding this comment

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

alignment

}

const (
mcoManifestPath = "bindata/manifests/machine-config/"
Copy link
Collaborator

Choose a reason for hiding this comment

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

let rename the folder to be bindata/manifests/switchdev-config/
and MCO andK8s both of them will use it.

}
}

type McoServiceInjection struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

remove all the Mco prefix from all the struct as they are not releated to MCO

lifecycle:
preStop:
exec:
command: ["/bin/sh","-c","rm -f /host/etc/systemd/system/switchdev-configuration.service"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is not good enough. We should undo all the other changes

pkg/plugins/k8s/k8s_plugin.go Show resolved Hide resolved
pkg/plugins/k8s/k8s_plugin.go Show resolved Hide resolved
}

func updateService(serviceObj *service.Service) error {
systemService, err := serviceManager.ReadService(serviceObj.Path)
Copy link
Collaborator

Choose a reason for hiding this comment

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

if you will move the compare here you won't need to check if that service need update.
Just do it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updateService is called from Apply when there is change needed, the compare is running from OnNodeChange which check if there is change needed to be applied

@Mmduh-483 Mmduh-483 force-pushed the switchdev-k8s branch 2 times, most recently from 0880741 to 357bdb2 Compare January 28, 2021 08:21

clean_services
# Reload host services
chroot $chroot_path /bin/bash -c systemctl daemon-reload > /dev/null
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't you restart the ovs and NM services?

updateList = append(updateList, "SwitchdevService")
}
if u.switchdevScript {
updateList = append(updateList, "SwitchdevService")
Copy link
Collaborator

Choose a reason for hiding this comment

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

should be "switchdevScript"


p.updateTarget.reset()
// Check services
err = p.isServicesNeedUpdate()
Copy link
Collaborator

Choose a reason for hiding this comment

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

isServicesNeedUpdate should return bool not err

return nil
}

func (p *K8sPlugin) readSystemServiceManifestFile(path string) (*service.Service, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should move to be in the function ServiceManager file like the compare services

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 is reading from bindata/manifests/machine-config and parsing the yaml file, I don't think this is related to ServiceManager
WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not? because it end with yaml? I think in the future when we will add services if any it will be in the same approach. Don't you think?

@Mmduh-483 Mmduh-483 changed the title [WIP] Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Support changing Eswitch mode of SR-IOV NICs for kubernetes deployment Feb 1, 2021
@Mmduh-483 Mmduh-483 requested a review from moshe010 February 1, 2021 09:05
@Mmduh-483 Mmduh-483 force-pushed the switchdev-k8s branch 2 times, most recently from 5cbf7bd to 6a59056 Compare February 1, 2021 11:28
return nil
}

func (p *K8sPlugin) readManifestFiles() error {
Copy link
Collaborator

Choose a reason for hiding this comment

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

it better to read and inject for each service so network manager and ovs should have there own method.
so you have one method of NM and one for ovs which does the read and inject

pkg/plugins/k8s/k8s_plugin.go Outdated Show resolved Hide resolved
return []*service.Service{p.networkManagerService, p.openVSwitchService}
}

func (p *K8sPlugin) isSystemServiceNeedUpdate(serviceObj *service.Service) (bool, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

let split the logic.
You should have isSystemServiceExist() to validate at start
and then isSystemServiceNeedUpdate can return just bool

pkg/plugins/k8s/k8s_plugin.go Show resolved Hide resolved
}
if p.updateTarget.needUpdate() {
glog.Infof("k8s-plugin OnNodeStateChange(): needDrain to update %q", p.updateTarget)
needDrain = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't you need reboot?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding the services doesn't require reboot

Copy link
Collaborator

Choose a reason for hiding this comment

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

but what about the VF rep udev rename? it won't be triggered ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is possible to add an additional condition to the udev renaming to do reboot, but the PR of renaming is not merged yet

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry I don't follow why it better to do it in the udev PR and not here?

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 assume would be better because the udev is not merged yet, and when udev is merged we need to do another PR to support it for k8s_plugin

pkg/plugins/k8s/k8s_plugin.go Show resolved Hide resolved
pkg/plugins/k8s/k8s_plugin.go Show resolved Hide resolved
return err
}
if !exist {
continue
Copy link
Collaborator

Choose a reason for hiding this comment

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

if it not exist it a problem we should log error

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if it not exist it means the NetworkManager or ovs is not installed on the host so a warning would serve better unless you consider them a pre-request, WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The ovs is must not sure about the NM

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So it would be better to split the logic to check if the service needs an update because there are mandatory and optional services

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let assume all of are mandatory ovs and NM

}
if p.updateTarget.needUpdate() {
glog.Infof("k8s-plugin OnNodeStateChange(): needDrain to update %q", p.updateTarget)
needDrain = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry I don't follow why it better to do it in the udev PR and not here?

}
update = true
glog.V(2).Infof("WriteSwitchdevConfFile(): write %s to switchdev.conf", newContent)
err = ioutil.WriteFile(switchDevConfPath, []byte(newContent), 0666)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I assume this what the permission in the MCO commit. I think it better to change it to 644.
@zshi-redhat what do you thing?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, we only need this file be readable for users. mco/k8s plugins write the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

@martinkennelly
Copy link
Member

/LGTM - Can you document the feature to advertise it? I am not sure where, features in readme? - Maybe we need a switchdev doc.

@zshi-redhat
Copy link
Collaborator

/LGTM - Can you document the feature to advertise it? I am not sure where, features in readme? - Maybe we need a switchdev doc.

@Mmduh-483 would you mind write a section in doc/ovs-hw-offload.md for using switchdev device on k8s? Thanks!

@Mmduh-483
Copy link
Contributor Author

@moshe010 @zshi-redhat @martinkennelly added docs under doc/ovs-hw-offload.md

host net-device. The VF representor plays the same role as TAP devices
in Para-Virtual (PV) setup. A packet sent through the VF representor on the host
arrives to the VF, and a packet sent through the VF is received by its representor.

Copy link
Collaborator

Choose a reason for hiding this comment

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

we should have prerequisites section:

  1. ovs installed
  2. Network Manager installed

doc/ovs-hw-offload.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@moshe010 moshe010 left a comment

Choose a reason for hiding this comment

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

@martinkennelly can you please take a look again. documentation was added

@moshe010
Copy link
Collaborator

@zshi-redhat Can we merge this ?

Copy link
Collaborator

@pliurh pliurh left a comment

Choose a reason for hiding this comment

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

If I read the code correctly, the k8s plugin will always try to update the systemd services even when switchdev is not configured. Did I miss anything?

lifecycle:
preStop:
exec:
command: ["/bindata/scripts/clean-k8s-services.sh"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to always run this script when the daemonset pod is terminated? At least, I don't think we need it for openshift.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Update the script to exist if CLUSTER_TYPE==openshift

@Mmduh-483
Copy link
Contributor Author

If I read the code correctly, the k8s plugin will always try to update the systemd services even when switchdev is not configured. Did I miss anything?

Updated to update services and swithdev config if policy is switchdev

@Mmduh-483 Mmduh-483 force-pushed the switchdev-k8s branch 2 times, most recently from 71a4f56 to 5cbd2d5 Compare February 23, 2021 14:30
@pliurh
Copy link
Collaborator

pliurh commented Mar 2, 2021

@Mmduh-483 Could you add more information to the commit description? This patch does more than just changing Eswitch mode. Also, I suggest adding a 'TODO' in the code, saying we will address the enableOvsOffload flag issue in the future.

Add pkg/service which contain utils to read MCO files for switchdev
services and scripts, this package is needed because vanilla
Kubernetes doesn't have support MCO which is part of openshift

Signed-off-by: Mamduh Alassi <[email protected]>
…config

Avoid confusion by machine-config which is related to Openshift MCO

Signed-off-by: Mamduh Alassi <[email protected]>
Openshift is handling switchdev by mco_plugin which uses Openshift MCO
to handle the services, this commit introduce k8s_plugin which handle
the same logic for vanilla Kubernetes that is missing MCO

Signed-off-by: Mamduh Alassi <[email protected]>
@Mmduh-483
Copy link
Contributor Author

@Mmduh-483 Could you add more information to the commit description? This patch does more than just changing Eswitch mode. Also, I suggest adding a 'TODO' in the code, saying we will address the enableOvsOffload flag issue in the future.

Updated the PR with separated commits with detailed commit description for each commit and the PR description

@pliurh pliurh merged commit e213aa2 into k8snetworkplumbingwg:master Mar 2, 2021
@pliurh pliurh mentioned this pull request Mar 4, 2021
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants