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 Pod secondary interfaces on VLAN network #5365

Merged
merged 1 commit into from
Aug 22, 2023

Conversation

jianjuns
Copy link
Contributor

@jianjuns jianjuns commented Aug 8, 2023

This commit adds support for connecting Pod secondary interfaces to a VLAN network. A Pod secondary interface configured with the VLAN networkType will be connected to the secondary network OVS bridge, and the specified VLAN tag will be set on the OVS port.
This commit mostly follows the existing SR-IOV secondary network implementation, in which a Pod controller configures Pod secondary interfaces based on the local Pod events. It thus inherits the existing limitations, like secondary interface configuration is not persisted on the Node and may get lost after antrea-agent restarts.

Reorganize some files:
Renamed pkg/agent/cniserver/sriov.go to secondary.go, and put secondary interface configuration funcs there.
Move SR-IOV interface related code in pkg/agent/secondarynetwork/podwatch/controller.go to sriov.go.

Issue: #5278

@jianjuns jianjuns added area/component/cni Issues or PRs related to the cni component area/interface Issues or PRs related to network interfaces area/ovs Issues or PRs related to OVS labels Aug 8, 2023
@jianjuns jianjuns marked this pull request as ready for review August 9, 2023 23:32
Comment on lines 252 to 255
// Include the inner veth interface name in the name generation, as one Pod can have more
// than one interfaces inc. secondary interfaces, while the outer interface name must be
// be unique.
hostIfaceName := util.GenerateContainerOuterVethName(podName, podNamespace, containerID, containerIfaceName)
Copy link
Contributor

Choose a reason for hiding this comment

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

My understanding is that "inner veth" is usually referred to as containerVeth and the "outer veth" referred to as hostVeth. The CNI project seems to be using this terminology (https://github.com/containernetworking/plugins/blob/v1.3.0/pkg/ip/link_linux.go#L139).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to containerVeth and hostVeth.

pkg/agent/cniserver/pod_configuration.go Show resolved Hide resolved
}
hostIface := result.Interfaces[0]
containerIface := result.Interfaces[1]
klog.InfoS("Configured SR-IOV interface", "Pod", podName, "Namespace", podNamespace, "interface", containerInterfaceName, "hostInterface", hostIface)
Copy link
Contributor

Choose a reason for hiding this comment

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

use klog.KRef (or klog.KObj when appropriate) to log references to K8s objects:

	klog.InfoS("Configured SR-IOV interface", "Pod", klog.KRef(podNamespace, podName), "interface", containerInterfaceName, "hostInterface", hostIface)

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.

Comment on lines 30 to 35
const (
sriovNetworkType = "sriov"
vlanNetworkType = "vlan"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

should we create a dedicated type for this?

type NetworkType string
const (
    sriovNetworkType NetworkType = "sriov"
    vlanNetworkType NetworkType = "vlan"
)

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 a type.

@@ -38,5 +39,7 @@ type SecondaryNetworkConfig struct {
Type string `json:"type,omitempty"`
// Set networkType to "sriov"
NetworkType string `json:"networkType,omitempty"`
MTU int `json:"mtu, omitempty"`
VLAN uint16 `json:"vlan, omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

probably better to use int32 in a public API, especially since the max value is 4096 and you have to perform validation anyway
even though this is not a K8s API: https://github.com/zecke/Kubernetes/blob/master/docs/devel/api-conventions.md#primitive-types

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to int32

@@ -38,5 +39,7 @@ type SecondaryNetworkConfig struct {
Type string `json:"type,omitempty"`
// Set networkType to "sriov"
NetworkType string `json:"networkType,omitempty"`
MTU int `json:"mtu, omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

s/int/int32

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

Comment on lines 100 to 104
if cniType != "" {
configStr = strings.Replace(configStr, "type\": \"antrea", "type\": \""+cniType, 1)
}
configStr = strings.Replace(configStr, "mtu\": 1500", "mtu\": "+strconv.Itoa(mtu), 1)
configStr = strings.Replace(configStr, "vlan\": 100", "vlan\": "+strconv.Itoa(int(vlan)), 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO, you should use the text/template package to do this more cleanly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to text/template. Thanks for the suggestion.

CNIConfig: config2,
},
}
assert.True(t, reflect.DeepEqual(&savedCNIConfig, infos[0]))
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought assert.Equal already used reflect.DeepEqual to check for comparison?

https://github.com/stretchr/testify/blob/f97607b89807936ac4ff96748d766cf4b9711f78/assert/assertions.go#L58

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. Changed to use assert.Equal.

@jianjuns jianjuns force-pushed the sec-net-vlan branch 2 times, most recently from fb2bd0c to c5f19c5 Compare August 11, 2023 00:12
}

