-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add healthcheck to check the gateway status
*Populate the healthcheck-ip in endpoint object *Ping the remote gateway nodes healthcheck ip Signed-off-by: Aswin Surayanarayanan <[email protected]>
- Loading branch information
1 parent
b5234c4
commit 6e612d6
Showing
8 changed files
with
216 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package healthchecker | ||
|
||
import ( | ||
"github.com/go-ping/ping" | ||
v1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" | ||
v1typed "github.com/submariner-io/submariner/pkg/client/clientset/versioned/typed/submariner.io/v1" | ||
"k8s.io/apimachinery/pkg/api/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/util/wait" | ||
"k8s.io/klog" | ||
"sync" | ||
"time" | ||
) | ||
|
||
var HealthCheckInterval = 15 * time.Second | ||
|
||
type HealthChecker struct { | ||
localEndpointName string | ||
client v1typed.GatewayInterface | ||
latencyMap *sync.Map | ||
} | ||
|
||
type LatencyInfo struct { | ||
Status v1.ConnectionStatus | ||
Latency *v1.LatencySpec | ||
} | ||
|
||
// NewEngine creates a new Engine for the local cluster | ||
func NewHealthChecker(localEndpointName string, client v1typed.GatewayInterface, | ||
latencyMap *sync.Map) *HealthChecker { | ||
return &HealthChecker{ | ||
localEndpointName: localEndpointName, | ||
client: client, | ||
latencyMap: latencyMap, | ||
} | ||
} | ||
|
||
func (h *HealthChecker) Run(stopCh <-chan struct{}) { | ||
go func() { | ||
wait.Until(h.checkRemoteGatewayHealth, HealthCheckInterval, stopCh) | ||
}() | ||
|
||
klog.Infof("CableEngine healthchecker started") | ||
} | ||
func (h *HealthChecker) checkRemoteGatewayHealth() { | ||
existingGw, err := h.client.Get(h.localEndpointName, metav1.GetOptions{}) | ||
if errors.IsNotFound(err) { | ||
klog.V(2).Info("Gateway object not found: %v", err) | ||
return; | ||
} else if err != nil { | ||
klog.Errorf("Error retrieving the gateway object: %v", err) | ||
return; | ||
} | ||
if (len(existingGw.Status.Connections) == 0) { | ||
klog.V(2).Info("No endpoints present in the gateway") | ||
return | ||
} | ||
deleteMap := copyLatencyMap(h.latencyMap) | ||
for _, endPointInfo := range existingGw.Status.Connections { | ||
hostName := endPointInfo.Endpoint.Hostname | ||
healthCheckIp := endPointInfo.Endpoint.HealthCheckIP | ||
// Remove the entry that is found in the gateway connection status | ||
deleteMap.Delete(hostName) | ||
go func() { | ||
latencyInfo := h.checkRemoteGatewayHealthSafe(hostName, healthCheckIp) | ||
if (latencyInfo != nil) { | ||
h.latencyMap.Store(hostName, latencyInfo) | ||
} | ||
}() | ||
} | ||
|
||
deleteMap.Range(func(k, v interface{}) bool { | ||
// Remove the entry that are missing in the gateway connection status from the | ||
// latencymap | ||
h.latencyMap.Delete(k) | ||
return true | ||
}) | ||
} | ||
|
||
func copyLatencyMap(latencyMap *sync.Map) sync.Map { | ||
var newMap sync.Map | ||
|
||
latencyMap.Range(func(k, v interface{}) bool { | ||
newMap.Store(k, v) | ||
return true | ||
}) | ||
|
||
return newMap | ||
} | ||
|
||
func (h *HealthChecker) checkRemoteGatewayHealthSafe(remoteHostName string, healthCheckIp string) *LatencyInfo { | ||
var lastRtt time.Duration | ||
pinger, err := ping.NewPinger(healthCheckIp) | ||
if err != nil { | ||
return nil; | ||
} | ||
|
||
pinger.Count = 3 | ||
pinger.SetPrivileged(true) | ||
pinger.OnRecv = func(packet *ping.Packet) { | ||
lastRtt = packet.Rtt | ||
} | ||
var latencyinfo *LatencyInfo | ||
pinger.OnFinish = func(stats *ping.Statistics) { | ||
if (stats.PacketLoss == 100) { | ||
latencySpec := &v1.LatencySpec{ | ||
LastRTT: 0, | ||
MinRTT: 0, | ||
AverageRTT: 0, | ||
MaxRTT: 0, | ||
StdDevRTT: 0, | ||
} | ||
latencyinfo = &LatencyInfo{ | ||
Status: v1.ConnectionError, | ||
Latency: latencySpec, | ||
} | ||
} else { | ||
latencySpec := &v1.LatencySpec{ | ||
LastRTT: float64(lastRtt.Microseconds()) / 1000, | ||
MinRTT: float64(stats.MinRtt.Microseconds()) / 1000, | ||
AverageRTT: float64(stats.AvgRtt.Microseconds()) / 1000, | ||
MaxRTT: float64(stats.MaxRtt.Microseconds()) / 1000, | ||
StdDevRTT: float64(stats.StdDevRtt.Microseconds()) / 1000, | ||
} | ||
latencyinfo = &LatencyInfo{ | ||
Status: v1.Connected, | ||
Latency: latencySpec, | ||
} | ||
} | ||
} | ||
err = pinger.Run() | ||
return latencyinfo | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters