Skip to content

Commit e250afa

Browse files
authored
cni-server: set node NetworkUnavailable condition after join subnet gateway check (#4915)
Signed-off-by: zhangzujian <zhangzujian.7@gmail.com>
1 parent a7fff99 commit e250afa

File tree

6 files changed

+88
-10
lines changed

6 files changed

+88
-10
lines changed

charts/kube-ovn/templates/ovn-CR.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ rules:
288288
- ovn-eips
289289
- ovn-eips/status
290290
- nodes
291+
- nodes/status
291292
- pods
292293
verbs:
293294
- get

dist/images/install.sh

+1
Original file line numberDiff line numberDiff line change
@@ -3665,6 +3665,7 @@ rules:
36653665
- ovn-eips
36663666
- ovn-eips/status
36673667
- nodes
3668+
- nodes/status
36683669
- pods
36693670
verbs:
36703671
- get

pkg/daemon/init.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func InitNodeGateway(config *Configuration) error {
8787
klog.Errorf("failed to get ip %s with mask %s, %v", ip, joinCIDR, err)
8888
return err
8989
}
90-
return configureNodeNic(portName, ipAddr, gw, joinCIDR, mac, config.MTU)
90+
return configureNodeNic(config.KubeClient, config.NodeName, portName, ipAddr, gw, joinCIDR, mac, config.MTU)
9191
}
9292

