Fullmoon System

Linux-Bonding konfigurieren: Unterschiede der Modi und Active-Backup-Einrichtung unter CentOS 7.9

EdwardMoon

Linux-Bonding ist eine Funktion, mit der zwei oder mehr physische Netzwerkschnittstellen zu einer einzigen logischen Schnittstelle gebündelt werden. Dadurch können im Fehlerfall Kommunikationspfade umgeschaltet oder die Last mehrerer Verbindungen verteilt werden. Die tatsächliche Wirkung hängt jedoch vom gewählten Modus und der Switch-Konfiguration ab. Dieser Artikel beschreibt die Unterschiede zwischen den einzelnen Modi und erklärt anschließend, wie Sie ein Active-Backup-Bonding in einer network-scripts-Umgebung unter CentOS 7.9 konfigurieren und wiederherstellen.

Geltungsbereich: Dies ist ein Wartungsbeispiel für eine Umgebung mit statischen IPv4-Adressen, die vom klassischen network.service verwaltet wird. Da der Support für CentOS Linux 7 am 30. Juni 2024 endete, sollte dies nicht als Standard für neue Server herangezogen werden. Offizielle Ankündigung zum Support-Ende von CentOS

Was Bonding leisten kann – und was nicht

Im Modus active-backup wird nur eine Netzwerkkarte (NIC) für die Kommunikation verwendet, während die andere im Fehlerfall einspringt. Selbst wenn Sie zwei 1-Gbit/s-NICs bündeln, bleibt die Bandbreite im Normalbetrieb auf die Geschwindigkeit einer einzelnen aktiven Schnittstelle beschränkt. Lastverteilungsmodi wie LACP hingegen können mehrere Datenströme auf verschiedene NICs aufteilen. Die Geschwindigkeit einer einzelnen Verbindung erhöht sich jedoch nicht automatisch um das Vielfache der Anzahl der Netzwerkkarten.

Das Bonding nutzt den Linux-Bonding-Treiber. Da netzwerkbasiertes Teaming über teamd eine separate Implementierung für denselben Zweck darstellt, sollten Sie beide Konfigurationsmethoden nicht miteinander vermischen. Selbst wenn die Verbindung redundant ausgelegt ist, kann die Kommunikation unterbrochen werden, wenn der gesamte Switch, ein übergeordneter Router oder dieselbe Stromversorgung gleichzeitig ausfallen.

Bonding-Modi und Switch-Konfiguration

Der Vergleich basiert auf einer typischen Serverumgebung, die an einen Switch angeschlossen ist. Direktverbindungen oder spezielle Topologien erfordern eine separate Prüfung.

Modus Verhalten Switch-Anforderungen Besonderheiten bei der Auswahl
0: balance-rr Verteilt ausgehende Pakete nacheinander auf die NICs Erfordert in der Regel statische Link-Aggregation Paketreihenfolge kann sich ändern
1: active-backup Eine aktive NIC, Failover im Fehlerfall Kein LACP oder statische Aggregation erforderlich Keine Bandbreitenbündelung
2: balance-xor Wählt den Ausgangspfad basierend auf einer Hash-Richtlinie Erfordert in der Regel statische Link-Aggregation Keine LACP-Aushandlung
3: broadcast Überträgt dieselben Pakete über alle NICs Erfordert in der Regel Link-Aggregation Reine Traffic-Duplizierung, keine Durchsatzsteigerung
4: 802.3ad / LACP Verteilt Datenströme innerhalb einer Aggregationsgruppe Erfordert LACP-Konfiguration auf den Switch-Ports Geschwindigkeit, Duplex-Modus und Hash-Richtlinie der Aggregationsgruppe prüfen
5: balance-tlb Ausgehende Lastverteilung, Empfang über eine einzige NIC Keine spezielle Aggregationskonfiguration erforderlich Treiberunterstützung prüfen
6: balance-alb Erweitert TLB um eingehende IPv4-Lastverteilung Keine spezielle Aggregationskonfiguration erforderlich Abhängig von ARP-Aushandlung und Unterstützung für MAC-Adressänderungen

