all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jason Conroy <conjaroy@gmail.com>
To: Zhu Zihao <all_but_last@163.com>
Cc: help-guix@gnu.org
Subject: Re: Port forwarding for Guix containers
Date: Wed, 25 Nov 2020 11:14:27 -0500	[thread overview]
Message-ID: <CABWzUjVuE3Y7h6yuVcih8MJd1OmB8OHA6WLAS=2mRv2WoCPrMQ@mail.gmail.com> (raw)
In-Reply-To: <86lfesjb6q.fsf@163.com>

Hi Zihao,

It sounds like you're running Guix for your host OS and want to have Guix
containers inside of that? If that's so, then my existing config won't be
much use to you: right now I'm running my Guix containers (the `guix system
container` shell scripts) inside of Debian via systemd.

But in case it helps, I think this is how you could approximate what
"docker run --network --publish ..." does:

1) Create a persistent network namespace with `ip netns add`.
2) Use `ip link add` to create a pair of virtual ethernet interfaces (veth)
- one for the host and one for the container.
3) Use `ip link set <iface> netns <namespace>` so that one of the veth
interfaces appears inside of the namespace, while its peer remains on the
host side.
4) Assign each of the veth interfaces an address in the same subnet, but
choose a subset that's unused on your system. For example, 192.168.0.1 and
192.168.0.2 within the subnet 192.168.0.0/24.
5) Bring up the interfaces with `ip link set <iface> up`. Do the same for
the loopback interface (lo) inside the namespace.
6) Inside the namespace, set up a default route using the address of the
veth interface on the host side.
7) Use iptables to configure source network address translation (SNAT) for
the traffic originating from the namespace so that it can connect to
external hosts (e.g. via eth0).
8) Enable IP forwarding: set /proc/sys/net/ipv4/ip_forward to 1, and add
related rules to iptables' FORWARD chain (if your default iptables policy
is to DROP packets).
9) Finally, use iptables again to enable port forwarding (DNAT) from
external hosts to your container.

Here, "do X inside of a namespace" usually means `ip netns exec <namespace>
<command>`. When the command is /bin/bash you can explore the namespace's
environment interactively. The namespace persists until you call `ip netns
del <namespace>`.

With the exception of #9, there are examples of each task in the script I
mentioned up-thread:
https://gist.github.com/dpino/6c0dca1742093346461e11aa8f608a99#file-ns-inet-sh

For my purposes, dynamic configuration of namespaces, interfaces, routes,
etc. (like Docker does) seems unnecessarily complicated and fragile, so
I've taken the approach of setting up my namespaces once at boot, and then
the container startup script is as simple as `ip netns exec <namespace>
<guix-container-script>`. Even when the Guix container itself shuts down
and restarts, the namespace settings above are unchanged.

How would these network settings be implemented using Guix services? I
don't have experience in this area, so the following is just a guess:
iptables-service seems suitable for tasks #7 - #9, and there's
static-networking-service for assigning addresses in task #4 (but I think
it will only know about the veth interface outside the namespace, not the
one inside). For the rest, I think you'd need to define some new service to
set up the namespace and virtual interfaces, and ensure that this service
runs before static-networking-service.

Hope that helps,

Jason

On Mon, Nov 23, 2020 at 11:22 AM Zhu Zihao <all_but_last@163.com> wrote:

>
> That's what I want to say, thank you!
>
> I want to combine different software in containers in docker-compose
> like way. It's more similar with a system container then a `guix
> environment` container.
>
> I'm not a Docker hater, but docker will corrupt your iptables entry and
> make the system impure. If you wanna use iptables-service-type and
> docker-service-type together, when you run `herd restart iptables`. All
> docker specific rules will be erased.
>
> > Supposing that we've developed some system container that starts a
> service
> > on port N. If we want to run another instance of the same container, we
> > first need to override the port number for the service in our
> > operating-system, otherwise the service in the second container will fail
> > to bind to port N in the shared network namespace. With a couple of
> > one-service containers this may not be so hard, but system containers in
> > general could have lots of services, and the authors of individual
> > containers may not want to worry about choosing port numbers that are
> > mutually disjoint from those in all other containers (and those used by
> the
> > container host itself).
>
> --
> Retrieve my PGP public key: https://meta.sr.ht/~citreu.pgp
>
> Zihao
>

  reply	other threads:[~2020-11-25 16:15 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-19 15:58 Port forwarding for Guix containers Zhu Zihao
2020-11-20 18:44 ` Bonface M. K.
2020-11-20 19:26 ` Christopher Baines
2020-11-21 14:53   ` zimoun
2020-11-21 20:20     ` Edouard Klein
2020-11-21 21:45     ` Jason Conroy
2020-11-22 15:09       ` edk
2020-11-23 14:58         ` Jason Conroy
2020-11-23 16:16       ` Zhu Zihao
2020-11-23 16:21       ` Zhu Zihao
2020-11-25 16:14         ` Jason Conroy [this message]
2020-12-03  9:32           ` Zhu Zihao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CABWzUjVuE3Y7h6yuVcih8MJd1OmB8OHA6WLAS=2mRv2WoCPrMQ@mail.gmail.com' \
    --to=conjaroy@gmail.com \
    --cc=all_but_last@163.com \
    --cc=help-guix@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.