Skip to content

Commit

Permalink
rootless: support podman network create (CNI-in-slirp4netns)
Browse files Browse the repository at this point in the history
Usage:
```
$ podman network create foo
$ podman run -d --name web --hostname web --network foo nginx:alpine
$ podman run --rm --network foo alpine wget -O - http://web.dns.podman
Connecting to web.dns.podman (10.88.4.6:80)
...
<h1>Welcome to nginx!</h1>
...
```

See contrib/rootless-cni-infra for the design.

Signed-off-by: Akihiro Suda <[email protected]>
  • Loading branch information
AkihiroSuda committed Sep 9, 2020
1 parent d34868a commit f82abc7
Show file tree
Hide file tree
Showing 18 changed files with 401 additions and 48 deletions.
3 changes: 0 additions & 3 deletions cmd/podman/networks/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ var (
RunE: networkCreate,
Args: cobra.MaximumNArgs(1),
Example: `podman network create podman1`,
Annotations: map[string]string{
registry.ParentNSRequired: "",
},
}
)

Expand Down
3 changes: 0 additions & 3 deletions cmd/podman/networks/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ var (
RunE: networkInspect,
Example: `podman network inspect podman`,
Args: cobra.MinimumNArgs(1),
Annotations: map[string]string{
registry.ParentNSRequired: "",
},
}
)

Expand Down
3 changes: 0 additions & 3 deletions cmd/podman/networks/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ var (
Long: networklistDescription,
RunE: networkList,
Example: `podman network list`,
Annotations: map[string]string{
registry.ParentNSRequired: "",
},
}
)

Expand Down
3 changes: 0 additions & 3 deletions cmd/podman/networks/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ var (
RunE: networkRm,
Example: `podman network rm podman`,
Args: cobra.MinimumNArgs(1),
Annotations: map[string]string{
registry.ParentNSRequired: "",
},
}
)

Expand Down
4 changes: 3 additions & 1 deletion libpod/container_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -957,8 +957,10 @@ func (c *Container) completeNetworkSetup() error {
if err := c.syncContainer(); err != nil {
return err
}
if c.config.NetMode.IsSlirp4netns() {
if rootless.IsRootless() {
return c.runtime.setupRootlessNetNS(c)
} else if c.config.NetMode.IsSlirp4netns() {
return c.runtime.setupSlirp4netns(c)
}
if err := c.runtime.setupNetNS(c); err != nil {
return err
Expand Down
14 changes: 11 additions & 3 deletions libpod/container_internal_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ func (c *Container) prepare() error {
// Set up network namespace if not already set up
noNetNS := c.state.NetNS == nil
if c.config.CreateNetNS && noNetNS && !c.config.PostConfigureNetNS {
netNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
if rootless.IsRootless() && len(c.config.Networks) > 0 {
netNS, networkStatus, createNetNSErr = AllocRootlessCNI(context.Background(), c)
} else {
netNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
}
if createNetNSErr != nil {
return
}
Expand All @@ -98,8 +102,12 @@ func (c *Container) prepare() error {
}

// handle rootless network namespace setup
if noNetNS && c.config.NetMode.IsSlirp4netns() && !c.config.PostConfigureNetNS {
createNetNSErr = c.runtime.setupRootlessNetNS(c)
if noNetNS && !c.config.PostConfigureNetNS {
if rootless.IsRootless() {
createNetNSErr = c.runtime.setupRootlessNetNS(c)
} else if c.config.NetMode.IsSlirp4netns() {
createNetNSErr = c.runtime.setupSlirp4netns(c)
}
}
}()
// Mount storage if not mounted
Expand Down
11 changes: 0 additions & 11 deletions libpod/container_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package libpod

import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/rootless"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -68,16 +67,6 @@ func (c *Container) validate() error {
}
}

// Rootless has some requirements, compared to networks.
if rootless.IsRootless() {
if len(c.config.Networks) > 0 {
return errors.Wrapf(define.ErrInvalidArg, "cannot join CNI networks if running rootless")
}

// TODO: Should we make sure network mode is set to Slirp if set
// at all?
}

// Can only set static IP or MAC is creating a network namespace.
if !c.config.CreateNetNS && (c.config.StaticIP != nil || c.config.StaticMAC != nil) {
return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP or MAC address if not creating a network namespace")
Expand Down
24 changes: 23 additions & 1 deletion libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package libpod

import (
"bytes"
"context"
"crypto/rand"
"fmt"
"io"
Expand Down Expand Up @@ -208,6 +209,20 @@ func checkSlirpFlags(path string) (*slirpFeatures, error) {

// Configure the network namespace for a rootless container
func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
if ctr.config.NetMode.IsSlirp4netns() {
return r.setupSlirp4netns(ctr)
}
if len(ctr.config.Networks) > 0 {
// set up port forwarder for CNI-in-slirp4netns
netnsPath := ctr.state.NetNS.Path()
// TODO: support slirp4netns port forwarder as well
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath)
}
return nil
}

// setupSlirp4netns can be called in rootful as well as in rootless
func (r *Runtime) setupSlirp4netns(ctr *Container) error {
path := r.config.Engine.NetworkCmdPath

if path == "" {
Expand Down Expand Up @@ -711,7 +726,7 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {

logrus.Debugf("Tearing down network namespace at %s for container %s", ctr.state.NetNS.Path(), ctr.ID())

// rootless containers do not use the CNI plugin
// rootless containers do not use the CNI plugin directly
if !rootless.IsRootless() && !ctr.config.NetMode.IsSlirp4netns() {
var requestedIP net.IP
if ctr.requestedIP != nil {
Expand All @@ -738,6 +753,13 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
}
}

// CNI-in-slirp4netns
if rootless.IsRootless() && len(ctr.config.Networks) != 0 {
if err := DeallocRootlessCNI(context.Background(), ctr); err != nil {
return errors.Wrapf(err, "error tearing down CNI-in-slirp4netns for container %s", ctr.ID())
}
}

// First unmount the namespace
if err := netns.UnmountNS(ctr.state.NetNS); err != nil {
return errors.Wrapf(err, "error unmounting network namespace for container %s", ctr.ID())
Expand Down
4 changes: 4 additions & 0 deletions libpod/networking_unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
return define.ErrNotImplemented
}

func (r *Runtime) setupSlirp4netns(ctr *Container) error {
return define.ErrNotImplemented
}

func (r *Runtime) setupNetNS(ctr *Container) error {
return define.ErrNotImplemented
}
Expand Down
4 changes: 2 additions & 2 deletions libpod/oci_conmon_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
cmd.ExtraFiles = append(cmd.ExtraFiles, childSyncPipe, childStartPipe)
cmd.ExtraFiles = append(cmd.ExtraFiles, envFiles...)

if r.reservePorts && !ctr.config.NetMode.IsSlirp4netns() {
if r.reservePorts && !rootless.IsRootless() && !ctr.config.NetMode.IsSlirp4netns() {
ports, err := bindPorts(ctr.config.PortMappings)
if err != nil {
return err
Expand All @@ -1098,7 +1098,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
cmd.ExtraFiles = append(cmd.ExtraFiles, ports...)
}

if ctr.config.NetMode.IsSlirp4netns() {
if ctr.config.NetMode.IsSlirp4netns() || rootless.IsRootless() {
if ctr.config.PostConfigureNetNS {
havePortMapping := len(ctr.Config().PortMappings) > 0
if havePortMapping {
Expand Down
Loading

0 comments on commit f82abc7

Please sign in to comment.