Page MenuHomeVyOS Platform

containers: Expanding options for networking and building containers
Needs testing, Requires assessmentPublicFEATURE REQUEST

Description

The goal here was to gain a few more options around configurability for containers.

The two pieces of this goal are:

  • Better build configurability, without the need for a full blown custom repository. To this end, I've introduced the option to be able build a container based on a Dockerfile/Containerfile. This would allow near infinite configurability.
  • Better network management. I'm one that hates NAT/masquerading and the lack of concise control over the network. So this allows one to create a traditional bridge, minus the NAT, which can then be dropped into something like a zone firewall.

Example config:

admin@edge# show container 
 name ubuntubuild {
     containerfile /config/containers/kroytest.Containerfile
     image kroy/test
     network service01 {
         address 10.72.1.202
     }
 }
 name ubuntutest {
     image ubuntu:focal
     network service01 {
     }
 }
 network service01 {
     enable-bridging
     prefix 10.72.1.0/24
 }

The container, ubuntubuild builds a container based on the Containerfile noted and has a static IP

admin@edge# cat /config/containers/kroytest.Containerfile 
FROM ubuntu:20.04

RUN apt-get update -y
RUN apt-get install ssh-import-id -y 
RUN apt-get install openssh-server -y
RUN apt-get install iproute2 -y


CMD ssh-import-id-gh kroy-the-rabbit && service ssh start && bash

The container ubuntutest just pulls from the registry as normal. It gains an IP address automatically.

The next change is the enable-bridging in the network. This disables the masquerading functionality of the network and exposes the network directly.

So a traceroute through my desktop. Hop #2 is the VyOS install running the container.

❯ traceroute 10.72.1.202
traceroute to 10.72.1.202 (10.72.1.202), 30 hops max, 60 byte packets
 1  route01.lan.kroy.io (10.9.1.3)  0.662 ms  0.618 ms  0.606 ms
 2  10.245.245.9 (10.245.245.9)  0.860 ms  0.699 ms  0.838 ms
 3  10.72.1.202 (10.72.1.202)  0.881 ms  0.870 ms  0.860 ms

There are two outstanding things from this that I'm not fully sure how to resolve.

  • Right now this works flawlessly with zone based firewalls. But I'm not sure what to do to allow this interface to use traditional firewalling. Does it just need to include a template?
set zone-policy zone LAN interface cni-podman0
  • cnd-podman0 is now available for use in NAT/firewalling/etc. But it's ugly and not very VyOS-y. This can be changed, but I'm not sure to what. container0, container1 etc? Whatever this ends up being would also have to be added to the list-interfaces.py script.

This is all tested and working and pull request is incoming.

Details

Difficulty level
Unknown (require assessment)
Version
1.4-rolling
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Unspecified (possibly destroys the router)

Event Timeline

kroy changed the task status from Open to Needs testing.Aug 18 2021, 4:46 PM
kroy claimed this task.
kroy updated the task description. (Show Details)
kroy changed Version from - to 1.4-rolling.

Network re-creates every time after reboot and gets configuration from "container network" section.
https://github.com/vyos/vyatta-cfg/blob/242f5685159f615ff79312041d3dde2063e5579a/scripts/init/vyos-router#L273-L277
So there is podman decide how to name this network.

In a different case, it tried to create a network which already been created.

Network re-creates every time after reboot and gets configuration from "container network" section.
https://github.com/vyos/vyatta-cfg/blob/242f5685159f615ff79312041d3dde2063e5579a/scripts/init/vyos-router#L273-L277
So there is podman decide how to name this network.

In a different case, it tried to create a network which already been created.

Right. And I can fix that in a similiar fashion to how the ipMasq is being changed. It's not actually "created" until the first container gets hit with it. So we can name it however we want.

To wit, I already had this working with multiple networks (I had named them podman0/1/2/3/4/etc), but I wanted to simplify the initial PR here.

For example,

# disable masquerading and use traditional bridging so VyOS can control firewalling/NAT/etc on the cni-podmanX interface
  interface_ctr = 0;
  for network, network_config in container['network'].items():
      # podman doesn't expose these options
      # this is the easiest way to change properties in the network config
      with open('/etc/cni/net.d/%s.conflist' % network, 'r') as sources:
          lines = sources.readlines()
      with open('/etc/cni/net.d/%s.conflist' % network, 'w') as sources:
          for line in lines:
              if 'enable_bridging' in network_config:
                  line = re.sub(r'"ipMasq": true', '"ipMasq": false', line)

              line = re.sub(r'"bridge": "cni-podman[0-9]*"', f'"bridge": "container{interface_ctr}"', line)
              sources.write(line)
          interface_ctr += 1

That accomplishes the goal of changing the podman interface name to containerX, but it's also not very repeatable (safe).

How can I re-trigger the build of the container when I have changed the file?

Right now it seems I need to delete and re-add the container? Maybe the "restart" option from T3765 would be an option?

Definitely seems to me a op-mode command to trigger a container rebuild would be appropriate.