<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Jul 11, 2018 at 12:10 PM <nert@wheatley> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Mon, Jul 09, 2018 at 05:00:49PM -0400, Jason Baron wrote:<br>
><br>
><br>
>On 07/08/2018 02:01 AM, Martin Kletzander wrote:<br>
>> On Thu, Jul 05, 2018 at 06:24:20PM +0200, Roman Mohr wrote:<br>
>>> On Thu, Jul 5, 2018 at 4:20 PM Jason Baron <<a href="mailto:jbaron@akamai.com" target="_blank">jbaron@akamai.com</a>> wrote:<br>
>>><br>
>>>> Hi,<br>
>>>><br>
>>>> Opening tap devices, such as macvtap, that are created in containers is<br>
>>>> problematic because the interface for opening tap devices is via<br>
>>>> /dev/tapNN and devtmpfs is not typically mounted inside a container as<br>
>>>> its not namespace aware. It is possible to do a mknod() in the<br>
>>>> container, once the tap devices are created, however, since the tap<br>
>>>> devices are created dynamically its not possible to apriori allow access<br>
>>>> to certain major/minor numbers, since we don't know what these are going<br>
>>>> to be. In addition, its desirable to not allow the mknod capability in<br>
>>>> containers. This behavior, I think is somewhat inconsistent with the<br>
>>>> tuntap driver where one can create tuntap devices inside a container by<br>
>>>> first opening /dev/net/tun and then using them by supplying the tuntap<br>
>>>> device name via the ioctl(TUNSETIFF). And since TUNSETIFF validates the<br>
>>>> network namespace, one is limited to opening network devices that belong<br>
>>>> to your current network namespace.<br>
>>>><br>
>>>> Here are some options to this issue, that I wanted to get feedback<br>
>>>> about, and just wondering if anybody else has run into this.<br>
>>>><br>
>>>> 1)<br>
>>>><br>
>>>> Don't create the tap device, such as macvtap in the container. Instead,<br>
>>>> create the tap device outside of the container and then move it into the<br>
>>>> desired container network namespace. In addition, do a mknod() for the<br>
>>>> corresponding /dev/tapNN device from outside the container before doing<br>
>>>> chroot().<br>
>>>><br>
>>>> This solution still doesn't allow tap devices to be created inside the<br>
>>>> container. Thus, in the case of kubevirt, which runs libvirtd inside of<br>
>>>> a container, it would mean changing libvirtd to open existing tap<br>
>>>> devices (as opposed to the current behavior of creating new ones). This<br>
>>>> would not require any kernel changes, but as mentioned seems<br>
>>>> inconsistent with the tuntap interface.<br>
>>>><br>
>>><br>
>>> For KubeVirt, apart from how exactly the device ends up in the<br>
>>> container, I<br>
>>> would want to pursue a way where all network preparations which require<br>
>>> privileges happens from a privileged process *outside* of the container.<br>
>>> Like CNI solutions do it. They run outside, have privileges and then<br>
>>> create<br>
>>> devices in the right network/mount namespace or move them there. The<br>
>>> final<br>
>>> goal for KubeVirt is that our pod with the qemu process is completely<br>
>>> unprivileged and privileged setup happens from outside.<br>
>>><br>
>>> As a consequence, and depending on which route Dan pursues with the<br>
>>> restructured libvirt, I would assume that either a privileged<br>
>>> libvirtd-part<br>
>>> outside of containers creates the devices by entering the right<br>
>>> namespaces,<br>
>>> or that libvirt in the container can consume pre-created tun/tap devices,<br>
>>> like qemu.<br>
>>><br>
>><br>
>> That would be nice, but as far as I understand there will always be a<br>
>> need for<br>
>> some privileges if you want to use a tap device.  It's nice that CNI<br>
>> does that<br>
>> and all the containers can run unprivileged, but that's because they do<br>
>> not open<br>
>> the tap device and they do not do any privileged operations on it.  But<br>
>> QEMU<br>
>> needs to.  So the only way would be passing an opened fd to the<br>
>> container or<br>
>> opening the tap device there and making the fd usable for one process in<br>
>> the<br>
>> container.  Is this already supported for some type of containers in<br>
>> some way?<br>
>><br>
>> Martin<br>
><br>
>Hi,<br>
><br>
>So another option here call it #3 is to pass open fds via unix sockets.<br>
>If there are privileged operations that QEMU is trying to do with the fd<br>
>though, how will opening it first and then passing it to an unprivileged<br>
>QEMU address that? Is the opener doing those operations first?<br>
><br>
<br>
Sorry for the confusion, but QEMU is not doing any privileged operations.  I got<br>
confused by the fact that anyone can open and do a R/W on a tap device.  But it<br>
looks like that's on purpose.  No capabilities are needed for opening<br>
/dev/net/tun and calling ioctl(TUNSETIFF) with existing name and then doing R/W<br>
operations on it.  It just works.<br>
<br>
Correct me if I'm wrong, but to sum it all up, the only things that we need to<br>
figure out (which might possibly be solved by ideas in the other thread) are:<br>
<br>
tap:<br>
- Existence of /dev/net/tun<br>
- Having permissions to open it (0666 by default, shouldn't be a nig deal)<br>
- Knowing the device name<br>
<br>
macvtap:<br>
- Existence of /dev/tapXX<br>
- Having permissions to open /dev/tapXX<br>
- One of the following:<br>
  - Knowing the device name (and being able to translate it using a netlink socket)<br>
  - Knowing the the device index<br>
<br>
The rest should be an implementation detail.<br>
<br>
Am I right?  Did I miss anything?</blockquote><div><br></div><div>At least from the KubeVirt use-case that sounds to be the things which we would need to solve the networking setup in a similar way like the Container Network Interface implementations solve the setup in k8s.</div><div><br></div><div>Best Regards,</div><div>Roman</div><div> </div></div></div>