mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-31 00:03:47 +00:00
init
This commit is contained in:
parent
e2f7750125
commit
23fae133f8
4
cmd/k8s-operator/deploy/chart/templates/operator.yaml
Normal file
4
cmd/k8s-operator/deploy/chart/templates/operator.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
- name: OPERATOR_DEFAULT_LOAD_BALANCER
|
||||||
|
value: {{ .Values.defaultLoadBalancer | quote }}
|
||||||
|
- name: PROXY_EPHEMERAL_KEYS
|
||||||
|
value: {{ .Values.ephemeralKeys | quote }}
|
@ -111,3 +111,12 @@ apiServerProxyConfig:
|
|||||||
mode: "false" # "true", "false", "noauth"
|
mode: "false" # "true", "false", "noauth"
|
||||||
|
|
||||||
imagePullSecrets: []
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
# If true, the operator will consider LoadBalancer Services with no
|
||||||
|
# loadBalancerClass field set as Tailscale Services.
|
||||||
|
defaultLoadBalancer: false
|
||||||
|
|
||||||
|
# If true, use ephemeral device authentication keys for all proxies.
|
||||||
|
# Ephemeral devices are automatically deleted from your tailnet when they
|
||||||
|
# disconnect, helping keep your tailnet clean.
|
||||||
|
ephemeralKeys: false
|
||||||
|
@ -76,6 +76,7 @@ func main() {
|
|||||||
tsFirewallMode = defaultEnv("PROXY_FIREWALL_MODE", "")
|
tsFirewallMode = defaultEnv("PROXY_FIREWALL_MODE", "")
|
||||||
defaultProxyClass = defaultEnv("PROXY_DEFAULT_CLASS", "")
|
defaultProxyClass = defaultEnv("PROXY_DEFAULT_CLASS", "")
|
||||||
isDefaultLoadBalancer = defaultBool("OPERATOR_DEFAULT_LOAD_BALANCER", false)
|
isDefaultLoadBalancer = defaultBool("OPERATOR_DEFAULT_LOAD_BALANCER", false)
|
||||||
|
useEphemeralKeys = defaultBool("PROXY_EPHEMERAL_KEYS", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
var opts []kzap.Opts
|
var opts []kzap.Opts
|
||||||
@ -109,7 +110,7 @@ func main() {
|
|||||||
hostinfo.SetApp(kubetypes.AppAPIServerProxy)
|
hostinfo.SetApp(kubetypes.AppAPIServerProxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
s, tsc := initTSNet(zlog)
|
s, tsc := initTSNet(zlog, useEphemeralKeys)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
restConfig := config.GetConfigOrDie()
|
restConfig := config.GetConfigOrDie()
|
||||||
maybeLaunchAPIServerProxy(zlog, restConfig, s, mode)
|
maybeLaunchAPIServerProxy(zlog, restConfig, s, mode)
|
||||||
@ -125,6 +126,7 @@ func main() {
|
|||||||
proxyTags: tags,
|
proxyTags: tags,
|
||||||
proxyFirewallMode: tsFirewallMode,
|
proxyFirewallMode: tsFirewallMode,
|
||||||
defaultProxyClass: defaultProxyClass,
|
defaultProxyClass: defaultProxyClass,
|
||||||
|
proxyUseEphemeralKeys: useEphemeralKeys,
|
||||||
}
|
}
|
||||||
runReconcilers(rOpts)
|
runReconcilers(rOpts)
|
||||||
}
|
}
|
||||||
@ -132,7 +134,7 @@ func main() {
|
|||||||
// initTSNet initializes the tsnet.Server and logs in to Tailscale. It uses the
|
// initTSNet initializes the tsnet.Server and logs in to Tailscale. It uses the
|
||||||
// CLIENT_ID_FILE and CLIENT_SECRET_FILE environment variables to authenticate
|
// CLIENT_ID_FILE and CLIENT_SECRET_FILE environment variables to authenticate
|
||||||
// with Tailscale.
|
// with Tailscale.
|
||||||
func initTSNet(zlog *zap.SugaredLogger) (*tsnet.Server, tsClient) {
|
func initTSNet(zlog *zap.SugaredLogger, useEphemeralKeys bool) (*tsnet.Server, tsClient) {
|
||||||
var (
|
var (
|
||||||
clientIDPath = defaultEnv("CLIENT_ID_FILE", "")
|
clientIDPath = defaultEnv("CLIENT_ID_FILE", "")
|
||||||
clientSecretPath = defaultEnv("CLIENT_SECRET_FILE", "")
|
clientSecretPath = defaultEnv("CLIENT_SECRET_FILE", "")
|
||||||
@ -196,6 +198,7 @@ waitOnline:
|
|||||||
Create: tailscale.KeyDeviceCreateCapabilities{
|
Create: tailscale.KeyDeviceCreateCapabilities{
|
||||||
Reusable: false,
|
Reusable: false,
|
||||||
Preauthorized: true,
|
Preauthorized: true,
|
||||||
|
Ephemeral: useEphemeralKeys,
|
||||||
Tags: strings.Split(operatorTags, ","),
|
Tags: strings.Split(operatorTags, ","),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -288,6 +291,7 @@ func runReconcilers(opts reconcilerOpts) {
|
|||||||
proxyImage: opts.proxyImage,
|
proxyImage: opts.proxyImage,
|
||||||
proxyPriorityClassName: opts.proxyPriorityClassName,
|
proxyPriorityClassName: opts.proxyPriorityClassName,
|
||||||
tsFirewallMode: opts.proxyFirewallMode,
|
tsFirewallMode: opts.proxyFirewallMode,
|
||||||
|
proxyUseEphemeralKeys: opts.proxyUseEphemeralKeys,
|
||||||
}
|
}
|
||||||
err = builder.
|
err = builder.
|
||||||
ControllerManagedBy(mgr).
|
ControllerManagedBy(mgr).
|
||||||
@ -542,12 +546,13 @@ func runReconcilers(opts reconcilerOpts) {
|
|||||||
Watches(&rbacv1.Role{}, recorderFilter).
|
Watches(&rbacv1.Role{}, recorderFilter).
|
||||||
Watches(&rbacv1.RoleBinding{}, recorderFilter).
|
Watches(&rbacv1.RoleBinding{}, recorderFilter).
|
||||||
Complete(&RecorderReconciler{
|
Complete(&RecorderReconciler{
|
||||||
recorder: eventRecorder,
|
recorder: eventRecorder,
|
||||||
tsNamespace: opts.tailscaleNamespace,
|
tsNamespace: opts.tailscaleNamespace,
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
l: opts.log.Named("recorder-reconciler"),
|
l: opts.log.Named("recorder-reconciler"),
|
||||||
clock: tstime.DefaultClock{},
|
clock: tstime.DefaultClock{},
|
||||||
tsClient: opts.tsClient,
|
tsClient: opts.tsClient,
|
||||||
|
proxyUseEphemeralKeys: opts.proxyUseEphemeralKeys,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create Recorder reconciler: %v", err)
|
startlog.Fatalf("could not create Recorder reconciler: %v", err)
|
||||||
@ -573,11 +578,12 @@ func runReconcilers(opts reconcilerOpts) {
|
|||||||
clock: tstime.DefaultClock{},
|
clock: tstime.DefaultClock{},
|
||||||
tsClient: opts.tsClient,
|
tsClient: opts.tsClient,
|
||||||
|
|
||||||
tsNamespace: opts.tailscaleNamespace,
|
tsNamespace: opts.tailscaleNamespace,
|
||||||
proxyImage: opts.proxyImage,
|
proxyImage: opts.proxyImage,
|
||||||
defaultTags: strings.Split(opts.proxyTags, ","),
|
defaultTags: strings.Split(opts.proxyTags, ","),
|
||||||
tsFirewallMode: opts.proxyFirewallMode,
|
tsFirewallMode: opts.proxyFirewallMode,
|
||||||
defaultProxyClass: opts.defaultProxyClass,
|
defaultProxyClass: opts.defaultProxyClass,
|
||||||
|
proxyUseEphemeralKeys: opts.proxyUseEphemeralKeys,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create ProxyGroup reconciler: %v", err)
|
startlog.Fatalf("could not create ProxyGroup reconciler: %v", err)
|
||||||
@ -627,9 +633,10 @@ type reconcilerOpts struct {
|
|||||||
// class for proxies that do not have a ProxyClass set.
|
// class for proxies that do not have a ProxyClass set.
|
||||||
// this is defined by an operator env variable.
|
// this is defined by an operator env variable.
|
||||||
defaultProxyClass string
|
defaultProxyClass string
|
||||||
|
proxyUseEphemeralKeys bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// enqueueAllIngressEgressProxySvcsinNS returns a reconcile request for each
|
// enqueueAllIngressEgressProxySvcsInNS returns a reconcile request for each
|
||||||
// ingress/egress proxy headless Service found in the provided namespace.
|
// ingress/egress proxy headless Service found in the provided namespace.
|
||||||
func enqueueAllIngressEgressProxySvcsInNS(ns string, cl client.Client, logger *zap.SugaredLogger) handler.MapFunc {
|
func enqueueAllIngressEgressProxySvcsInNS(ns string, cl client.Client, logger *zap.SugaredLogger) handler.MapFunc {
|
||||||
return func(ctx context.Context, _ client.Object) []reconcile.Request {
|
return func(ctx context.Context, _ client.Object) []reconcile.Request {
|
||||||
|
@ -66,11 +66,12 @@ type ProxyGroupReconciler struct {
|
|||||||
tsClient tsClient
|
tsClient tsClient
|
||||||
|
|
||||||
// User-specified defaults from the helm installation.
|
// User-specified defaults from the helm installation.
|
||||||
tsNamespace string
|
tsNamespace string
|
||||||
proxyImage string
|
proxyImage string
|
||||||
defaultTags []string
|
defaultTags []string
|
||||||
tsFirewallMode string
|
tsFirewallMode string
|
||||||
defaultProxyClass string
|
defaultProxyClass string
|
||||||
|
proxyUseEphemeralKeys bool
|
||||||
|
|
||||||
mu sync.Mutex // protects following
|
mu sync.Mutex // protects following
|
||||||
egressProxyGroups set.Slice[types.UID] // for egress proxygroups gauge
|
egressProxyGroups set.Slice[types.UID] // for egress proxygroups gauge
|
||||||
@ -477,7 +478,7 @@ func (r *ProxyGroupReconciler) ensureConfigSecretsCreated(ctx context.Context, p
|
|||||||
if len(tags) == 0 {
|
if len(tags) == 0 {
|
||||||
tags = r.defaultTags
|
tags = r.defaultTags
|
||||||
}
|
}
|
||||||
authKey, err = newAuthKey(ctx, r.tsClient, tags)
|
authKey, err = newAuthKey(ctx, r.tsClient, tags, r.proxyUseEphemeralKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -165,6 +165,7 @@ type tailscaleSTSReconciler struct {
|
|||||||
proxyImage string
|
proxyImage string
|
||||||
proxyPriorityClassName string
|
proxyPriorityClassName string
|
||||||
tsFirewallMode string
|
tsFirewallMode string
|
||||||
|
proxyUseEphemeralKeys bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sts tailscaleSTSReconciler) validate() error {
|
func (sts tailscaleSTSReconciler) validate() error {
|
||||||
@ -376,7 +377,7 @@ func (a *tailscaleSTSReconciler) createOrGetSecret(ctx context.Context, logger *
|
|||||||
if len(tags) == 0 {
|
if len(tags) == 0 {
|
||||||
tags = a.defaultTags
|
tags = a.defaultTags
|
||||||
}
|
}
|
||||||
authKey, err = newAuthKey(ctx, a.tsClient, tags)
|
authKey, err = newAuthKey(ctx, a.tsClient, tags, a.proxyUseEphemeralKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", nil, err
|
return "", "", nil, err
|
||||||
}
|
}
|
||||||
@ -511,12 +512,13 @@ func deviceInfo(sec *corev1.Secret, podUID string, log *zap.SugaredLogger) (dev
|
|||||||
return dev, nil
|
return dev, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAuthKey(ctx context.Context, tsClient tsClient, tags []string) (string, error) {
|
func newAuthKey(ctx context.Context, tsClient tsClient, tags []string, ephemeral bool) (string, error) {
|
||||||
caps := tailscale.KeyCapabilities{
|
caps := tailscale.KeyCapabilities{
|
||||||
Devices: tailscale.KeyDeviceCapabilities{
|
Devices: tailscale.KeyDeviceCapabilities{
|
||||||
Create: tailscale.KeyDeviceCreateCapabilities{
|
Create: tailscale.KeyDeviceCreateCapabilities{
|
||||||
Reusable: false,
|
Reusable: false,
|
||||||
Preauthorized: true,
|
Preauthorized: true,
|
||||||
|
Ephemeral: ephemeral,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -57,6 +57,7 @@ type RecorderReconciler struct {
|
|||||||
clock tstime.Clock
|
clock tstime.Clock
|
||||||
tsNamespace string
|
tsNamespace string
|
||||||
tsClient tsClient
|
tsClient tsClient
|
||||||
|
proxyUseEphemeralKeys bool
|
||||||
|
|
||||||
mu sync.Mutex // protects following
|
mu sync.Mutex // protects following
|
||||||
recorders set.Slice[types.UID] // for recorders gauge
|
recorders set.Slice[types.UID] // for recorders gauge
|
||||||
@ -289,7 +290,7 @@ func (r *RecorderReconciler) ensureAuthSecretCreated(ctx context.Context, tsr *t
|
|||||||
if len(tags) == 0 {
|
if len(tags) == 0 {
|
||||||
tags = tsapi.Tags{"tag:k8s"}
|
tags = tsapi.Tags{"tag:k8s"}
|
||||||
}
|
}
|
||||||
authKey, err := newAuthKey(ctx, r.tsClient, tags.Stringify())
|
authKey, err := newAuthKey(ctx, r.tsClient, tags.Stringify(), r.proxyUseEphemeralKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user