Im Gegensatz zu Modus 5 kann Modus 6 auch den eingehenden IPv4-Verkehr verteilen. Es muss zwischen der statischen Aggregation der Modi 0, 2 und 3 und dem LACP-Modus 4 unterschieden werden. Detaillierte Anforderungen finden Sie im Abschnitt „Modi und Switch-Konfiguration“ der Linux-Kernel-Bonding-Dokumentation.

Arbeitsumgebung und Vorabprüfung

In diesem Beispiel werden eth0 und eth1 zu bond0 zusammengefasst. Die Server-IP wird auf 192.168.1.100/24 und das Gateway auf 192.168.1.1 festgelegt. Ersetzen Sie diese Werte durch Ihre tatsächlichen Schnittstellennamen und IP-Adressen und stellen Sie sicher, dass keine IP-Konflikte vorliegen und das Gateway im selben Subnetz liegt. Die Switch-Ports müssen demselben VLAN und Netzwerk zugeordnet sein. Gruppieren Sie die Ports für Active-Backup nicht in einer LACP-Gruppe.

Die Anwendung der Netzwerkkonfiguration unterbricht die Kommunikation der betroffenen NICs. Führen Sie diese Arbeiten nicht ausschließlich über eine SSH-Verbindung durch. Stellen Sie stattdessen einen unabhängigen Out-of-Band-Management-Zugang (wie IPMI, iDRAC oder eine Virtualisierungskonsole) sicher und planen Sie ein Wartungsfenster ein. Wenn Sie VLANs, Bridges, virtuelle IPs, mehrere Standardrouten, richtlinienbasiertes Routing (Policy Routing) oder IPv6 verwenden, müssen Sie diese Einstellungen separat auf das Bond-Interface übertragen. Das unten stehende Skript zur automatischen Generierung ist kein Tool, das all diese komplexen Konfigurationen automatisch konvertiert.

cat /etc/centos-release
uname -r
ip -br link
ip -br address
ip route show table all
ip rule show
systemctl is-active network
systemctl is-active NetworkManager
modinfo bonding
ethtool eth0
ethtool eth1

Stellen Sie sicher, dass network die Schnittstellen verwaltet und der NetworkManager deaktiviert ist. Falls Ihr Server vom NetworkManager verwaltet wird, stoppen Sie diesen Dienst nicht für dieses Beispiel, sondern nutzen Sie stattdessen das nmcli-Bonding-Verfahren für diese Umgebung. Vermeiden Sie, dass beide Tools dieselbe NIC gleichzeitig verwalten.

Der Befehl modinfo bonding ruft Informationen über das Kernel-Modul ab. Da der Bonding-Treiber in den Standard-Kerneln der Distributionen enthalten ist, müssen Sie kein separates kmod-bonding-Paket installieren, nur weil das Modul nicht in der Ausgabe von lsmod aufgeführt wird. Falls bereits modinfo fehlschlägt, prüfen Sie zunächst, ob der aktuell laufende Kernel mit den installierten Modulpaketen übereinstimmt.

Aufbau der fertigen ifcfg-Dateien

Die IP-Adresse, das Gateway und die Bonding-Optionen werden in der Datei /etc/sysconfig/network-scripts/ifcfg-bond0 definiert. Die Option miimon=100 überwacht den Link-Status im Abstand von 100 Millisekunden, garantiert jedoch nicht die Erreichbarkeit des gesamten übergeordneten Netzwerkpfads.

DEVICE=bond0
NAME=bond0
TYPE=Bond
BONDING_MASTER=yes
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
IPADDR=192.168.1.100
PREFIX=24
GATEWAY=192.168.1.1
DEFROUTE=yes
PEERDNS=no
IPV6INIT=no
BONDING_OPTS="mode=active-backup miimon=100"

Die Option PEERDNS=no verhindert, dass die DNS-Einstellungen durch dieses Profil überschrieben werden. Prüfen Sie nach der Aktivierung, ob die Namensauflösung weiterhin wie gewohnt funktioniert. Der Eintrag IPV6INIT=no in diesem Beispiel verdeutlicht, dass es sich um eine reine IPv4-Umgebung handelt; übernehmen Sie dies nicht ungeprüft für Server, die IPv6 nutzen.

