summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2017-12-08 15:11:14 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2017-12-14 23:59:21 +0000
commit840eb04e03e9292c54621c7ff75cbf95e690d86f (patch)
tree60216367054d06720a38ba96b1e1b1827e7e23a2 /libpod
parent316341a81dec52c5fd84c6e8c194639240c57273 (diff)
downloadpodman-840eb04e03e9292c54621c7ff75cbf95e690d86f.tar.gz
podman-840eb04e03e9292c54621c7ff75cbf95e690d86f.tar.bz2
podman-840eb04e03e9292c54621c7ff75cbf95e690d86f.zip
Add iptables integration to network code
Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #109 Approved by: mheon
Diffstat (limited to 'libpod')
-rw-r--r--libpod/networking.go75
-rw-r--r--libpod/runtime.go25
2 files changed, 87 insertions, 13 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
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 9712b6dd3..480da6677 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -12,6 +12,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/ulule/deepcopier"
+ "k8s.io/kubernetes/pkg/kubelet/network/hostport"
)
// A RuntimeOption is a functional option which alters the Runtime created by
@@ -20,16 +21,17 @@ type RuntimeOption func(*Runtime) error
// Runtime is the core libpod runtime
type Runtime struct {
- config *RuntimeConfig
- state State
- store storage.Store
- storageService *storageService
- imageContext *types.SystemContext
- ociRuntime *OCIRuntime
- lockDir string
- netPlugin ocicni.CNIPlugin
- valid bool
- lock sync.RWMutex
+ config *RuntimeConfig
+ state State
+ store storage.Store
+ storageService *storageService
+ imageContext *types.SystemContext
+ ociRuntime *OCIRuntime
+ lockDir string
+ netPlugin ocicni.CNIPlugin
+ hostportManager hostport.HostPortManager
+ valid bool
+ lock sync.RWMutex
}
// RuntimeConfig contains configuration options used to set up the runtime
@@ -170,7 +172,8 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
}
runtime.netPlugin = netPlugin
- // TODO: iptables/firewalld integration to ensure rules are in place for forwarding
+ // Set up the hostport manager
+ runtime.hostportManager = hostport.NewHostportManager()
// Set up the state
if runtime.config.InMemoryState {