diff options
Diffstat (limited to 'libpod/networking.go')
-rw-r--r-- | libpod/networking.go | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/libpod/networking.go b/libpod/networking.go index 24e6339d7..082aae20d 100644 --- a/libpod/networking.go +++ b/libpod/networking.go @@ -1,10 +1,15 @@ package libpod import ( + "net" + "strings" + "github.com/containernetworking/plugins/pkg/ns" "github.com/cri-o/ocicni/pkg/ocicni" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/kubelet/network/hostport" ) // Get an OCICNI network config @@ -18,6 +23,32 @@ func getPodNetwork(id, name, nsPath string, ports []ocicni.PortMapping) ocicni.P } } +// Convert port mapping struct from OCICNI version to one Kubernetes understands +func portMappingToHostport(mappings []ocicni.PortMapping) ([]*hostport.PortMapping, error) { + newMappings := make([]*hostport.PortMapping, len(mappings)) + for _, port := range mappings { + var protocol v1.Protocol + switch strings.ToLower(port.Protocol) { + case "udp": + protocol = v1.ProtocolUDP + case "tcp": + protocol = v1.ProtocolTCP + default: + return nil, errors.Wrapf(ErrInvalidArg, "protocol must be TCP or UDP, instead got %s", port.Protocol) + } + + newPort := new(hostport.PortMapping) + newPort.Name = "" + newPort.HostPort = port.HostPort + newPort.ContainerPort = port.ContainerPort + newPort.Protocol = protocol + newPort.HostIP = port.HostIP + + newMappings = append(newMappings, newPort) + } + return newMappings, nil +} + // Create and configure a new network namespace for a container func (r *Runtime) createNetNS(ctr *Container) (err error) { ctrNS, err := ns.NewNS() @@ -38,7 +69,32 @@ func (r *Runtime) createNetNS(ctr *Container) (err error) { return errors.Wrapf(err, "error configuring network namespace for container %s", ctr.ID()) } - // TODO hostport mappings for forwarded ports + if len(ctr.config.PortMappings) != 0 { + ip, err := r.netPlugin.GetPodNetworkStatus(podNetwork) + if err != nil { + return errors.Wrapf(err, "failed to get status of network for container %s", ctr.ID()) + } + + ip4 := net.ParseIP(ip).To4() + if ip4 == nil { + return errors.Wrapf(err, "failed to parse IPv4 address for container %s", ctr.ID()) + } + + portMappings, err := portMappingToHostport(ctr.config.PortMappings) + if err != nil { + return errors.Wrapf(err, "failed to generate port ammpings for container %s", ctr.ID()) + } + + err = r.hostportManager.Add(ctr.ID(), &hostport.PodPortMapping{ + Name: ctr.Name(), + PortMappings: portMappings, + IP: ip4, + HostNetwork: false, + }, "lo") + if err != nil { + return errors.Wrapf(err, "failed to add port mappings for container %s", ctr.ID()) + } + } ctr.state.NetNS = ctrNS @@ -62,7 +118,22 @@ func (r *Runtime) teardownNetNS(ctr *Container) error { return nil } - // TODO hostport mappings for forwarded ports should be undone + portMappings, err := portMappingToHostport(ctr.config.PortMappings) + if err != nil { + logrus.Errorf("Failed to generate port mappings for container %s: %v", ctr.ID(), err) + } else { + // Only attempt to remove hostport mappings if we successfully + // converted to hostport-style mappings + err := r.hostportManager.Remove(ctr.ID(), &hostport.PodPortMapping{ + Name: ctr.Name(), + PortMappings: portMappings, + HostNetwork: false, + }) + if err != nil { + logrus.Errorf("Failed to tear down port mappings for container %s: %v", ctr.ID(), err) + } + } + podNetwork := getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.PortMappings) // The network may have already been torn down, so don't fail here, just log |