9393
func InitMirror(config *Configuration) error {

pkg/daemon/ovs_linux.go

+40-5
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ import (
2222
sriovutilfs "github.com/k8snetworkplumbingwg/sriovnet/pkg/utils/filesystem"
2323
"github.com/vishvananda/netlink"
2424
"golang.org/x/sys/unix"
25+
corev1 "k8s.io/api/core/v1"
2526
k8serrors "k8s.io/apimachinery/pkg/api/errors"
2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2728
"k8s.io/apimachinery/pkg/labels"
2829
"k8s.io/apimachinery/pkg/types"
30+
"k8s.io/client-go/kubernetes"
2931
"k8s.io/klog/v2"
3032

3133
kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
@@ -591,7 +593,7 @@ func waitNetworkReady(nic, ipAddr, gateway string, underlayGateway, verbose bool
591593
return nil
592594
}
593595

594-
func configureNodeNic(portName, ip, gw, joinCIDR string, macAddr net.HardwareAddr, mtu int) error {
596+
func configureNodeNic(cs kubernetes.Interface, nodeName, portName, ip, gw, joinCIDR string, macAddr net.HardwareAddr, mtu int) error {
595597
ipStr := util.GetIPWithoutMask(ip)
596598
raw, err := ovs.Exec(ovs.MayExist, "add-port", "br-int", util.NodeNic, "--",
597599
"set", "interface", util.NodeNic, "type=internal", "--",
@@ -670,11 +672,20 @@ func configureNodeNic(portName, ip, gw, joinCIDR string, macAddr net.HardwareAdd
670672

671673
// ping ovn0 gw to activate the flow
672674
klog.Infof("wait ovn0 gw ready")
673-
if err := waitNetworkReady(util.NodeNic, ip, gw, false, true, gatewayCheckMaxRetry, nil); err != nil {
675+
status := corev1.ConditionFalse
676+
reason := "JoinSubnetGatewayReachable"
677+
message := fmt.Sprintf("ping check to gateway ip %s succeeded", gw)
678+
if err = waitNetworkReady(util.NodeNic, ip, gw, false, true, gatewayCheckMaxRetry, nil); err != nil {
674679
klog.Errorf("failed to init ovn0 check: %v", err)
675-
return err
680+
status = corev1.ConditionTrue
681+
reason = "JoinSubnetGatewayUnreachable"
682+
message = fmt.Sprintf("ping check to gateway ip %s failed", gw)
676683
}
677-
return nil
684+
if err := util.SetNodeNetworkUnavailableCondition(cs, nodeName, status, reason, message); err != nil {
685+
klog.Errorf("failed to set node network unavailable condition: %v", err)
686+
}
687+
688+
return err
678689
}
679690

680691
// If OVS restart, the ovn0 port will down and prevent host to pod network,
@@ -696,7 +707,31 @@ func (c *Controller) loopOvn0Check() {
696707
}
697708
ip := node.Annotations[util.IPAddressAnnotation]
698709
gw := node.Annotations[util.GatewayAnnotation]
699-
if err := waitNetworkReady(util.NodeNic, ip, gw, false, false, 5, nil); err != nil {
710+
status := corev1.ConditionFalse
711+
reason := "JoinSubnetGatewayReachable"
712+
message := fmt.Sprintf("ping check to gateway ip %s succeeded", gw)
713+
if err = waitNetworkReady(util.NodeNic, ip, gw, false, false, 5, nil); err != nil {
714+
klog.Errorf("failed to init ovn0 check: %v", err)
715+
status = corev1.ConditionTrue
716+
reason = "JoinSubnetGatewayUnreachable"
717+
message = fmt.Sprintf("ping check to gateway ip %s failed", gw)
718+
}
719+
720+
var alreadySet bool
721+
for _, condition := range node.Status.Conditions {
722+
if condition.Type == corev1.NodeNetworkUnavailable && condition.Status == corev1.ConditionTrue &&
723+
condition.Reason == reason && condition.Message == message {
724+
alreadySet = true
725+
break
726+
}
727+
}
728+
if !alreadySet {
729+
if err := util.SetNodeNetworkUnavailableCondition(c.config.KubeClient, c.config.NodeName, status, reason, message); err != nil {
730+
klog.Errorf("failed to set node network unavailable condition: %v", err)
731+
}
732+
}
733+
734+
if err != nil {
700735
util.LogFatalAndExit(err, "failed to ping ovn0 gateway %s", gw)
701736
}
702737
}

pkg/daemon/ovs_windows.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99

1010
"github.com/Microsoft/hcsshim"
1111
"github.com/containernetworking/plugins/pkg/hns"
12+
corev1 "k8s.io/api/core/v1"
1213
"k8s.io/apimachinery/pkg/types"
14+
"k8s.io/client-go/kubernetes"
1315
"k8s.io/klog/v2"
1416

1517
kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
@@ -262,7 +264,7 @@ func waitNetworkReady(nic, ipAddr, gateway string, underlayGateway, verbose bool
262264
return nil
263265
}
264266

265-
func configureNodeNic(portName, ip, gw, joinCIDR string, macAddr net.HardwareAddr, mtu int) error {
267+
func configureNodeNic(cs kubernetes.Interface, nodeName, portName, ip, gw, joinCIDR string, macAddr net.HardwareAddr, mtu int) error {
266268
ipStr := util.GetIPWithoutMask(ip)
267269
raw, err := ovs.Exec(ovs.MayExist, "add-port", "br-int", util.NodeNic, "--",
268270
"set", "interface", util.NodeNic, "type=internal", "--",
@@ -326,11 +328,19 @@ func configureNodeNic(portName, ip, gw, joinCIDR string, macAddr net.HardwareAdd
326328

327329
// ping ovn0 gw to activate the flow
328330
klog.Infof("wait ovn0 gw ready")
329-
if err := waitNetworkReady(util.NodeNic, ip, gw, false, true, gatewayCheckMaxRetry); err != nil {
331+
status := corev1.ConditionFalse
332+
reason := "JoinSubnetGatewayReachable"
333+
message := fmt.Sprintf("ping check to gateway ip %s succeeded", gw)
334+
if err = waitNetworkReady(util.NodeNic, ip, gw, false, true, gatewayCheckMaxRetry); err != nil {
330335
klog.Errorf("failed to init ovn0 check: %v", err)
331-
return err
336+
status = corev1.ConditionTrue
337+
reason = "JoinSubnetGatewayUnreachable"
338+
message = fmt.Sprintf("ping check to gateway ip %s failed", gw)
332339
}
333-
return nil
340+
if err := util.SetNodeNetworkUnavailableCondition(cs, nodeName, status, reason, message); err != nil {
341+
klog.Errorf("failed to set node network unavailable condition: %v", err)
342+
}
343+
return err
334344
}
335345

336346
// If OVS restart, the ovn0 port will down and prevent host to pod network,

pkg/util/k8s.go

+31
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package util
22

33
import (
4+
"context"
45
"crypto/tls"
6+
"encoding/json"
57
"errors"
68
"fmt"
79
"net"
@@ -15,6 +17,7 @@ import (
1517
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1618
"k8s.io/apimachinery/pkg/labels"
1719
"k8s.io/apimachinery/pkg/selection"
20+
"k8s.io/client-go/kubernetes"
1821
"k8s.io/klog/v2"
1922
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2023

@@ -169,3 +172,31 @@ func DeploymentIsReady(deployment *appsv1.Deployment) bool {
169172
}
170173
return true
171174
}
175+
176+
func SetNodeNetworkUnavailableCondition(cs kubernetes.Interface, nodeName string, status v1.ConditionStatus, reason, message string) error {
177+
now := metav1.NewTime(time.Now())
178+
patch := map[string]map[string][]v1.NodeCondition{
179+
"status": {
180+
"conditions": []v1.NodeCondition{{
181+
Type: v1.NodeNetworkUnavailable,
182+
Status: status,
183+
Reason: reason,
184+
Message: message,
185+
LastTransitionTime: now,
186+
LastHeartbeatTime: now,
187+
}},
188+
},
189+
}
190+
data, err := json.Marshal(patch)
191+
if err != nil {
192+
klog.Errorf("failed to marshal patch data: %v", err)
193+
return err
194+
}
195+
196+
if _, err = cs.CoreV1().Nodes().PatchStatus(context.Background(), nodeName, data); err != nil {
197+
klog.Errorf("failed to patch node %s: %v", nodeName, err)
198+
return err
199+
}
200+
201+
return nil
202+
}

0 commit comments

Comments
 (0)