Weisen Sie den physischen NICs keine IP-Adressen oder Standard-Gateways zu, sondern konfigurieren Sie diese stattdessen über die Parameter MASTER und SLAVE. Es folgen die Inhalte der beiden separaten Dateien:

# /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
TYPE=Ethernet
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
MASTER=bond0
SLAVE=yes
IPV6INIT=no

# /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
NAME=eth1
TYPE=Ethernet
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
MASTER=bond0
SLAVE=yes
IPV6INIT=no

Stellen Sie sicher, dass keine doppelten ifcfg-Dateien oder separaten Profile für dieselbe NIC verbleiben, die automatisch gestartet werden könnten. Die spezifischen Bonding-Optionen werden über BONDING_OPTS definiert. Wenn eine korrekte ifcfg-Konfiguration vorliegt, lädt das Netzwerk-Skript das erforderliche Modul automatisch. Ein manueller Eintrag in /etc/modules-load.d/bonding.conf ist daher nicht zwingend erforderlich. Offizielle RHEL 7-Dokumentation zur ifcfg-Bonding-Konfiguration

Bash-Skript zur Erstellung von Backups und Konfigurationsentwürfen

Speichern Sie den folgenden Inhalt als prepare-bond.sh und passen Sie die Variablenwerte an Ihre Umgebung an. Das Skript sichert die aktuellen ifcfg-Dateien und den Netzwerkstatus in einem Verzeichnis, auf das nur root Zugriff hat, und erstellt die neuen Konfigurationsentwürfe in einem separaten Pfad. Das eigentliche Überschreiben der ifcfg-Dateien und der Neustart der Netzwerkschnittstellen werden im nächsten Abschnitt durchgeführt.

#!/bin/bash
# Nur für CentOS 7.9 / network.service: Erstellt lediglich Backups und Konfigurationsentwürfe.
set -euo pipefail
umask 077

BOND_DEVICE="bond0"
ETH0_DEVICE="eth0"
ETH1_DEVICE="eth1"
IP_ADDRESS="192.168.1.100"
PREFIX="24"
GATEWAY="192.168.1.1"
CFG_DIR="/etc/sysconfig/network-scripts"

