mirror of
https://github.com/tailscale/tailscale.git
synced 2026-06-03 21:01:54 +08:00
Some checks failed
checklocks / checklocks (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
Dockerfile build / deploy (push) Has been cancelled
CI / gomod-cache (push) Has been cancelled
CI / fuzz (push) Has been cancelled
update-flake / update-flake (push) Has been cancelled
tailscale.com/cmd/vet / vet (push) Has been cancelled
CI / race-root-integration (1/4) (push) Has been cancelled
CI / race-root-integration (2/4) (push) Has been cancelled
CI / race-root-integration (3/4) (push) Has been cancelled
CI / race-root-integration (4/4) (push) Has been cancelled
CI / test (-race, amd64, 1/3) (push) Has been cancelled
CI / test (-race, amd64, 2/3) (push) Has been cancelled
CI / test (-race, amd64, 3/3) (push) Has been cancelled
CI / test (386) (push) Has been cancelled
CI / test (amd64) (push) Has been cancelled
CI / Windows (${{ matrix.name || matrix.shard}}) (win-bench, benchmarks) (push) Has been cancelled
CI / Windows (${{ matrix.name || matrix.shard}}) (win-shard-1-2, 1/2) (push) Has been cancelled
CI / Windows (${{ matrix.name || matrix.shard}}) (win-shard-2-2, 2/2) (push) Has been cancelled
CI / Windows (win-tool-go) (push) Has been cancelled
CI / macos (push) Has been cancelled
CI / privileged (push) Has been cancelled
CI / vm (push) Has been cancelled
CI / cross (386, linux) (push) Has been cancelled
CI / cross (amd64, darwin) (push) Has been cancelled
CI / cross (amd64, freebsd) (push) Has been cancelled
CI / cross (amd64, openbsd) (push) Has been cancelled
CI / cross (amd64, windows) (push) Has been cancelled
CI / cross (arm, 5, linux) (push) Has been cancelled
CI / cross (arm, 7, linux) (push) Has been cancelled
CI / cross (arm64, darwin) (push) Has been cancelled
CI / cross (arm64, linux) (push) Has been cancelled
CI / cross (arm64, windows) (push) Has been cancelled
CI / cross (loong64, linux) (push) Has been cancelled
CI / ios (push) Has been cancelled
CI / crossmin (amd64, illumos) (push) Has been cancelled
CI / crossmin (amd64, plan9) (push) Has been cancelled
CI / crossmin (amd64, solaris) (push) Has been cancelled
CI / crossmin (ppc64, aix) (push) Has been cancelled
CI / android (push) Has been cancelled
CI / wasm (push) Has been cancelled
CI / tailscale_go (push) Has been cancelled
CI / depaware (push) Has been cancelled
CI / go_generate (push) Has been cancelled
CI / go_mod_tidy (push) Has been cancelled
CI / licenses (push) Has been cancelled
CI / staticcheck (${{ matrix.name }}) (--with-tags-all=darwin, arm64, darwin, macOS) (push) Has been cancelled
CI / staticcheck (${{ matrix.name }}) (--with-tags-all=linux, amd64, linux, Linux) (push) Has been cancelled
CI / staticcheck (${{ matrix.name }}) (--with-tags-all=windows, amd64, windows, Windows) (push) Has been cancelled
CI / staticcheck (${{ matrix.name }}) (--without-tags-any=windows,darwin,linux --shard=1/4, amd64, linux, Portable (1/4)) (push) Has been cancelled
CI / staticcheck (${{ matrix.name }}) (--without-tags-any=windows,darwin,linux --shard=2/4, amd64, linux, Portable (2/4)) (push) Has been cancelled
CI / staticcheck (${{ matrix.name }}) (--without-tags-any=windows,darwin,linux --shard=3/4, amd64, linux, Portable (3/4)) (push) Has been cancelled
CI / staticcheck (${{ matrix.name }}) (--without-tags-any=windows,darwin,linux --shard=4/4, amd64, linux, Portable (4/4)) (push) Has been cancelled
CI / notify_slack (push) Has been cancelled
CI / merge_blocker (push) Has been cancelled
CI / check_mergeability_strict (push) Has been cancelled
CI / check_mergeability (push) Has been cancelled
* cmd/containerboot,kube/services: support the ability to automatically advertise services on startup Updates #17769 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk> * cmd/containerboot: don't assume we want to use kube state store if in kubernetes Fixes #8188 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk> --------- Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
101 lines
3.7 KiB
Go
101 lines
3.7 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
// Package services manages graceful shutdown of Tailscale Services advertised
|
|
// by Kubernetes clients.
|
|
package services
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"tailscale.com/client/local"
|
|
"tailscale.com/ipn"
|
|
"tailscale.com/kube/localclient"
|
|
"tailscale.com/types/logger"
|
|
)
|
|
|
|
// EnsureServicesAdvertised is a function that gets called on containerboot
|
|
// startup and ensures that Services get advertised if they exist.
|
|
func EnsureServicesAdvertised(ctx context.Context, services []string, lc localclient.LocalClient, logf logger.Logf) error {
|
|
if _, err := lc.EditPrefs(ctx, &ipn.MaskedPrefs{
|
|
AdvertiseServicesSet: true,
|
|
Prefs: ipn.Prefs{
|
|
AdvertiseServices: services,
|
|
},
|
|
}); err != nil {
|
|
// EditPrefs only returns an error if it fails _set_ its local prefs.
|
|
// If it fails to _persist_ the prefs in state, we don't get an error
|
|
// and we continue waiting below, as control will failover as usual.
|
|
return fmt.Errorf("error setting prefs AdvertiseServices: %w", err)
|
|
}
|
|
|
|
// Services use the same (failover XOR regional routing) mechanism that
|
|
// HA subnet routers use. Unfortunately we don't yet get a reliable signal
|
|
// from control that it's responded to our unadvertisement, so the best we
|
|
// can do is wait for 20 seconds, where 15s is the approximate maximum time
|
|
// it should take for control to choose a new primary, and 5s is for buffer.
|
|
//
|
|
// Note: There is no guarantee that clients have been _informed_ of the new
|
|
// primary no matter how long we wait. We would need a mechanism to await
|
|
// netmap updates for peers to know for sure.
|
|
//
|
|
// See https://tailscale.com/kb/1115/high-availability for more details.
|
|
// TODO(tomhjp): Wait for a netmap update instead of sleeping when control
|
|
// supports that.
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil
|
|
case <-time.After(20 * time.Second):
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// EnsureServicesNotAdvertised is a function that gets called on containerboot
|
|
// or k8s-proxy termination and ensures that any currently advertised Services
|
|
// get unadvertised to give clients time to switch to another node before this
|
|
// one is shut down.
|
|
func EnsureServicesNotAdvertised(ctx context.Context, lc *local.Client, logf logger.Logf) error {
|
|
prefs, err := lc.GetPrefs(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("error getting prefs: %w", err)
|
|
}
|
|
if len(prefs.AdvertiseServices) == 0 {
|
|
return nil
|
|
}
|
|
|
|
logf("unadvertising services: %v", prefs.AdvertiseServices)
|
|
if _, err := lc.EditPrefs(ctx, &ipn.MaskedPrefs{
|
|
AdvertiseServicesSet: true,
|
|
Prefs: ipn.Prefs{
|
|
AdvertiseServices: nil,
|
|
},
|
|
}); err != nil {
|
|
// EditPrefs only returns an error if it fails _set_ its local prefs.
|
|
// If it fails to _persist_ the prefs in state, we don't get an error
|
|
// and we continue waiting below, as control will failover as usual.
|
|
return fmt.Errorf("error setting prefs AdvertiseServices: %w", err)
|
|
}
|
|
|
|
// Services use the same (failover XOR regional routing) mechanism that
|
|
// HA subnet routers use. Unfortunately we don't yet get a reliable signal
|
|
// from control that it's responded to our unadvertisement, so the best we
|
|
// can do is wait for 20 seconds, where 15s is the approximate maximum time
|
|
// it should take for control to choose a new primary, and 5s is for buffer.
|
|
//
|
|
// Note: There is no guarantee that clients have been _informed_ of the new
|
|
// primary no matter how long we wait. We would need a mechanism to await
|
|
// netmap updates for peers to know for sure.
|
|
//
|
|
// See https://tailscale.com/kb/1115/high-availability for more details.
|
|
// TODO(tomhjp): Wait for a netmap update instead of sleeping when control
|
|
// supports that.
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil
|
|
case <-time.After(20 * time.Second):
|
|
return nil
|
|
}
|
|
}
|