Skip to content

Commit e90637a

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

File tree

6 files changed

+89
-10
lines changed

6 files changed

+89
-10
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ rules:
276276
- ovn-eips
277277
- ovn-eips/status
278278
- nodes
279+
- nodes/status
279280
- pods
280281
verbs:
281282
- get

dist/images/install.sh

+1
Original file line numberDiff line numberDiff line change
@@ -3287,6 +3287,7 @@ rules:
32873287
- ovn-eips
32883288
- ovn-eips/status
32893289
- nodes
3290+
- nodes/status
32903291
- pods
32913292
verbs:
32923293
- 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, cidr, err)
8888
return err
8989
}
90-
return configureNodeNic(portName, ipAddr, gw, cidr, mac, config.MTU)
90+
return configureNodeNic(config.KubeClient, config.NodeName, portName, ipAddr, gw, cidr, 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

+32
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
package util
22

33
import (
4+
"context"
45
"crypto/tls"
6+
"encoding/json"
57
"fmt"
68
"net"
79
"net/url"
810
"strings"
911
"time"
1012

1113
v1 "k8s.io/api/core/v1"
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1215
"k8s.io/apimachinery/pkg/labels"
1316
"k8s.io/apimachinery/pkg/selection"
17+
"k8s.io/client-go/kubernetes"
1418
"k8s.io/klog/v2"
1519
)
1620

@@ -116,3 +120,31 @@ func LabelSelectorNotEmpty(key string) (labels.Selector, error) {
116120
func GetTruncatedUID(uid string) string {
117121
return uid[len(uid)-12:]
118122
}
123+
124+
func SetNodeNetworkUnavailableCondition(cs kubernetes.Interface, nodeName string, status v1.ConditionStatus, reason, message string) error {
125+
now := metav1.NewTime(time.Now())
126+
patch := map[string]map[string][]v1.NodeCondition{
127+
"status": {
128+
"conditions": []v1.NodeCondition{{
129+
Type: v1.NodeNetworkUnavailable,
130+
Status: status,
131+
Reason: reason,
132+
Message: message,
133+
LastTransitionTime: now,
134+
LastHeartbeatTime: now,
135+
}},
136+
},
137+
}
138+
data, err := json.Marshal(patch)
139+
if err != nil {
140+
klog.Errorf("failed to marshal patch data: %v", err)
141+
return err
142+
}
143+
144+
if _, err = cs.CoreV1().Nodes().PatchStatus(context.Background(), nodeName, data); err != nil {
145+
klog.Errorf("failed to patch node %s: %v", nodeName, err)
146+
return err
147+
}
148+
149+
return nil
150+
}

0 commit comments

Comments
 (0)