Public ip for a LXD container

Hello,

I want to set a specify a public to a container to avoid NAT. My network look like so,

network

The ISP has provided a fiber modem which is in bridge mode. I have connected it to a switch which has a VLAN 100 defined. The switch tags the traffic and connects to the server which has the LXD container.

The LXD host netwok looks like this,

$ ip link show vlan100
60: vlan100@eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 12:34:56:78:12:23 brd ff:ff:ff:ff:ff:ff

tcpdump on vlan100 interface shows the arp requests coming from WAN side, so i know it is working.

The ISP has provided me a public ip address (e.g. 202.16.1.2) which i want to assign to a container. It is not clear to what kind of network should i use.

I tried the routed approach for debian like this, but the container is not able to ping the internet.

#lxc profile show routed_debian
config:
  user.network-config: |
    #cloud-config
    version: 2
    ethernets:
        eth0:
          dhcp4: false
          dhcp6: false
          routes:
          - to: 0.0.0.0/0
            via: 169.254.0.1
            on-link: true
  user.user-data: |
    #cloud-config
    bootcmd:
      - echo 'nameserver 8.8.8.8' > /etc/resolvconf/resolv.conf.d/tail
      - systemctl restart resolvconf
description: Default LXD profile
devices:
  eth0:
    ipv4.address: 202.16.1.2
    name: eth0
    nictype: routed
    parent: vlan100
    type: nic
name: routed_debian
used_by:
- /1.0/instances/turnpublic

Any help would be much appreciated.

I followed this post and created a container like so,

$ lxc config show cipvlan
architecture: x86_64
config:
  image.architecture: amd64
  image.description: ubuntu 18.04 LTS amd64 (release) (20211129)
  image.label: release
  image.os: ubuntu
  image.release: bionic
  image.serial: "20211129"
  image.type: squashfs
  image.version: "18.04"
  volatile.base_image: 62b292b5a57e02d19d90ae99af4684323d029882bd98291c6ce77f5cc9b0a79f
  volatile.eth0.host_name: lxd51d65d58
  volatile.eth0.last_state.created: "false"
  volatile.eth0.name: eth0
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
  volatile.last_state.power: RUNNING
  volatile.uuid: d62a4359-ceac-4f46-ab55-2e403a64285a
devices:
  eth0:
    ipv4.address: 202.16.1.2
    nictype: ipvlan
    parent: vlan100
    type: nic
ephemeral: false
profiles:
- default
stateful: false
description: ""

In the contained the netplan config looks like so,

# cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    version: 2
    ethernets:
      eth0:
        addresses:
          - 202.16.1.2/32
        nameservers:
          addresses:
          - 8.8.8.8
        routes:
          - to: 0.0.0.0/0
            via: 169.254.0.1
            on-link: true

Unfortunately, i am still not able to ping to the internet.

root@cipvlan:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.0.1     0.0.0.0         UG    0      0        0 eth0
root@cipvlan:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2104ms

There is no firewall on the host, since i want the traffic to directly go from container to the CPE modem without NAT.

# iptables -L -v -n -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination   

I was able to get this working by using a macvlan.

The LXD config looks like,

devices:
  eth0:
    nictype: macvlan
    parent: vlan100
    type: nic

The debian 10 container has the network defined,

$ cat /etc/network/interfaces

# The loopback network interface
auto lo
iface lo inet loopback

auto eth0
#iface eth0 inet dhcp
iface eth0  inet static
 address 202.16.1.2
 netmask 255.255.255.0
 gateway 202.16.1.1
 dns-domain 8.8.8.8

source /etc/network/interfaces.d/*