bridget/bridget.sh

241 lines
7.2 KiB
Bash
Raw Normal View History

2017-12-20 18:56:40 +03:00
#!/bin/sh
2017-12-22 14:25:48 +03:00
CNI_CONFIG="${CNI_CONFIG:-/etc/cni/net.d/10-bridget.conf}"
2017-12-21 14:34:10 +03:00
2017-12-20 18:56:40 +03:00
usage() {
2020-10-15 23:16:05 +03:00
cat <<EOF
2017-12-20 18:56:40 +03:00
Available variables:
2017-12-20 19:41:35 +03:00
- BRIDGE (example: cbr0)
2017-12-20 18:56:40 +03:00
- VLAN (example: 100)
- IFACE (example: eth0)
2017-12-20 19:41:35 +03:00
- MTU (default: 1500)
2018-10-18 11:47:37 +03:00
- CHECK_SLAVES (default: 1)
2017-12-21 03:45:27 +03:00
- POD_NETWORK (default: 10.244.0.0/16)
2018-10-18 11:47:37 +03:00
- DEBUG (default: 0)
2017-12-20 18:56:40 +03:00
Short workflow:
* If the bridge exists it will be used, otherwise it will be created
2017-12-20 18:56:40 +03:00
* If VLAN and IFACE are set, the following chain will be created:
2017-12-20 18:56:40 +03:00
IFACE <-- VLAN <-- BRIDGE
* IP-address will be set automatically. This IP-address
will be used as default gateway for containers
to make kubernetes services work.
2017-12-20 18:56:40 +03:00
EOF
}
error() {
2017-12-22 01:06:22 +03:00
>&2 echo -en "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:\t"
2017-12-22 00:56:24 +03:00
>&2 echo "$1"
2017-12-20 18:56:40 +03:00
>&2 usage
exit 1
}
2017-12-22 00:25:17 +03:00
log() {
2017-12-22 01:06:22 +03:00
echo -en "[$(date '+%Y-%m-%d %H:%M:%S')] INFO:\t"
2017-12-22 00:56:24 +03:00
echo "$1"
2017-12-22 00:25:17 +03:00
}
debug() {
2018-10-18 11:47:37 +03:00
if [ "${DEBUG:-0}" = 1 ]; then
2018-01-26 23:58:50 +03:00
>&2 echo -en "[$(date '+%Y-%m-%d %H:%M:%S')] DEBUG:\t"
>&2 echo "$1"
2017-12-22 00:56:24 +03:00
fi
2017-12-22 00:25:17 +03:00
}
2017-12-21 03:45:27 +03:00
next_ip() {
2020-10-15 23:16:05 +03:00
local IP_HEX=$(printf '%.2X%.2X%.2X%.2X\n' $(echo $1 | sed -e 's/\./ /g'))
local NEXT_IP_HEX=$(printf %.8X $(echo $((0x$IP_HEX + 1))))
local NEXT_IP=$(printf '%d.%d.%d.%d\n' $(echo $NEXT_IP_HEX | sed -r 's/(..)/0x\1 /g'))
2017-12-21 03:45:27 +03:00
echo $NEXT_IP
}
prev_ip() {
2020-10-15 23:16:05 +03:00
local IP_HEX=$(printf '%.2X%.2X%.2X%.2X\n' $(echo $1 | sed -e 's/\./ /g'))
local PREV_IP_HEX=$(printf %.8X $(echo $((0x$IP_HEX - 1))))
local PREV_IP=$(printf '%d.%d.%d.%d\n' $(echo $PREV_IP_HEX | sed -r 's/(..)/0x\1 /g'))
2017-12-21 03:45:27 +03:00
echo $PREV_IP
}
getnodecidr() {
CA_CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
2018-08-05 02:13:35 +03:00
curl -sS -m 5 --cacert $CA_CERT -H "Authorization: Bearer $TOKEN" "https://${KUBERNETES_PORT#*//}/api/v1/nodes/$1" | jq -r .spec.podCIDR
2017-12-21 03:45:27 +03:00
}
2017-12-20 18:56:40 +03:00
# ------------------------------------------------------------------------------------
# Configure bridge
# ------------------------------------------------------------------------------------
2017-12-22 00:25:17 +03:00
log "Starting bridge configuration"
2017-12-20 18:56:40 +03:00
[ -z "$BRIDGE" ] && error "BRIDGE variable is not defined"
[ -z "$NODE_NAME" ] && error "NODE_NAME variable is not defined"
2017-12-20 18:56:40 +03:00
# Check if bridge interface exist
2020-10-15 23:16:05 +03:00
if ! ip link show "$BRIDGE" 1>/dev/null 2>/dev/null; then
2017-12-22 00:25:17 +03:00
log "Adding new bridge $BRIDGE"
2017-12-20 18:56:40 +03:00
ip link add dev "$BRIDGE" type bridge
2017-12-22 14:38:09 +03:00
export CHECK_SLAVES=1
2017-12-22 00:25:17 +03:00
else
log "Bridge $BRIDGE already exist, use it"
2017-12-20 18:56:40 +03:00
fi
2017-12-22 00:25:17 +03:00
log "Setting bridge $BRIDGE up"
2017-12-20 18:56:40 +03:00
ip link set "$BRIDGE" up
# ------------------------------------------------------------------------------------
# Configure vlan
# ------------------------------------------------------------------------------------
2017-12-22 00:25:17 +03:00
2018-10-18 11:47:37 +03:00
if ([ ! -z "$VLAN" ] || [ ! -z "$IFACE" ]) && [ "${CHECK_SLAVES:-1}" = 1 ]; then
2017-12-22 00:25:17 +03:00
log "Starting VLAN configuration"
2017-12-20 18:56:40 +03:00
[ -z "$IFACE" ] && error "IFACE variable is not defined"
2017-12-22 04:34:52 +03:00
if [ ! -z "$VLAN" ]; then
# check if vlan interface exist
2020-10-15 23:16:05 +03:00
if ip link show "$IFACE.$VLAN" 1>/dev/null 2>/dev/null; then
2017-12-22 04:34:52 +03:00
log "VLAN interface $IFACE.$VLAN already exist"
else
log "Adding new VLAN interface $IFACE.$VLAN"
2018-10-18 11:47:37 +03:00
ip link add link "$IFACE" name "$IFACE.$VLAN" mtu "${MTU}" type vlan id "$VLAN"
2017-12-22 04:34:52 +03:00
fi
log "Setting vlan $IFACE.$VLAN up"
ip link set dev "$IFACE.$VLAN" up
fi
fi
2017-12-22 00:25:17 +03:00
2017-12-22 04:34:52 +03:00
# ------------------------------------------------------------------------------------
# Configure slaves
# ------------------------------------------------------------------------------------
2017-12-22 00:25:17 +03:00
2018-10-18 11:47:37 +03:00
if ([ ! -z "$VLAN" ] || [ ! -z "$IFACE" ]) && [ "${CHECK_SLAVES:-1}" = 1 ]; then
2017-12-22 00:25:17 +03:00
2017-12-22 04:34:52 +03:00
log "Starting configuring slave interfaces"
2017-12-22 00:25:17 +03:00
2017-12-22 04:34:52 +03:00
if [ ! -z "$VLAN" ]; then
SLAVEIF="$IFACE.$VLAN"
2017-12-22 15:51:32 +03:00
else
2017-12-22 04:34:52 +03:00
SLAVEIF="$IFACE"
2017-12-20 18:56:40 +03:00
fi
2017-12-22 00:25:17 +03:00
2020-10-15 23:16:05 +03:00
if ! ip link show "$SLAVEIF" 1>/dev/null 2>/dev/null; then
2017-12-22 15:28:12 +03:00
error "$SLAVEIF does not exist"
fi
2017-12-22 04:34:52 +03:00
# check if slave interface contains right master
2020-10-15 23:16:05 +03:00
MASTERIF="$(ip -o link show "$SLAVEIF" | grep -o -m1 'master [^ ]\+' | cut -d' ' -f2)"
2017-12-22 04:34:52 +03:00
case "$MASTERIF" in
2020-10-15 23:16:05 +03:00
"$BRIDGE") log "$SLAVEIF already member of $BRIDGE" ;;
"" ) log "Adding $SLAVEIF as member to $BRIDGE"
ip link set "$SLAVEIF" master "$BRIDGE" ;;
* ) error "interface $SLAVEIF have another master" ;;
2017-12-22 04:34:52 +03:00
esac
2017-12-20 18:56:40 +03:00
fi
2017-12-21 03:45:27 +03:00
# ------------------------------------------------------------------------------------
# Retrive network parameters
# ------------------------------------------------------------------------------------
2017-12-22 00:25:17 +03:00
log "Starting retriving parameters"
2017-12-21 03:45:27 +03:00
POD_NETWORK="${POD_NETWORK:-10.244.0.0/16}"
NODE_NETWORK="$(getnodecidr "${NODE_NAME}")"
2018-08-05 02:03:01 +03:00
if [ -z "$NODE_NETWORK" ] || [ "$NODE_NETWORK" = "null" ]; then
2020-10-15 23:16:05 +03:00
error "Failed to get node cidr"
fi
2017-12-22 00:25:17 +03:00
2017-12-22 00:43:49 +03:00
set -e
2020-10-15 23:16:05 +03:00
export "POD_$(ipcalc -b "$POD_NETWORK")" # POD_BROADCAST
export "POD_$(ipcalc -p "$POD_NETWORK")" # POD_PREFIX
export "POD_$(ipcalc -n "$POD_NETWORK")" # POD_NETWORK
export "NODE_$(ipcalc -p "$NODE_NETWORK")" # NODE_PREFIX
export "NODE_$(ipcalc -b "$NODE_NETWORK")" # NODE_BROADCAST
export "NODE_$(ipcalc -n "$NODE_NETWORK")" # NODE_NETWORK
export "NODE_IP=$(next_ip "$NODE_NETWORK")" # NODE_IP
2017-12-21 03:45:27 +03:00
2017-12-22 00:43:49 +03:00
set +e
2020-10-15 23:16:05 +03:00
debug "POD_BROADCAST=$POD_BROADCAST"
2017-12-22 00:25:17 +03:00
debug "POD_PREFIX=$POD_PREFIX"
debug "POD_NETWORK=$POD_NETWORK"
debug "NODE_PREFIX=$NODE_PREFIX"
debug "NODE_BROADCAST=$NODE_BROADCAST"
debug "NODE_NETWORK=$NODE_NETWORK"
debug "NODE_IP=$NODE_IP"
2017-12-21 03:45:27 +03:00
# ------------------------------------------------------------------------------------
# Configure IP-address
# ------------------------------------------------------------------------------------
log "Configuring $NODE_IP/$POD_PREFIX on $BRIDGE"
ip -o addr show "$BRIDGE" | grep -o 'inet [^ ]\+' | while read _ IP; do
# Remove bridge addresses from the same subnet, don't touch other addresses
2020-10-16 10:51:11 +03:00
if [ "$(ipcalc -b "$IP")" = "BROADCAST=${POD_BROADCAST}" ] && [ "$IP" != "$NODE_IP/$POD_PREFIX" ]; then
ip addr del "$IP" dev "$BRIDGE"
fi
done
ip addr change "$NODE_IP/$POD_PREFIX" dev "$BRIDGE"
2017-12-21 03:45:27 +03:00
2017-12-20 18:56:40 +03:00
# ------------------------------------------------------------------------------------
# Configure cni
# ------------------------------------------------------------------------------------
2017-12-21 03:45:27 +03:00
2017-12-22 00:25:17 +03:00
log "Starting generating CNI configuration"
2017-12-22 00:43:49 +03:00
set -e
GATEWAY="${NODE_IP}"
2017-12-21 03:45:27 +03:00
SUBNET="${POD_NETWORK}/${POD_PREFIX}"
FIRST_IP="$(next_ip "${NODE_IP}")"
LAST_IP="$(prev_ip "${NODE_BROADCAST}")"
2017-12-21 03:45:27 +03:00
2017-12-22 00:43:49 +03:00
set +e
2017-12-22 00:25:17 +03:00
debug "GATEWAY=$GATEWAY"
debug "SUBNET=$SUBNET"
debug "FIRST_IP=$FIRST_IP"
debug "LAST_IP=$LAST_IP"
log "Writing $CNI_CONFIG"
2020-10-15 23:16:05 +03:00
cat >$CNI_CONFIG <<EOT
2017-12-20 18:56:40 +03:00
{
2017-12-22 14:25:48 +03:00
"name": "bridget",
"cniVersion": "0.2.0",
2017-12-20 18:56:40 +03:00
"type": "bridge",
"bridge": "${BRIDGE}",
2017-12-21 20:45:21 +03:00
"ipMasq": true,
2017-12-20 19:39:05 +03:00
"mtu": ${MTU:-1500},
2017-12-20 18:56:40 +03:00
"ipam": {
2017-12-21 03:45:27 +03:00
"type": "host-local",
"subnet": "${SUBNET}",
"rangeStart": "${FIRST_IP}",
"rangeEnd": "${LAST_IP}",
2017-12-21 14:34:10 +03:00
"gateway": "${GATEWAY}",
2017-12-21 03:45:27 +03:00
"routes": [
{ "dst": "0.0.0.0/0" }
]
2017-12-20 18:56:40 +03:00
}
}
EOT
2018-01-27 01:49:49 +03:00
# Display config
cat "$CNI_CONFIG"
2017-12-20 18:56:40 +03:00
# ------------------------------------------------------------------------------------
2017-12-21 15:26:07 +03:00
# Sleep gently
2017-12-20 18:56:40 +03:00
# ------------------------------------------------------------------------------------
2018-01-26 23:58:50 +03:00
exec tail -f /dev/null