Create macvlan to allow healthchecks in DHCP mode

Create macvlan to allow healthchecks in DHCP mode
This commit is contained in:
Kroese 2023-04-21 20:41:37 +02:00 committed by GitHub
commit a2e9827f8a
4 changed files with 44 additions and 28 deletions

View File

@ -48,7 +48,6 @@ EXPOSE 139
EXPOSE 443
EXPOSE 445
EXPOSE 5000
EXPOSE 5001
ENV URL ""
ENV ALLOCATE "Y"

View File

@ -13,7 +13,6 @@ services:
- NET_ADMIN
ports:
- 5000:5000
- 5001:5001
volumes:
- /var/dsm:/storage
restart: on-failure

View File

@ -46,7 +46,6 @@ services:
- NET_ADMIN
ports:
- 5000:5000
- 5001:5001
restart: on-failure
stop_grace_period: 1m
```
@ -165,8 +164,6 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
- 'c 510:* rwm'
```
This will make DSM retrieve an IP from your router. This will not be the same as the macvlan IP of the container, so to determine which one was assigned to DSM please check the container logfile or use the devices page of your router for example.
NOTE: The exact cgroup rule may be different than `510` depending on your system, but the correct rule number will be printed to the logfile in case of error.
* ### How do I install a specific version of vDSM? ###

View File