// ConfigureSriovSecondaryInterface configures a SR-IOV secondary interface for a Pod.
func (pc *podConfigurator) ConfigureSriovSecondaryInterface(
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 func is copied from the original cniserver/sriov.go without changes.

// See the License for the specific language governing permissions and
// limitations under the License.

package podwatch
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All funcs in this file are moved from podwatch/controller.go without changes.

Comment on lines 252 to 255
// Include the inner veth interface name in the name generation, as one Pod can have more
// than one interfaces inc. secondary interfaces, while the outer interface name must be
// be unique.
hostIfaceName := util.GenerateContainerOuterVethName(podName, podNamespace, containerID, containerIfaceName)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to containerVeth and hostVeth.

pkg/agent/cniserver/pod_configuration.go Show resolved Hide resolved
@@ -38,5 +39,7 @@ type SecondaryNetworkConfig struct {
Type string `json:"type,omitempty"`
// Set networkType to "sriov"
NetworkType string `json:"networkType,omitempty"`
MTU int `json:"mtu, omitempty"`
VLAN uint16 `json:"vlan, omitempty"`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to int32

@@ -38,5 +39,7 @@ type SecondaryNetworkConfig struct {
Type string `json:"type,omitempty"`
// Set networkType to "sriov"
NetworkType string `json:"networkType,omitempty"`
MTU int `json:"mtu, omitempty"`
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

Comment on lines 100 to 104
if cniType != "" {
configStr = strings.Replace(configStr, "type\": \"antrea", "type\": \""+cniType, 1)
}
configStr = strings.Replace(configStr, "mtu\": 1500", "mtu\": "+strconv.Itoa(mtu), 1)
configStr = strings.Replace(configStr, "vlan\": 100", "vlan\": "+strconv.Itoa(int(vlan)), 1)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to text/template. Thanks for the suggestion.

CNIConfig: config2,
},
}
assert.True(t, reflect.DeepEqual(&savedCNIConfig, infos[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.

You are right. Changed to use assert.Equal.

@jianjuns jianjuns force-pushed the sec-net-vlan branch 3 times, most recently from 5db5adf to 39a71fc Compare August 12, 2023 23:16
@jianjuns jianjuns requested a review from antoninbas August 15, 2023 23:47
Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

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

only a couple of nits, otherwise LGTM

// The probability of collision should be neglectable.
func GenerateContainerInterfaceName(podName, podNamespace, containerID string) string {
// Use the podName as the prefix and the containerID as the hashing key.
// podNamespace is not used currently.
return generateInterfaceName(containerID, podName, true)
}

// GenerateContainerOuterVethName generates a unique interface name using the
Copy link
Contributor

Choose a reason for hiding this comment

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

s/GenerateContainerOuterVethName/GenerateContainerHostVethName

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks.

Comment on lines 79 to 80
assert.True(t, len(ifaceName0) <= interfaceNameLength)
assert.True(t, strings.HasPrefix(ifaceName0, podName0+"-"))
Copy link
Contributor

Choose a reason for hiding this comment

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

use require as you typically want all the subtests below to be skipped if one of these assertions is false

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

containerID0 := "container0"
eth0 := "eth0"
ifaceName0 := GenerateContainerHostVethName(podName0, podNamespace0, containerID0, eth0)
assert.True(t, len(ifaceName0) <= interfaceNameLength)
Copy link
Contributor

Choose a reason for hiding this comment

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

require.Less

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

continue
}
if networkConfig.NetworkType == vlanNetworkType {
if networkConfig.VLAN > vlanIDMax || networkConfig.VLAN < 0 {
klog.ErrorS(nil, "Invalid VLAN ID", "NetworkAttachmentDefinition", klog.KObj(netDefCRD), "Pod", klog.KObj(pod))
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybe add the VLAN value to the log

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

}
}
if networkConfig.MTU < 0 {
klog.ErrorS(nil, "Invalid MTU", "NetworkAttachmentDefinition", klog.KObj(netDefCRD), "Pod", klog.KObj(pod))
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above, but for MTU

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

network2 := testNetwork("net2")
savedCNIConfig := *cniConfig
network1 := testNetwork("net1", sriovNetworkType)
network2 := testNetworkExt("net2", "", vlanNetworkType, defaultMTU, 100)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: define a local constant for the vlan id

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

This commit adds support for connecting Pod secondary interfaces to a
VLAN network. A Pod secondary interface configured with the VLAN
networkType will be connected to the secondary network OVS bridge, and
the specified VLAN tag will be set on the OVS port.
This commit mostly follows the existing SR-IOV secondary network
implementation, in which a Pod controller configures Pod secondary
interfaces based on the local Pod events. It thus inherits the existing
limitations, like secondary interface configuration is not persisted on
the Node and may get lost after antrea-agent restarts.

Signed-off-by: Jianjun Shen <shenj@vmware.com>
Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

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

LGTM

@jianjuns
Copy link
Contributor Author

/test-all

Copy link
Contributor

@arunvelayutham arunvelayutham left a comment

Choose a reason for hiding this comment

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

changes LGTM. thank you @jianjuns

@jianjuns jianjuns merged commit 391666f into antrea-io:main Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/component/cni Issues or PRs related to the cni component area/interface Issues or PRs related to network interfaces area/ovs Issues or PRs related to OVS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants