Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Egress IP health monitoring over GRPC #3100

Merged
merged 5 commits into from Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions contrib/kind.sh
Expand Up @@ -50,6 +50,7 @@ usage() {
echo " [-dd |--dns-domain |"
echo " [-ric | --run-in-container |"
echo " [-cn | --cluster-name |"
echo " [-ehp|--egress-ip-healthcheck-port <num>]"
flavio-fernandes marked this conversation as resolved.
Show resolved Hide resolved
echo " [-h]]"
echo ""
echo "-cf | --config-file Name of the KIND J2 configuration file."
Expand Down Expand Up @@ -92,6 +93,7 @@ usage() {
echo "-dd | --dns-domain Configure a custom dnsDomain for k8s services, Defaults to 'cluster.local'"
echo "-cn | --cluster-name Configure the kind cluster's name"
echo "-ric | --run-in-container Configure the script to be run from a docker container, allowing it to still communicate with the kind controlplane"
echo "-ehp | --egress-ip-healthcheck-port TCP port used for gRPC session by egress IP node check. DEFAULT: 9107 (Use "0" for legacy dial to port 9)."
echo "--delete Delete current cluster"
echo ""
}
Expand Down Expand Up @@ -222,6 +224,14 @@ parse_args() {
;;
-ric | --run-in-container ) RUN_IN_CONTAINER=true
;;
-ehp | --egress-ip-healthcheck-port ) shift
if ! [[ "$1" =~ ^[0-9]+$ ]]; then
echo "Invalid egress-ip-healthcheck-port: $1"
usage
exit 1
fi
OVN_EGRESSIP_HEALTHCHECK_PORT=$1
;;
--delete ) delete
exit
;;
Expand Down Expand Up @@ -277,6 +287,7 @@ print_params() {
echo "OVN_HOST_NETWORK_NAMESPACE = $OVN_HOST_NETWORK_NAMESPACE"
echo "OVN_ENABLE_EX_GW_NETWORK_BRIDGE = $OVN_ENABLE_EX_GW_NETWORK_BRIDGE"
echo "OVN_EX_GW_NETWORK_INTERFACE = $OVN_EX_GW_NETWORK_INTERFACE"
echo "OVN_EGRESSIP_HEALTHCHECK_PORT = $OVN_EGRESSIP_HEALTHCHECK_PORT"
echo ""
}

Expand Down Expand Up @@ -382,6 +393,7 @@ set_default_params() {
KIND_NUM_WORKER=${KIND_NUM_WORKER:-2}
fi
OVN_HOST_NETWORK_NAMESPACE=${OVN_HOST_NETWORK_NAMESPACE:-ovn-host-network}
OVN_EGRESSIP_HEALTHCHECK_PORT=${OVN_EGRESSIP_HEALTHCHECK_PORT:-9107}
OCI_BIN=${KIND_EXPERIMENTAL_PROVIDER:-docker}
}