die() { printf '%s\n' "$*" >&2; exit 1; }
valid_ipv4() {
  local value="$1" octet a b c d
  [[ "$value" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]] || return 1
  IFS=. read -r a b c d <<< "$value"
  for octet in "$a" "$b" "$c" "$d"; do
    (( 10#$octet <= 255 )) || return 1
  done
}

[[ "$EUID" -eq 0 ]] || die "root로 실행하세요."
[[ -d "$CFG_DIR" ]] || die "network-scripts 경로가 없습니다."
for nic in "$BOND_DEVICE" "$ETH0_DEVICE" "$ETH1_DEVICE"; do
  [[ "$nic" =~ ^[a-zA-Z0-9_-]{1,15}$ ]] || die "인터페이스 이름을 확인하세요."
done
[[ "$ETH0_DEVICE" != "$ETH1_DEVICE" ]] || die "서로 다른 물리 NIC가 필요합니다."
[[ "$BOND_DEVICE" != "$ETH0_DEVICE" && "$BOND_DEVICE" != "$ETH1_DEVICE" ]] ||
  die "bond 이름이 물리 NIC와 같습니다."
[[ ! -e "/sys/class/net/$BOND_DEVICE" && ! -e "$CFG_DIR/ifcfg-$BOND_DEVICE" ]] ||
  die "기존 bond가 있습니다. 기존 구성 변경은 이 예제 범위 밖입니다."
valid_ipv4 "$IP_ADDRESS" || die "IP 주소 형식이 잘못되었습니다."
valid_ipv4 "$GATEWAY" || die "게이트웨이 주소 형식이 잘못되었습니다."
[[ "$GATEWAY" != "$IP_ADDRESS" ]] || die "게이트웨이는 서버 자신과 달라야 합니다."
[[ "$PREFIX" =~ ^([1-9]|[12][0-9]|3[0-2])$ ]] || die "PREFIX는 1~32여야 합니다."
systemctl is-active --quiet network ||
  die "기존 network.service 환경에서만 사용하세요."
if systemctl is-active --quiet NetworkManager; then
  die "NetworkManager 환경입니다. 해당 환경의 nmcli 본딩 절차를 사용하세요."
fi

modinfo bonding >/dev/null
for nic in "$ETH0_DEVICE" "$ETH1_DEVICE"; do
  [[ -e "/sys/class/net/$nic" ]] || die "NIC가 없습니다: $nic"
  [[ -f "$CFG_DIR/ifcfg-$nic" ]] || die "기존 ifcfg 파일이 없습니다: $nic"
  [[ ! -L "/sys/class/net/$nic/master" ]] || die "이미 다른 장치에 종속된 NIC입니다: $nic"
  [[ ! -e "$CFG_DIR/route-$nic" && ! -e "$CFG_DIR/rule-$nic" &&
     ! -e "$CFG_DIR/route6-$nic" && ! -e "$CFG_DIR/rule6-$nic" ]] ||
    die "별도 경로/정책 설정은 bond에 따로 이전해야 합니다: $nic"
  if ip -6 address show dev "$nic" scope global | grep -q 'inet6 '; then
    die "IPv6 주소가 있는 NIC입니다. IPv6 이전 계획을 먼저 작성하세요: $nic"
  fi
done

PLAN_DIR=$(mktemp -d "/root/bond-plan.XXXXXXXX")
mkdir "$PLAN_DIR/before" "$PLAN_DIR/new"
for nic in "$ETH0_DEVICE" "$ETH1_DEVICE"; do
  cp -a "$CFG_DIR/ifcfg-$nic" "$PLAN_DIR/before/"
done
ip address show > "$PLAN_DIR/address-before.txt"
ip route show table all > "$PLAN_DIR/routes-before.txt"
ip rule show > "$PLAN_DIR/rules-before.txt"
printf 'BOND_DEVICE=%q\nETH0_DEVICE=%q\nETH1_DEVICE=%q\n' \
  "$BOND_DEVICE" "$ETH0_DEVICE" "$ETH1_DEVICE" > "$PLAN_DIR/names.sh"

cat > "$PLAN_DIR/new/ifcfg-$BOND_DEVICE" <<EOF
DEVICE=$BOND_DEVICE
NAME=$BOND_DEVICE
TYPE=Bond
BONDING_MASTER=yes
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
IPADDR=$IP_ADDRESS
PREFIX=$PREFIX
GATEWAY=$GATEWAY
DEFROUTE=yes
PEERDNS=no
IPV6INIT=no
BONDING_OPTS="mode=active-backup miimon=100"
EOF

for nic in "$ETH0_DEVICE" "$ETH1_DEVICE"; do
  cat > "$PLAN_DIR/new/ifcfg-$nic" <<EOF
DEVICE=$nic
NAME=$nic
TYPE=Ethernet
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
MASTER=$BOND_DEVICE
SLAVE=yes
IPV6INIT=no
EOF
done
printf '백업 및 후보 설정: %s\n' "$PLAN_DIR"
printf '실제 설정과 네트워크 상태는 변경하지 않았습니다.\n'

Prüfen Sie zunächst die Syntax mit bash -n prepare-bond.sh und führen Sie das Skript anschließend mit sudo bash prepare-bond.sh aus, um die Konfigurationsentwürfe zu erstellen. Notieren Sie sich den ausgegebenen Pfad und das Backup-Verzeichnis. Da die automatischen Prüfungen des Skripts keine IP-Konflikte, VLAN-Zugehörigkeiten, Switch-Richtlinien oder Routing-Abhängigkeiten vollständig validieren können, müssen Sie die manuellen Vorabprüfungen dennoch sorgfältig durchführen.

Aktivierung über die Konsole

Führen Sie die folgenden Befehle Schritt für Schritt aus. Falls ein Schritt fehlschlägt, fahren Sie nicht fort. Ein Exit-Code von 1 bei diff bedeutet, dass Unterschiede vorhanden sind. Stellen Sie sicher, dass diese Abweichungen den beabsichtigten Änderungen entsprechen, bevor Sie die Netzwerkschnittstellen deaktivieren. Beachten Sie, dass sich durch das Ändern der IP-Adresse in diesem Beispiel auch Ihre administrative Verbindungsadresse ändern kann.

# Auf der Root-Konsole ausführen. Ersetzen Sie den folgenden Pfad durch den tatsächlich generierten Pfad.
PLAN_DIR=/root/bond-plan.XXXXXXXX
test -f "$PLAN_DIR/names.sh" || exit 1
source "$PLAN_DIR/names.sh"
CFG_DIR=/etc/sysconfig/network-scripts

# Prüfung der Konfigurationsentwürfe: Bis zu diesem Zeitpunkt wird der Netzwerkstatus nicht verändert.
cat "$PLAN_DIR/new/ifcfg-$BOND_DEVICE"
diff -u "$PLAN_DIR/before/ifcfg-$ETH0_DEVICE" "$PLAN_DIR/new/ifcfg-$ETH0_DEVICE"
diff -u "$PLAN_DIR/before/ifcfg-$ETH1_DEVICE" "$PLAN_DIR/new/ifcfg-$ETH1_DEVICE"

# Nur nach erfolgreicher Prüfung ausführen. Ab hier wird die Verbindung der betroffenen NICs unterbrochen.
# Falls ifdown fehlschlägt, Ursache prüfen und abbrechen.
ifdown "$ETH0_DEVICE"
ifdown "$ETH1_DEVICE"

# Die folgenden drei Dateien installieren. Falls ein Fehler auftritt, nicht aktivieren, sondern Rollback durchführen.
install -o root -g root -m 600 "$PLAN_DIR/new/ifcfg-$BOND_DEVICE" "$CFG_DIR/ifcfg-$BOND_DEVICE"
install -o root -g root -m 600 "$PLAN_DIR/new/ifcfg-$ETH0_DEVICE" "$CFG_DIR/ifcfg-$ETH0_DEVICE"
install -o root -g root -m 600 "$PLAN_DIR/new/ifcfg-$ETH1_DEVICE" "$CFG_DIR/ifcfg-$ETH1_DEVICE"
restorecon "$CFG_DIR/ifcfg-$BOND_DEVICE" "$CFG_DIR/ifcfg-$ETH0_DEVICE" "$CFG_DIR/ifcfg-$ETH1_DEVICE"

ifup "$BOND_DEVICE"
ifup "$ETH0_DEVICE"
ifup "$ETH1_DEVICE"

Prüfung von IP-Adresse, Bonding-Modus und Failover

ip -br address show bond0
ip -d link show bond0
ip link show master bond0
cat /proc/net/bonding/bond0
ip route
ping -c 4 -I bond0 192.168.1.1
ethtool eth0
ethtool eth1

Dass das Interface bond0 angezeigt wird, reicht als Erfolgsnachweis nicht aus. Prüfen Sie, ob die IP-Adresse ausschließlich dem Bond-Interface zugewiesen ist, ob beide physischen NICs dem Bond untergeordnet sind und ob die Standardroute korrekt gesetzt ist. Überprüfen Sie in /proc/net/bonding/bond0 die folgenden Parameter:

# Beispielhaftes Format; keine Messwerte eines spezifischen Servers.
Bonding Mode: fault-tolerance (active-backup)
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 100
...
Slave Interface: eth0
MII Status: up
Speed: 1000 Mbps
...
Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps

Der Parameter Currently Active Slave zeigt die Schnittstelle an, die aktuell für die Kommunikation genutzt wird. Stellen Sie sicher, dass der MII Status beider NICs auf „up“ steht. Die tatsächliche Verbindungsgeschwindigkeit sollten Sie über die ethtool-Ausgabe der jeweiligen physischen NICs prüfen. Interpretieren Sie die auf dem Bond-Interface angezeigte kumulierte Geschwindigkeit nicht als tatsächlichen Durchsatz.

  1. Senden Sie von einem separaten Client aus kontinuierliche Pings und reale Dienstanfragen an die IP-Adresse des Servers.
  2. Trennen Sie bei geöffneter Wartungskonsole das Kabel der aktiven NIC oder deaktivieren Sie den entsprechenden Switch-Port.
  3. Beobachten Sie, ob die aktive Schnittstelle auf den anderen Port wechselt, die Kommunikation wiederhergestellt wird, und dokumentieren Sie den Paketverlust sowie die Auswirkungen auf den Dienst.
  4. Stellen Sie die getrennte Verbindung wieder her und prüfen Sie den Link-Status beider Ports. Testen Sie den redundanten Pfad auf dieselbe Weise.
  5. Prüfen Sie den Aufbau neuer Administrationssitzungen, die DNS-Auflösung sowie die Dienstantworten und führen Sie anschließend einen geplanten Neustart durch, um die Dauerhaftigkeit der Konfiguration zu bestätigen.

Ein physischer Kabeltest unterscheidet sich von einem Test auf Ausfälle im übergeordneten Netzwerk. Da miimon lediglich den Link-Status überwacht, kann es Ausfälle an übergeordneten Switches oder Routern, bei denen die physische Verbindung bestehen bleibt, unter Umständen nicht erkennen. Testen Sie das für Ihre Dienste erforderliche Ausfallszenario und die Switch-Konfiguration daher separat.

Wiederherstellung bei Problemen (Rollback)

Führen Sie die folgenden Schritte über die Konsole aus. Dieses Verfahren gilt für eine Neukonfiguration, bei der vor dem Start kein Bond existierte, und stellt die vom Vorbereitungsskript gesicherten ursprünglichen NIC-Einstellungen wieder her. Prüfen Sie eventuelle Fehler bei den einzelnen Schritten sowie den aktuellen Status, verifizieren Sie die Originaldateien und führen Sie das Rollback durch. Falls Sie während der Einrichtung Routing-, DNS- oder Firewall-Einstellungen geändert haben, müssen Sie diese Änderungen ebenfalls manuell rückgängig machen.

# Geben Sie den tatsächlichen Backup-Pfad an, der bei der Aktivierung ausgegeben wurde. Auf der Root-Konsole ausführen.
PLAN_DIR=/root/bond-plan.XXXXXXXX
test -f "$PLAN_DIR/names.sh" || exit 1
source "$PLAN_DIR/names.sh"
CFG_DIR=/etc/sysconfig/network-scripts

# Ergebnisse der einzelnen Schritte prüfen. Falls ifdown für ein noch nicht existierendes Bond fehlschlägt, zuerst den Status prüfen.
ifdown "$BOND_DEVICE"
ifdown "$ETH0_DEVICE"
ifdown "$ETH1_DEVICE"

# Dieses Verfahren gilt nur für eine Neukonfiguration, bei der zuvor kein Bond existierte.
ip link delete "$BOND_DEVICE" type bond
mv "$CFG_DIR/ifcfg-$BOND_DEVICE" "$PLAN_DIR/ifcfg-bond-failed"
cp -a "$PLAN_DIR/before/ifcfg-$ETH0_DEVICE" "$CFG_DIR/ifcfg-$ETH0_DEVICE"
cp -a "$PLAN_DIR/before/ifcfg-$ETH1_DEVICE" "$CFG_DIR/ifcfg-$ETH1_DEVICE"
restorecon "$CFG_DIR/ifcfg-$ETH0_DEVICE" "$CFG_DIR/ifcfg-$ETH1_DEVICE"

ifup "$ETH0_DEVICE"
ifup "$ETH1_DEVICE"
ip -br address
ip route
journalctl -u network --since '-10 minutes' --no-pager

Vergleichen Sie nach der Wiederherstellung die IP-Adressen und Routen mit den Dateien address-before.txt und routes-before.txt und prüfen Sie den administrativen Zugriff sowie die Dienste von einem externen Client aus. Falls der Link Failure Count ansteigt oder der Modus nicht den Erwartungen entspricht, überprüfen Sie zuerst die Verkabelung, die Switch-VLANs, die Link-Aggregation-Einstellungen, eventuelle doppelte Profile sowie die Parameter in BONDING_OPTS.

Referenzen