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

[vpc-bridge] Support host port mapping for Windows #93

Merged
merged 2 commits into from
Jun 2, 2023

Conversation

rawahars
Copy link
Contributor

Summary

vpc-bridge CNI plugin (previously known as vpc-shared-eni) is used for networking on Windows nodes running in EKS. Presently, we do not support container to host port mapping using this CNI plugin. Therefore, vpc-bridge plugin silently ignores any port mapping between container to host for the configured endpoint.

As per the CNI convention, plugins can request that the runtime insert this dynamic configuration by explicitly listing their capabilities in the network configuration. Dynamic information (i.e. data that a runtime fills out) should be placed in a runtimeConfig section.
Reference: https://www.cni.dev/docs/conventions/#dynamic-plugin-specific-fields-capabilities--runtime-configuration

portMappings is one such capability.

In order to support host port usage, we need to add the appropriate policy during the HNS Endpoint creation.
However, as communicated in microsoft/Windows-Containers#360, we need to use HNS V2 for creating this endpoint policy. Therefore in this PR, we will enhance the vpc-bridge CNI plugin to predominantly use HNS V2 and also add support for host port mappings.

Description of changes:

we are making the following changes-

  • We will change the vpc-bridge CNI plugin to be HNS V2 first. This means that we will only use HNS V1 APIs for attaching the endpoint to the container when using docker runtime.
    • The HNS network would be created using V2 APIs
    • The endpoint would be created using V2 APIs
    • The Network and Endpoint policies would be V2 policies
  • We will add the RuntimeConfig using which CNI plugin can obtain the configured port mapping
  • We will add the appropriate policies to apply the port mappings.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Presently, in the `vpc-bridge` plugin, we use HNS V1 APIs to create the HNS network and the HNS endpoint. Once the endpoint is created, we use either V1 or V2 APIs for attaching the endpoint to the container.

Given that V2 is the way forward where Microsoft supports newer features, we are converting our plugins to be V2 first. In this commit, we make the following changes-
- We use HNS V2 to create the network
- We use HNS V2 to create the HNS endpoint

After that, we will use either V1 or V2 to attach the endpoint to our container/namespace depending upon the runtime.
@davidedmondsMPG
Copy link

Very interested in this - was somewhat surprised to discover that it wasn't already available on Windows on EKS, though it is understandable. Making this functionality work should enable using Agones on Windows nodes in EKS, as that makes fairly heavy use of HostPorts to expose game servers.

Copy link
Contributor

@ofiliz ofiliz left a comment

Choose a reason for hiding this comment

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

1st round of feedback.

plugins/vpc-bridge/network/network.go Outdated Show resolved Hide resolved
plugins/vpc-bridge/network/bridge_windows.go Show resolved Hide resolved
plugins/vpc-bridge/network/bridge_windows.go Outdated Show resolved Hide resolved
plugins/vpc-bridge/network/bridge_windows.go Show resolved Hide resolved
plugins/vpc-bridge/network/bridge_windows.go Outdated Show resolved Hide resolved
HostPort int `json:"hostPort"`
ContainerPort int `json:"containerPort"`
Protocol string `json:"protocol"`
HostIP string `json:"hostIP,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Where is "HostIP" used? I don't see any references to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

HostIP is part of the Pod spec. Reference here.

So we can use this field to specify the VIP on host to which we want to bind the port to. Reference here.

In the present PR I have not used the same since the implicit VIP is the host instance IP. Should we add support for passing HostIP?

Copy link
Contributor

Choose a reason for hiding this comment

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

We can add it later if we need to.
Also please make Protocol the first field.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes sure. I will then omit this field from the config for the time being.

plugins/vpc-bridge/config/netconfig.go Outdated Show resolved Hide resolved
log.Infof("Creating HNS network: %+v", hnsRequest)
hnsResponse, err := hcsshim.HNSNetworkRequest("POST", "", hnsRequest)
log.Infof("Creating HNS network: %+v", hnsNetwork)
hnsResponse, err := hnsNetwork.Create()
Copy link
Contributor

Choose a reason for hiding this comment

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

Switching to HCN (v2) is a major change. There may be various behavioral differences between v1 and v2 that are hard to notice just by reading this CR. This is just a reminder to ensure proper test coverage for all ECS and EKS supported OS versions and scenarios before merging.

network/vpc/vpc.go Outdated Show resolved Hide resolved
// protocolTcp indicates tcp protocol number for port mapping.
protocolTcp = 6
// protocolUdp indicates udp protocol number for port mapping.
protocolUdp = 17
Copy link
Contributor

Choose a reason for hiding this comment

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

These are not port definitions and therefore shouldn't be in port.go.
If you want to keep them and the ProtocolToNumber function in the vpc package, maybe create a new protocol.go and put them there? Also go convention is to keep acronyms uppercase as in "protocolTCP".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes sure. I will create a new file named protocol.go and refactor the methods there.

Presently, the vpc-bridge plugin silently ignores any port mapping between container to host for the configured endpoint.

As per the current CNI convention, plugins can request that the runtime insert this dynamic configuration by explicitly listing their capabilities in the network configuration. Dynamic information (i.e. data that a runtime fills out) should be placed in a runtimeConfig section. Reference: https://www.cni.dev/docs/conventions/#dynamic-plugin-specific-fields-capabilities--runtime-configuration

`portMappings` is one such capability. This change adds the support for creating NAT port mappings between container and host ports as configured by the runtime.
@ofiliz ofiliz merged commit 1d75c58 into aws:master Jun 2, 2023
2 checks passed
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.

None yet

3 participants