Expand Down Expand Up @@ -579,6 +591,7 @@ create_ovn_kube_manifests() {
--ovn-loglevel-controller="${OVN_LOG_LEVEL_CONTROLLER}" \
--ovnkube-config-duration-enable=true \
--egress-ip-enable=true \
--egress-ip-healthcheck-port="${OVN_EGRESSIP_HEALTHCHECK_PORT}" \
--egress-firewall-enable=true \
--egress-qos-enable=true \
--v4-join-subnet="${JOIN_SUBNET_IPV4}" \
Expand Down
9 changes: 9 additions & 0 deletions dist/images/daemonset.sh
Expand Up @@ -60,6 +60,7 @@ OVN_DISABLE_PKT_MTU_CHECK=""
OVN_EMPTY_LB_EVENTS=""
OVN_MULTICAST_ENABLE=""
OVN_EGRESSIP_ENABLE=
OVN_EGRESSIP_HEALTHCHECK_PORT=
OVN_EGRESSFIREWALL_ENABLE=
OVN_EGRESSQOS_ENABLE=
OVN_DISABLE_OVN_IFACE_ID_VER="false"
Expand Down Expand Up @@ -207,6 +208,9 @@ while [ "$1" != "" ]; do
--egress-ip-enable)
OVN_EGRESSIP_ENABLE=$VALUE
;;
--egress-ip-healthcheck-port)
OVN_EGRESSIP_HEALTHCHECK_PORT=$VALUE
;;
--disabe-ovn-iface-id-ver)
OVN_DISABLE_OVN_IFACE_ID_VER=$VALUE
;;
Expand Down Expand Up @@ -319,6 +323,8 @@ ovn_hybrid_overlay_enable=${OVN_HYBRID_OVERLAY_ENABLE}
echo "ovn_hybrid_overlay_enable: ${ovn_hybrid_overlay_enable}"
ovn_egress_ip_enable=${OVN_EGRESSIP_ENABLE}
echo "ovn_egress_ip_enable: ${ovn_egress_ip_enable}"
ovn_egress_ip_healthcheck_port=${OVN_EGRESSIP_HEALTHCHECK_PORT}
echo "ovn_egress_ip_healthcheck_port: ${ovn_egress_ip_healthcheck_port}"
ovn_egress_firewall_enable=${OVN_EGRESSFIREWALL_ENABLE}
echo "ovn_egress_firewall_enable: ${ovn_egress_firewall_enable}"
ovn_egress_qos_enable=${OVN_EGRESSQOS_ENABLE}
Expand Down Expand Up @@ -406,6 +412,7 @@ ovn_image=${image} \
ovn_v6_join_subnet=${ovn_v6_join_subnet} \
ovn_multicast_enable=${ovn_multicast_enable} \
ovn_egress_ip_enable=${ovn_egress_ip_enable} \
ovn_egress_ip_healthcheck_port=${ovn_egress_ip_healthcheck_port} \
ovn_ssl_en=${ovn_ssl_en} \
ovn_remote_probe_interval=${ovn_remote_probe_interval} \
ovn_monitor_all=${ovn_monitor_all} \
Expand Down Expand Up @@ -445,6 +452,7 @@ ovn_image=${image} \
ovn_v6_join_subnet=${ovn_v6_join_subnet} \
ovn_multicast_enable=${ovn_multicast_enable} \
ovn_egress_ip_enable=${ovn_egress_ip_enable} \
ovn_egress_ip_healthcheck_port=${ovn_egress_ip_healthcheck_port} \
ovn_netflow_targets=${ovn_netflow_targets} \
ovn_sflow_targets=${ovn_sflow_targets} \
ovn_ipfix_targets=${ovn_ipfix_targets} \
Expand Down Expand Up @@ -474,6 +482,7 @@ ovn_image=${image} \
ovn_v6_join_subnet=${ovn_v6_join_subnet} \
ovn_multicast_enable=${ovn_multicast_enable} \
ovn_egress_ip_enable=${ovn_egress_ip_enable} \
ovn_egress_ip_healthcheck_port=${ovn_egress_ip_healthcheck_port} \
ovn_egress_firewall_enable=${ovn_egress_firewall_enable} \
ovn_egress_qos_enable=${ovn_egress_qos_enable} \
ovn_ssl_en=${ovn_ssl_en} \
Expand Down
16 changes: 16 additions & 0 deletions dist/images/ovnkube.sh
Expand Up @@ -73,6 +73,7 @@ fi
# OVN_LFLOW_CACHE_LIMIT - maximum number of logical flow cache entries of ovn-controller
# OVN_LFLOW_CACHE_LIMIT_KB - maximum size of the logical flow cache of ovn-controller
# OVN_EGRESSIP_ENABLE - enable egress IP for ovn-kubernetes
# OVN_EGRESSIP_HEALTHCHECK_PORT - egress IP node check to use grpc on this port (0 ==> dial to port 9 instead)
# OVN_EGRESSFIREWALL_ENABLE - enable egressFirewall for ovn-kubernetes
# OVN_EGRESSQOS_ENABLE - enable egress QoS for ovn-kubernetes
# OVN_UNPRIVILEGED_MODE - execute CNI ovs/netns commands from host (default no)
Expand Down Expand Up @@ -211,6 +212,8 @@ ovn_lflow_cache_limit_kb=${OVN_LFLOW_CACHE_LIMIT_KB:-}
ovn_multicast_enable=${OVN_MULTICAST_ENABLE:-}
#OVN_EGRESSIP_ENABLE - enable egress IP for ovn-kubernetes
ovn_egressip_enable=${OVN_EGRESSIP_ENABLE:-false}
#OVN_EGRESSIP_HEALTHCHECK_PORT - egress IP node check to use grpc on this port
ovn_egress_ip_healthcheck_port=${OVN_EGRESSIP_HEALTHCHECK_PORT:-9107}
#OVN_EGRESSFIREWALL_ENABLE - enable egressFirewall for ovn-kubernetes
ovn_egressfirewall_enable=${OVN_EGRESSFIREWALL_ENABLE:-false}
#OVN_EGRESSQOS_ENABLE - enable egress QoS for ovn-kubernetes
Expand Down Expand Up @@ -948,6 +951,12 @@ ovn-master() {
if [[ ${ovn_egressip_enable} == "true" ]]; then
egressip_enabled_flag="--enable-egress-ip"
fi

egressip_healthcheck_port_flag=
if [[ -n "${ovn_egress_ip_healthcheck_port}" ]]; then
egressip_healthcheck_port_flag="--egressip-node-healthcheck-port=${ovn_egress_ip_healthcheck_port}"
fi

egressfirewall_enabled_flag=
if [[ ${ovn_egressfirewall_enable} == "true" ]]; then
egressfirewall_enabled_flag="--enable-egress-firewall"
Expand Down Expand Up @@ -995,6 +1004,7 @@ ovn-master() {
${multicast_enabled_flag} \
${ovn_acl_logging_rate_limit_flag} \
${egressip_enabled_flag} \
${egressip_healthcheck_port_flag} \
${egressfirewall_enabled_flag} \
${egressqos_enabled_flag} \
${ovnkube_config_duration_enable_flag} \
Expand Down Expand Up @@ -1104,6 +1114,11 @@ ovn-node() {
egressip_enabled_flag="--enable-egress-ip"
fi

egressip_healthcheck_port_flag=
if [[ -n "${ovn_egress_ip_healthcheck_port}" ]]; then
egressip_healthcheck_port_flag="--egressip-node-healthcheck-port=${ovn_egress_ip_healthcheck_port}"
fi

disable_ovn_iface_id_ver_flag=
if [[ ${ovn_disable_ovn_iface_id_ver} == "true" ]]; then
disable_ovn_iface_id_ver_flag="--disable-ovn-iface-id-ver"
Expand Down Expand Up @@ -1257,6 +1272,7 @@ ovn-node() {
${lflow_cache_limit_kb} \
${multicast_enabled_flag} \
${egressip_enabled_flag} \
${egressip_healthcheck_port_flag} \
${disable_ovn_iface_id_ver_flag} \
${netflow_targets} \
${sflow_targets} \
Expand Down
2 changes: 2 additions & 0 deletions dist/templates/ovnkube-master.yaml.j2
Expand Up @@ -195,6 +195,8 @@ spec:
value: "{{ ovn_hybrid_overlay_enable }}"
- name: OVN_EGRESSIP_ENABLE
value: "{{ ovn_egress_ip_enable }}"
- name: OVN_EGRESSIP_HEALTHCHECK_PORT
value: "{{ ovn_egress_ip_healthcheck_port }}"
- name: OVN_EGRESSFIREWALL_ENABLE
value: "{{ ovn_egress_firewall_enable }}"
- name: OVN_EGRESSQOS_ENABLE
Expand Down
2 changes: 2 additions & 0 deletions dist/templates/ovnkube-node.yaml.j2
Expand Up @@ -153,6 +153,8 @@ spec:
value: "{{ ovn_hybrid_overlay_enable }}"
- name: OVN_EGRESSIP_ENABLE
value: "{{ ovn_egress_ip_enable }}"
- name: OVN_EGRESSIP_HEALTHCHECK_PORT
value: "{{ ovn_egress_ip_healthcheck_port }}"
- name: OVN_HYBRID_OVERLAY_NET_CIDR
value: "{{ ovn_hybrid_overlay_net_cidr }}"
- name: OVN_DISABLE_SNAT_MULTIPLE_GWS
Expand Down
4 changes: 3 additions & 1 deletion go-controller/go.mod
Expand Up @@ -34,6 +34,8 @@ require (
golang.org/x/net v0.0.0-20220526153639-5463443f8c37
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.0
gopkg.in/fsnotify/fsnotify.v1 v1.4.7
gopkg.in/gcfg.v1 v1.2.3
gopkg.in/natefinch/lumberjack.v2 v2.0.0
Expand Down Expand Up @@ -97,7 +99,7 @@ require (
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go-controller/go.sum
Expand Up @@ -825,6 +825,7 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1 h1:E7wSQBXkH3T3diucK+9Z1kjn4+/9tNG7lZLr75oOhh8=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
Expand All @@ -845,6 +846,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
Expand Down
6 changes: 6 additions & 0 deletions go-controller/pkg/config/config.go
Expand Up @@ -337,6 +337,7 @@ type OVNKubernetesFeatureConfig struct {
EgressIPReachabiltyTotalTimeout int `gcfg:"egressip-reachability-total-timeout"`
EnableEgressFirewall bool `gcfg:"enable-egress-firewall"`
EnableEgressQoS bool `gcfg:"enable-egress-qos"`
EgressIPNodeHealthCheckPort int `gcfg:"egressip-node-healthcheck-port"`
flavio-fernandes marked this conversation as resolved.
Show resolved Hide resolved
}

// GatewayMode holds the node gateway mode
Expand Down Expand Up @@ -876,6 +877,11 @@ var OVNK8sFeatureFlags = []cli.Flag{
Destination: &cliConfig.OVNKubernetesFeature.EnableEgressQoS,
Value: OVNKubernetesFeature.EnableEgressQoS,
},
&cli.IntFlag{
Name: "egressip-node-healthcheck-port",
Usage: "Configure EgressIP node reachability using gRPC on this TCP port.",
Destination: &cliConfig.OVNKubernetesFeature.EgressIPNodeHealthCheckPort,
},
}

// K8sFlags capture Kubernetes-related options
Expand Down
7 changes: 7 additions & 0 deletions go-controller/pkg/config/config_test.go
Expand Up @@ -210,6 +210,7 @@ mode=full

[ovnkubernetesfeature]
egressip-reachability-total-timeout=3
egressip-node-healthcheck-port=1234
`

var newData string
Expand Down Expand Up @@ -298,6 +299,7 @@ var _ = Describe("Config Operations", func() {
gomega.Expect(OvnKubeNode.MgmtPortNetdev).To(gomega.Equal(""))
gomega.Expect(Gateway.RouterSubnet).To(gomega.Equal(""))
gomega.Expect(OVNKubernetesFeature.EgressIPReachabiltyTotalTimeout).To(gomega.Equal(1))
gomega.Expect(OVNKubernetesFeature.EgressIPNodeHealthCheckPort).To(gomega.Equal(0))

for _, a := range []OvnAuthConfig{OvnNorth, OvnSouth} {
gomega.Expect(a.Scheme).To(gomega.Equal(OvnDBSchemeUnix))
Expand Down Expand Up @@ -602,6 +604,7 @@ var _ = Describe("Config Operations", func() {

gomega.Expect(HybridOverlay.Enabled).To(gomega.BeTrue())
gomega.Expect(OVNKubernetesFeature.EgressIPReachabiltyTotalTimeout).To(gomega.Equal(3))
gomega.Expect(OVNKubernetesFeature.EgressIPNodeHealthCheckPort).To(gomega.Equal(1234))
gomega.Expect(HybridOverlay.ClusterSubnets).To(gomega.Equal([]CIDRNetworkEntry{
{ovntest.MustParseIPNet("11.132.0.0/14"), 23},
}))
Expand Down Expand Up @@ -683,6 +686,7 @@ var _ = Describe("Config Operations", func() {

gomega.Expect(HybridOverlay.Enabled).To(gomega.BeTrue())
gomega.Expect(OVNKubernetesFeature.EgressIPReachabiltyTotalTimeout).To(gomega.Equal(5))
gomega.Expect(OVNKubernetesFeature.EgressIPNodeHealthCheckPort).To(gomega.Equal(4321))
gomega.Expect(HybridOverlay.ClusterSubnets).To(gomega.Equal([]CIDRNetworkEntry{
{ovntest.MustParseIPNet("11.132.0.0/14"), 23},
}))
Expand Down Expand Up @@ -738,6 +742,7 @@ var _ = Describe("Config Operations", func() {
"-ofctrl-wait-before-clear=5000",
"-metrics-enable-config-duration=true",
"-egressip-reachability-total-timeout=5",
"-egressip-node-healthcheck-port=4321",
}
err = app.Run(cliArgs)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
Expand Down Expand Up @@ -1074,6 +1079,7 @@ enable-pprof=true
gomega.Equal("ssl:6.5.4.1:6652,ssl:6.5.4.2:6652,ssl:6.5.4.3:6652"))
gomega.Expect(OvnSouth.CertCommonName).To(gomega.Equal("testsbcommonname"))
gomega.Expect(OVNKubernetesFeature.EgressIPReachabiltyTotalTimeout).To(gomega.Equal(3))
gomega.Expect(OVNKubernetesFeature.EgressIPNodeHealthCheckPort).To(gomega.Equal(12345))
return nil
}
cliArgs := []string{
Expand Down Expand Up @@ -1110,6 +1116,7 @@ enable-pprof=true
"-sb-client-cacert=/client/cacert2",
"-sb-cert-common-name=testsbcommonname",
"-egressip-reachability-total-timeout=3",
"-egressip-node-healthcheck-port=12345",
}
err = app.Run(cliArgs)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
Expand Down
40 changes: 40 additions & 0 deletions go-controller/pkg/node/node.go
Expand Up @@ -20,13 +20,15 @@ import (
"k8s.io/klog/v2"
utilnet "k8s.io/utils/net"

"github.com/containernetworking/plugins/pkg/ip"
honode "github.com/ovn-org/ovn-kubernetes/go-controller/hybrid-overlay/pkg/controller"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/cni"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/factory"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/informer"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/kube"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/node/controllers/upgrade"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/ovn/healthcheck"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types"
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util"
"github.com/vishvananda/netlink"
Expand Down Expand Up @@ -571,10 +573,48 @@ func (n *OvnNode) Start(ctx context.Context, wg *sync.WaitGroup) error {
}
}

// Start the health checking server used by egressip, if EgressIPNodeHealthCheckPort is specified
if err := n.startEgressIPHealthCheckingServer(wg, mgmtPortConfig); err != nil {
flavio-fernandes marked this conversation as resolved.
Show resolved Hide resolved
return err
}

klog.Infof("OVN Kube Node initialized and ready.")
return nil
}

func (n *OvnNode) startEgressIPHealthCheckingServer(wg *sync.WaitGroup, mgmtPortConfig *managementPortConfig) error {
healthCheckPort := config.OVNKubernetesFeature.EgressIPNodeHealthCheckPort
if healthCheckPort == 0 {
klog.Infof("Egress IP health check server skipped: no port specified")
return nil
}

var nodeMgmtIP net.IP
if mgmtPortConfig.ipv4 != nil {
nodeMgmtIP = mgmtPortConfig.ipv4.ifAddr.IP
} else if mgmtPortConfig.ipv6 != nil {
nodeMgmtIP = mgmtPortConfig.ipv6.ifAddr.IP
// Wait for IPv6 address to become usable.
flavio-fernandes marked this conversation as resolved.
Show resolved Hide resolved
if err := ip.SettleAddresses(mgmtPortConfig.ifName, 10); err != nil {
return fmt.Errorf("failed start health checking server due to unsettled IPv6: %w", err)
}
} else {
return fmt.Errorf("unable to start health checking server: no mgmt ip")
}

healthServer, err := healthcheck.NewEgressIPHealthServer(nodeMgmtIP, healthCheckPort)
if err != nil {
return fmt.Errorf("unable to allocate health checking server: %v", err)
}

wg.Add(1)
go func() {
defer wg.Done()
healthServer.Run(n.stopChan)
}()
return nil
}

func (n *OvnNode) WatchEndpointSlices() error {
_, err := n.watchFactory.AddEndpointSliceHandler(cache.ResourceEventHandlerFuncs{
UpdateFunc: func(old, new interface{}) {
Expand Down