cmd/k8s-operator,kube/kubetypes,k8s-operator/apis: reconcile L3 HA Services (#15961)

This reconciler allows users to make applications highly available at L3 by
leveraging Tailscale Virtual Services. Many Kubernetes Service's
(irrespective of the cluster they reside in) can be mapped to a
Tailscale Virtual Service, allowing access to these Services at L3.

Updates #15895

Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
This commit is contained in:
Tom Meadows
2025-05-19 12:58:32 +01:00
committed by GitHub
parent d89aa29081
commit df8d51023e
13 changed files with 1431 additions and 21 deletions

View File

@@ -10,6 +10,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math/rand/v2"
"net/http"
"reflect"
"slices"
@@ -17,8 +18,6 @@ import (
"sync"
"time"
"math/rand/v2"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
@@ -59,6 +58,7 @@ const (
"Please contact Tailscale support through https://tailscale.com/contact/support to enable the feature flag, then recreate the operator's Pod."
warningTailscaleServiceFeatureFlagNotEnabled = "TailscaleServiceFeatureFlagNotEnabled"
managedTSServiceComment = "This Tailscale Service is managed by the Tailscale Kubernetes Operator, do not modify"
)
var gaugePGIngressResources = clientmetric.NewGauge(kubetypes.MetricIngressPGResourceCount)
@@ -323,7 +323,6 @@ func (r *HAIngressReconciler) maybeProvision(ctx context.Context, hostname strin
tsSvcPorts = append(tsSvcPorts, "80")
}
const managedTSServiceComment = "This Tailscale Service is managed by the Tailscale Kubernetes Operator, do not modify"
tsSvc := &tailscale.VIPService{
Name: serviceName,
Tags: tags,
@@ -532,9 +531,7 @@ func (r *HAIngressReconciler) maybeCleanup(ctx context.Context, hostname string,
if err != nil {
return
}
if e := r.deleteFinalizer(ctx, ing, logger); err != nil {
err = errors.Join(err, e)
}
err = r.deleteFinalizer(ctx, ing, logger)
}()
// 1. Check if there is a Tailscale Service associated with this Ingress.
@@ -766,7 +763,6 @@ const (
)
func (a *HAIngressReconciler) maybeUpdateAdvertiseServicesConfig(ctx context.Context, pgName string, serviceName tailcfg.ServiceName, mode serviceAdvertisementMode, logger *zap.SugaredLogger) (err error) {
// Get all config Secrets for this ProxyGroup.
secrets := &corev1.SecretList{}
if err := a.List(ctx, secrets, client.InNamespace(a.tsNamespace), client.MatchingLabels(pgSecretLabels(pgName, "config"))); err != nil {
@@ -1091,7 +1087,6 @@ func (r *HAIngressReconciler) hasCerts(ctx context.Context, svc tailcfg.ServiceN
Namespace: r.tsNamespace,
Name: domain,
}, secret)
if err != nil {
if apierrors.IsNotFound(err) {
return false, nil