--- /dev/null
+---
+schema: pegleg/Script/v1
+metadata:
+ schema: metadata/Document/v1
+ name: configure-ip-rules
+ storagePolicy: cleartext
+ layeringDefinition:
+ abstract: false
+ layer: global
+data: |-
+ #!/bin/bash
+ set -ex
+
+ function usage() {
+ cat <<EOU
+ Options are:
+
+ -c POD_CIDR The pod CIDR for the Kubernetes cluster, e.g. 10.97.0.0/16
+ -i INTERFACE (optional) The interface for internal pod traffic, e.g.
+ bond0.22. Used to auto-detect the service gateway.
+ Exclusive with -g.
+ -g SERVICE_GW (optional) The service gateway/VRR IP for routing pod
+ traffic. Exclusive with -i.
+ -o OVERLAP_CIDR (optional) This CIDR will be routed via the VRRP IP on
+ INTERFACE. It is used to provide a work around when
+ complete Calico routes cannot be received via BGP.
+ e.g. 10.96.0.0/15. NOTE: This must include the POD_CIDR.
+ -s SERVICE_CIDR (optional) A routable CIDR to configure for ingress, maas,
+ e.g. 10.23.22.192/29
+ EOU
+ }
+
+ SERVICE_CIDR=
+ OVERLAP_CIDR=
+
+ while getopts ":c:g:hi:o:s:" o; do
+ case "${o}" in
+ c)
+ POD_CIDR=${OPTARG}
+ ;;
+ g)
+ SERVICE_GW=${OPTARG}
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ i)
+ INTERFACE=${OPTARG}
+ ;;
+ o)
+ OVERLAP_CIDR=${OPTARG}
+ ;;
+ s)
+ SERVICE_CIDR=${OPTARG}
+ ;;
+ \?)
+ echo "Unknown option: -${OPTARG}" >&2
+ exit 1
+ ;;
+ :)
+ echo "Missing argument for option: -${OPTARG}" >&2
+ exit 1
+ ;;
+ *)
+ echo "Unimplemented option: -${OPTARG}" >&2
+ exit 1
+ ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ if [ "x$POD_CIDR" == "x" ]; then
+ echo "Missing pod CIDR, e.g -c 10.97.0.0/16" >&2
+ usage
+ exit 1
+ fi
+
+ if [ "x$INTERFACE" != "x" ]; then
+ while ! ip route list dev "${INTERFACE}" > /dev/null; do
+ echo Waiting for device "${INTERFACE}" to be ready. >&2
+ sleep 5
+ done
+ fi
+
+ intra_vrrp_ip=
+ if [ "x${SERVICE_GW}" == "x" ]; then
+ intra_vrrp_ip=$(ip route list dev "${INTERFACE}" | awk '($2~/via/){print $3}' | head -n 1)
+ else
+ intra_vrrp_ip=${SERVICE_GW}
+ fi
+
+ TABLE="1500"
+
+ if [ "x${intra_vrrp_ip}" == "x" ]; then
+ echo "Either INTERFACE or SERVICE_GW is required: e.g. either -i bond0.22 or -g 10.23.22.1"
+ usage
+ exit 1
+ fi
+
+ # Setup a routing table for traffic from service IPs
+ ip route flush table "${TABLE}"
+ ip route add default via "${intra_vrrp_ip}" table "${TABLE}"
+
+ # Setup arp_announce adjustment on interface facing gateway
+ arp_intf=$(ip route get ${intra_vrrp_ip} | grep dev | awk '{print $3}')
+ echo 2 > /proc/sys/net/ipv4/conf/${arp_intf}/arp_announce
+
+
+ if [ "x$OVERLAP_CIDR" != "x" ]; then
+ # NOTE: This is a work-around for nodes not receiving complete
+ # routes via BGP.
+ ip route add "${OVERLAP_CIDR}" via "${intra_vrrp_ip}"
+ fi
+
+ if [ "x$SERVICE_CIDR" != "x" ]; then
+ # Traffic from the service IPs to pods should use the pod network.
+ ip rule add \
+ from "${SERVICE_CIDR}" \
+ to "${POD_CIDR}" \
+ lookup main \
+ pref 10000
+ # Other traffic from service IPs should only use the VRRP IP
+ ip rule add \
+ from "${SERVICE_CIDR}" \
+ lookup "${TABLE}" \
+ pref 10100
+ fi