summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshley Cui <acui@redhat.com>2020-09-25 10:00:43 -0400
committerAshley Cui <acui@redhat.com>2020-09-25 21:34:23 -0400
commitb6176d8987a0049a253fd7a70b2cd8e17bd50b53 (patch)
treee4ce740ebc925079ab223b41acec4c15b85b6fd9
parent98aa458c7a13c72fabe02cd0ed2919c2801ef207 (diff)
downloadpodman-b6176d8987a0049a253fd7a70b2cd8e17bd50b53.tar.gz
podman-b6176d8987a0049a253fd7a70b2cd8e17bd50b53.tar.bz2
podman-b6176d8987a0049a253fd7a70b2cd8e17bd50b53.zip
Add support for slirp network for pods
flag --network=slirp4netns[options] for root and rootless pods Signed-off-by: Ashley Cui <acui@redhat.com>
-rw-r--r--cmd/podman/pods/create.go14
-rw-r--r--docs/source/markdown/podman-pod-create.1.md19
-rw-r--r--libpod/define/pod_inspect.go2
-rw-r--r--libpod/options.go20
-rw-r--r--libpod/pod.go2
-rw-r--r--libpod/pod_api.go2
-rw-r--r--libpod/runtime_pod_infra_linux.go5
-rw-r--r--pkg/domain/entities/pods.go1
-rw-r--r--pkg/specgen/generate/pod_create.go3
-rw-r--r--pkg/specgen/pod_validate.go4
-rw-r--r--pkg/specgen/podspecgen.go3
-rw-r--r--test/e2e/pod_create_test.go12
12 files changed, 78 insertions, 9 deletions
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index d8d32b930..ac6d83edd 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -141,14 +141,20 @@ func create(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+ parts := strings.SplitN(netInput, ":", 2)
+
n := specgen.Namespace{}
- switch netInput {
- case "bridge":
+ switch {
+ case netInput == "bridge":
n.NSMode = specgen.Bridge
- case "host":
+ case netInput == "host":
n.NSMode = specgen.Host
- case "slirp4netns":
+ case netInput == "slirp4netns", strings.HasPrefix(netInput, "slirp4netns:"):
n.NSMode = specgen.Slirp
+ if len(parts) > 1 {
+ createOptions.Net.NetworkOptions = make(map[string][]string)
+ createOptions.Net.NetworkOptions[parts[0]] = strings.Split(parts[1], ",")
+ }
default:
// Container and NS mode are presently unsupported
n.NSMode = specgen.Bridge
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index d60fc65fe..7b0902c19 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -81,7 +81,20 @@ Assign a name to the pod.
**--network**=*mode*
-Set network mode for the pod. Supported values are *bridge* (the default), *host* (do not create a network namespace, all containers in the pod will use the host's network), or a comma-separated list of the names of CNI networks the pod should join.
+Set network mode for the pod. Supported values are
+- `bridge`: Create a network stack on the default bridge. This is the default for rootful containers.
+- `host`: Do not create a network namespace, all containers in the pod will use the host's network. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
+- Comma-separated list of the names of CNI networks the pod should join.
+- `slirp4netns[:OPTIONS,...]`: use slirp4netns to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options:
+ - **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
+ - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`).
+ - **enable_ipv6=true|false**: Enable IPv6. Default is false. (Required for `outbound_addr6`).
+ - **outbound_addr=INTERFACE**: Specify the outbound interface slirp should bind to (ipv4 traffic only).
+ - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp should bind to.
+ - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp should bind to (ipv6 traffic only).
+ - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp should bind to.
+ - **port_handler=rootlesskit**: Use rootlesskit for port forwarding. Default.
+ - **port_handler=slirp4netns**: Use the slirp4netns port forwarding.
**--no-hosts**=**true**|**false**
@@ -129,6 +142,10 @@ $ podman pod create --infra=false
$ podman pod create --infra-command /top
$ podman pod create --publish 8443:443
+
+$ podman pod create --network slirp4netns:outbound_addr=127.0.0.1,allow_host_loopback=true
+
+$ podman pod create --network slirp4netns:cidr=192.168.0.0/24
```
## SEE ALSO
diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go
index 60e19fe05..a4115eb92 100644
--- a/libpod/define/pod_inspect.go
+++ b/libpod/define/pod_inspect.go
@@ -89,6 +89,8 @@ type InspectPodInfraConfig struct {
HostAdd []string
// Networks is a list of CNI networks the pod will join.
Networks []string
+ // NetworkOptions are additional options for each network
+ NetworkOptions map[string][]string
}
// InspectPodContainerInfo contains information on a container in a pod.
diff --git a/libpod/options.go b/libpod/options.go
index f7b3419e5..f7190d0e3 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -2203,3 +2203,23 @@ func WithPodInfraExitCommand(exitCmd []string) PodCreateOption {
return nil
}
}
+
+// WithPodSlirp4netns tells the pod to use slirp4netns.
+func WithPodSlirp4netns(networkOptions map[string][]string) PodCreateOption {
+ return func(pod *Pod) error {
+ if pod.valid {
+ return define.ErrPodFinalized
+ }
+
+ if !pod.config.InfraContainer.HasInfraContainer {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod networking as no infra container is being created")
+ }
+ if pod.config.InfraContainer.HostNetwork {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set both HostNetwork and Slirp4netns")
+ }
+ pod.config.InfraContainer.Slirp4netns = true
+ pod.config.InfraContainer.NetworkOptions = networkOptions
+
+ return nil
+ }
+}
diff --git a/libpod/pod.go b/libpod/pod.go
index 709184008..a5a0532be 100644
--- a/libpod/pod.go
+++ b/libpod/pod.go
@@ -107,6 +107,8 @@ type InfraContainerConfig struct {
ExitCommand []string `json:"exitCommand,omitempty"`
InfraImage string `json:"infraImage,omitempty"`
InfraCommand []string `json:"infraCommand,omitempty"`
+ Slirp4netns bool `json:"slirp4netns,omitempty"`
+ NetworkOptions map[string][]string `json:"network_options,omitempty"`
}
// ID retrieves the pod's ID
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index ec4cc08f7..0ae180356 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -584,7 +584,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
infraConfig.Networks = make([]string, 0, len(p.config.InfraContainer.Networks))
infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...)
}
-
+ infraConfig.NetworkOptions = p.config.InfraContainer.NetworkOptions
infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings)
}
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index 164068638..e8e71afd1 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -77,8 +77,11 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
// Since user namespace sharing is not implemented, we only need to check if it's rootless
if !p.config.InfraContainer.HostNetwork {
netmode := "bridge"
- if isRootless {
+ if isRootless || p.config.InfraContainer.Slirp4netns {
netmode = "slirp4netns"
+ if len(p.config.InfraContainer.NetworkOptions) != 0 {
+ options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions))
+ }
}
// PostConfigureNetNS should not be set since user namespace sharing is not implemented
// and rootless networking no longer supports post configuration setup
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 7b38dbd87..426419833 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -142,6 +142,7 @@ func (p PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) {
s.StaticMAC = p.Net.StaticMAC
s.PortMappings = p.Net.PublishPorts
s.CNINetworks = p.Net.CNINetworks
+ s.NetworkOptions = p.Net.NetworkOptions
if p.Net.UseImageResolvConf {
s.NoManageResolvConf = true
}
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 101201252..43caf0fe9 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -99,6 +99,9 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
case specgen.Host:
logrus.Debugf("Pod will use host networking")
options = append(options, libpod.WithPodHostNetwork())
+ case specgen.Slirp:
+ logrus.Debugf("Pod will use slirp4netns")
+ options = append(options, libpod.WithPodSlirp4netns(p.NetworkOptions))
default:
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
}
diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go
index 907c0bb69..a6c61a203 100644
--- a/pkg/specgen/pod_validate.go
+++ b/pkg/specgen/pod_validate.go
@@ -72,9 +72,9 @@ func (p *PodSpecGenerator) Validate() error {
return exclusivePodOptions("NoInfra", "NoManageResolvConf")
}
}
- if p.NetNS.NSMode != "" && p.NetNS.NSMode != Bridge && p.NetNS.NSMode != Default {
+ if p.NetNS.NSMode != "" && p.NetNS.NSMode != Bridge && p.NetNS.NSMode != Slirp && p.NetNS.NSMode != Default {
if len(p.PortMappings) > 0 {
- return errors.New("PortMappings can only be used with Bridge mode networking")
+ return errors.New("PortMappings can only be used with Bridge or slirp4netns networking")
}
if len(p.CNINetworks) > 0 {
return errors.New("CNINetworks can only be used with Bridge mode networking")
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index 3c32ec365..7d771f5bb 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -134,6 +134,9 @@ type PodNetworkConfig struct {
// Conflicts with NoInfra=true and NoManageHosts.
// Optional.
HostAdd []string `json:"hostadd,omitempty"`
+ // NetworkOptions are additional options for each network
+ // Optional.
+ NetworkOptions map[string][]string `json:"network_options,omitempty"`
}
// PodCgroupConfig contains configuration options about a pod's cgroups.
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index ed62e8a4b..c540b6e54 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -405,4 +405,16 @@ entrypoint ["/fromimage"]
Expect(check1.ExitCode()).To(Equal(0))
Expect(check1.OutputToString()).To(Equal("/fromcommand"))
})
+
+ It("podman create pod with slirp network option", func() {
+ name := "test"
+ session := podmanTest.Podman([]string{"pod", "create", "--name", name, "--network", "slirp4netns:port_handler=slirp4netns", "-p", "8082:8000"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ check := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.InfraConfig.NetworkOptions.slirp4netns}}", name})
+ check.WaitWithDefaultTimeout()
+ Expect(check.ExitCode()).To(Equal(0))
+ Expect(check.OutputToString()).To(Equal("[port_handler=slirp4netns]"))
+ })
})