@ -4,6 +4,7 @@ set -eu
# Docker environment variabeles
: ${VM_NET_TAP:='dsm'}
: ${VM_NET_DEV:='eth0'}
: ${VM_NET_HOST:='VirtualDSM'}
: ${VM_NET_MAC:='02:11:32:AA:BB:CC'}
@ -19,23 +20,28 @@ set -eu
configureDHCP() {
# Create /dev/vhost-net
if [ ! -c /dev/vhost-net ]; then
mknod /dev/vhost-net c 10 238
chmod 660 /dev/vhost-net
fi
VM_NET_VLAN="vlan"
GATEWAY=$(ip r | grep default | awk '{print $3}')
NETWORK=$(ip -o route | grep "${VM_NET_DEV}" | grep -v default | awk '{print $1}')
IP=$(ip address show dev "${VM_NET_DEV}" | grep inet | awk '/inet / { print $2 }' | cut -f1 -d/)
if [ ! -c /dev/vhost-net ]; then
echo -n "Error: VHOST interface not available. Please add the following "
echo "docker variable to your container: --device=/dev/vhost-net" && exit 85
fi
ip l add link "${VM_NET_DEV}" "${VM_NET_VLAN}" type macvlan mode bridge
ip address add "${IP}" dev "${VM_NET_VLAN}"
ip link set dev "${VM_NET_VLAN}" up
ip route flush dev "${VM_NET_DEV}"
ip route flush dev "${VM_NET_VLAN}"
ip route add "${NETWORK}" dev "${VM_NET_VLAN}" metric 0
ip route add default via "${GATEWAY}"
echo "Info: Retrieving IP via DHCP using MAC ${VM_NET_MAC}..."
ip l add link eth0 name "${VM_NET_TAP}" address "${VM_NET_MAC}" type macvtap mode bridge || true
ip l add link "${VM_NET_DEV}" name "${VM_NET_TAP}" address "${VM_NET_MAC}" type macvtap mode bridge || true
ip l set "${VM_NET_TAP}" up
ip a flush eth0
ip a flush "${VM_NET_DEV}"
ip a flush "${VM_NET_TAP}"
DHCP_IP=$( dhclient -v "${VM_NET_TAP}" 2>&1 | grep ^bound | cut -d' ' -f3 )
@ -46,11 +52,19 @@ configureDHCP() {
echo "ERROR: Cannot retrieve IP from DHCP using MAC ${VM_NET_MAC}" && exit 16
fi
# Store IP for Docker healthcheck
echo "${DHCP_IP}" > "/var/dsm.ip"
ip a flush "${VM_NET_TAP}"
# Create /dev/vhost-net
if [ ! -c /dev/vhost-net ]; then
mknod /dev/vhost-net c 10 238
chmod 660 /dev/vhost-net
fi
if [ ! -c /dev/vhost-net ]; then
echo -n "Error: VHOST interface not available. Please add the following "
echo "docker variable to your container: --device=/dev/vhost-net" && exit 85
fi
TAP_NR=$(</sys/class/net/"${VM_NET_TAP}"/ifindex)
TAP_PATH="/dev/tap${TAP_NR}"
@ -79,6 +93,9 @@ configureDHCP() {
echo "variable to your container: --device=/dev/vhost-net" && exit 22
fi
# Store IP for Docker healthcheck
echo "${DHCP_IP}" > "/var/dsm.ip"
NET_OPTS="-netdev tap,id=hostnet0,vhost=on,vhostfd=40,fd=30"
}
@ -86,22 +103,20 @@ configureNAT () {
VM_NET_IP='20.20.20.21'
# Store IP for Docker healthcheck
echo "${VM_NET_IP}" > "/var/dsm.ip"
#Create bridge with static IP for the VM guest
brctl addbr dockerbridge
ip addr add ${VM_NET_IP%.*}.1/24 broadcast ${VM_NET_IP%.*}.255 dev dockerbridge
ip link set dockerbridge up
#QEMU Works with taps, set tap to the bridge created
ip tuntap add dev "${VM_NET_TAP}" mode tap
ip link set "${VM_NET_TAP}" up promisc on
brctl addif dockerbridge "${VM_NET_TAP}"
#Add internet connection to the VM
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p tcp -j DNAT --to $VM_NET_IP
iptables -t nat -A PREROUTING -i eth0 -p udp -j DNAT --to $VM_NET_IP
iptables -t nat -A POSTROUTING -o "${VM_NET_DEV}" -j MASQUERADE
iptables -t nat -A PREROUTING -i "${VM_NET_DEV}" -p tcp -j DNAT --to $VM_NET_IP
iptables -t nat -A PREROUTING -i "${VM_NET_DEV}" -p udp -j DNAT --to $VM_NET_IP
# Hack for guest VMs complaining about "bad udp checksums in 5 packets"
iptables -A POSTROUTING -t mangle -p udp --dport bootpc -j CHECKSUM --checksum-fill || true
@ -116,6 +131,9 @@ configureNAT () {
echo "0 $VM_NET_MAC $VM_NET_IP $VM_NET_HOST 01:${VM_NET_MAC}" > /var/lib/misc/dnsmasq.leases
chmod 644 /var/lib/misc/dnsmasq.leases
# Store IP for Docker healthcheck
echo "${VM_NET_IP}" > "/var/dsm.ip"
NET_OPTS="-netdev tap,ifname=${VM_NET_TAP},script=no,downscript=no,id=hostnet0"
# Build DNS options from container /etc/resolv.conf
@ -141,7 +159,7 @@ configureNAT () {
[ "$DEBUG" = "Y" ] && echo && echo "$DNSMASQ $DNSMASQ_OPTS"
$DNSMASQ ${DNSMASQ_OPTS:+ $DNSMASQ_OPTS}
$DNSMASQ ${DNSMASQ_OPTS:+ $DNSMASQ_OPTS}
}
# ######################################
@ -164,7 +182,7 @@ GATEWAY=$(ip r | grep default | awk '{print $3}')
if [ "$DEBUG" = "Y" ]; then
IP=$(ip address show dev eth0 | grep inet | awk '/inet / { print $2 }' | cut -f1 -d/)
IP=$(ip address show dev "${VM_NET_DEV}" | grep inet | awk '/inet / { print $2 }' | cut -f1 -d/)
echo "Info: Container IP is ${IP} with gateway ${GATEWAY}"
ifconfig
ip route
@ -187,7 +205,10 @@ else
configureDHCP
# Display the received IP on port 5000
/run/server.sh 5000 "The location of DSM is http://${DHCP_IP}:5000" > /dev/null &
HTML="The location of DSM is http://${DHCP_IP}:5000<script>\
setTimeout(function(){ window.location.replace('http://${DHCP_IP}:5000'); }, 2000);</script>"
/run/server.sh 5000 "${HTML}" > /dev/null &
fi