mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
cmd/k8s-operator: cleanup runReconciler signature (#11993)
Updates#cleanup Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit is contained in:
parent
35872e86d2
commit
406293682c
@ -38,10 +38,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
repoRoot := "../../"
|
repoRoot := "../../"
|
||||||
switch os.Args[1] {
|
switch os.Args[1] {
|
||||||
case "helmcrd": // insert CRD to Helm templates behind a installCRDs=true conditional check
|
case "helmcrd": // insert CRDs to Helm templates behind a installCRDs=true conditional check
|
||||||
log.Print("Adding Connector CRD to Helm templates")
|
log.Print("Adding CRDs to Helm templates")
|
||||||
if err := generate("./"); err != nil {
|
if err := generate("./"); err != nil {
|
||||||
log.Fatalf("error adding Connector CRD to Helm templates: %v", err)
|
log.Fatalf("error adding CRDs to Helm templates: %v", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case "staticmanifests": // generate static manifests from Helm templates (including the CRD)
|
case "staticmanifests": // generate static manifests from Helm templates (including the CRD)
|
||||||
|
@ -60,12 +60,13 @@ func main() {
|
|||||||
tailscale.I_Acknowledge_This_API_Is_Unstable = true
|
tailscale.I_Acknowledge_This_API_Is_Unstable = true
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tsNamespace = defaultEnv("OPERATOR_NAMESPACE", "")
|
tsNamespace = defaultEnv("OPERATOR_NAMESPACE", "")
|
||||||
tslogging = defaultEnv("OPERATOR_LOGGING", "info")
|
tslogging = defaultEnv("OPERATOR_LOGGING", "info")
|
||||||
image = defaultEnv("PROXY_IMAGE", "tailscale/tailscale:latest")
|
image = defaultEnv("PROXY_IMAGE", "tailscale/tailscale:latest")
|
||||||
priorityClassName = defaultEnv("PROXY_PRIORITY_CLASS_NAME", "")
|
priorityClassName = defaultEnv("PROXY_PRIORITY_CLASS_NAME", "")
|
||||||
tags = defaultEnv("PROXY_TAGS", "tag:k8s")
|
tags = defaultEnv("PROXY_TAGS", "tag:k8s")
|
||||||
tsFirewallMode = defaultEnv("PROXY_FIREWALL_MODE", "")
|
tsFirewallMode = defaultEnv("PROXY_FIREWALL_MODE", "")
|
||||||
|
isDefaultLoadBalancer = defaultBool("OPERATOR_DEFAULT_LOAD_BALANCER", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
var opts []kzap.Opts
|
var opts []kzap.Opts
|
||||||
@ -94,9 +95,19 @@ func main() {
|
|||||||
defer s.Close()
|
defer s.Close()
|
||||||
restConfig := config.GetConfigOrDie()
|
restConfig := config.GetConfigOrDie()
|
||||||
maybeLaunchAPIServerProxy(zlog, restConfig, s, mode)
|
maybeLaunchAPIServerProxy(zlog, restConfig, s, mode)
|
||||||
// TODO (irbekrm): gather the reconciler options into an opts struct
|
rOpts := reconcilerOpts{
|
||||||
// rather than passing a million of them in one by one.
|
log: zlog,
|
||||||
runReconcilers(zlog, s, tsNamespace, restConfig, tsClient, image, priorityClassName, tags, tsFirewallMode)
|
tsServer: s,
|
||||||
|
tsClient: tsClient,
|
||||||
|
tailscaleNamespace: tsNamespace,
|
||||||
|
restConfig: restConfig,
|
||||||
|
proxyImage: image,
|
||||||
|
proxyPriorityClassName: priorityClassName,
|
||||||
|
proxyActAsDefaultLoadBalancer: isDefaultLoadBalancer,
|
||||||
|
proxyTags: tags,
|
||||||
|
proxyFirewallMode: tsFirewallMode,
|
||||||
|
}
|
||||||
|
runReconcilers(rOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@ -204,11 +215,8 @@ waitOnline:
|
|||||||
|
|
||||||
// runReconcilers starts the controller-runtime manager and registers the
|
// runReconcilers starts the controller-runtime manager and registers the
|
||||||
// ServiceReconciler. It blocks forever.
|
// ServiceReconciler. It blocks forever.
|
||||||
func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string, restConfig *rest.Config, tsClient *tailscale.Client, image, priorityClassName, tags, tsFirewallMode string) {
|
func runReconcilers(opts reconcilerOpts) {
|
||||||
var (
|
startlog := opts.log.Named("startReconcilers")
|
||||||
isDefaultLoadBalancer = defaultBool("OPERATOR_DEFAULT_LOAD_BALANCER", false)
|
|
||||||
)
|
|
||||||
startlog := zlog.Named("startReconcilers")
|
|
||||||
// For secrets and statefulsets, we only get permission to touch the objects
|
// For secrets and statefulsets, we only get permission to touch the objects
|
||||||
// in the controller's own namespace. This cannot be expressed by
|
// in the controller's own namespace. This cannot be expressed by
|
||||||
// .Watches(...) below, instead you have to add a per-type field selector to
|
// .Watches(...) below, instead you have to add a per-type field selector to
|
||||||
@ -216,7 +224,7 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
// implicitly filter what parts of the world the builder code gets to see at
|
// implicitly filter what parts of the world the builder code gets to see at
|
||||||
// all.
|
// all.
|
||||||
nsFilter := cache.ByObject{
|
nsFilter := cache.ByObject{
|
||||||
Field: client.InNamespace(tsNamespace).AsSelector(),
|
Field: client.InNamespace(opts.tailscaleNamespace).AsSelector(),
|
||||||
}
|
}
|
||||||
mgrOpts := manager.Options{
|
mgrOpts := manager.Options{
|
||||||
// TODO (irbekrm): stricter filtering what we watch/cache/call
|
// TODO (irbekrm): stricter filtering what we watch/cache/call
|
||||||
@ -234,7 +242,7 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
},
|
},
|
||||||
Scheme: tsapi.GlobalScheme,
|
Scheme: tsapi.GlobalScheme,
|
||||||
}
|
}
|
||||||
mgr, err := manager.New(restConfig, mgrOpts)
|
mgr, err := manager.New(opts.restConfig, mgrOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create manager: %v", err)
|
startlog.Fatalf("could not create manager: %v", err)
|
||||||
}
|
}
|
||||||
@ -248,13 +256,13 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
eventRecorder := mgr.GetEventRecorderFor("tailscale-operator")
|
eventRecorder := mgr.GetEventRecorderFor("tailscale-operator")
|
||||||
ssr := &tailscaleSTSReconciler{
|
ssr := &tailscaleSTSReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
tsnetServer: s,
|
tsnetServer: opts.tsServer,
|
||||||
tsClient: tsClient,
|
tsClient: opts.tsClient,
|
||||||
defaultTags: strings.Split(tags, ","),
|
defaultTags: strings.Split(opts.proxyTags, ","),
|
||||||
operatorNamespace: tsNamespace,
|
operatorNamespace: opts.tailscaleNamespace,
|
||||||
proxyImage: image,
|
proxyImage: opts.proxyImage,
|
||||||
proxyPriorityClassName: priorityClassName,
|
proxyPriorityClassName: opts.proxyPriorityClassName,
|
||||||
tsFirewallMode: tsFirewallMode,
|
tsFirewallMode: opts.proxyFirewallMode,
|
||||||
}
|
}
|
||||||
err = builder.
|
err = builder.
|
||||||
ControllerManagedBy(mgr).
|
ControllerManagedBy(mgr).
|
||||||
@ -266,10 +274,10 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
Complete(&ServiceReconciler{
|
Complete(&ServiceReconciler{
|
||||||
ssr: ssr,
|
ssr: ssr,
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
logger: zlog.Named("service-reconciler"),
|
logger: opts.log.Named("service-reconciler"),
|
||||||
isDefaultLoadBalancer: isDefaultLoadBalancer,
|
isDefaultLoadBalancer: opts.proxyActAsDefaultLoadBalancer,
|
||||||
recorder: eventRecorder,
|
recorder: eventRecorder,
|
||||||
tsNamespace: tsNamespace,
|
tsNamespace: opts.tailscaleNamespace,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create service reconciler: %v", err)
|
startlog.Fatalf("could not create service reconciler: %v", err)
|
||||||
@ -291,7 +299,7 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
ssr: ssr,
|
ssr: ssr,
|
||||||
recorder: eventRecorder,
|
recorder: eventRecorder,
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
logger: zlog.Named("ingress-reconciler"),
|
logger: opts.log.Named("ingress-reconciler"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create ingress reconciler: %v", err)
|
startlog.Fatalf("could not create ingress reconciler: %v", err)
|
||||||
@ -310,14 +318,14 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
ssr: ssr,
|
ssr: ssr,
|
||||||
recorder: eventRecorder,
|
recorder: eventRecorder,
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
logger: zlog.Named("connector-reconciler"),
|
logger: opts.log.Named("connector-reconciler"),
|
||||||
clock: tstime.DefaultClock{},
|
clock: tstime.DefaultClock{},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create connector reconciler: %v", err)
|
startlog.Fatalf("could not create connector reconciler: %v", err)
|
||||||
}
|
}
|
||||||
// TODO (irbekrm): switch to metadata-only watches for resources whose
|
// TODO (irbekrm): switch to metadata-only watches for resources whose
|
||||||
// spec we don't need to inspect to reduce memory consumption
|
// spec we don't need to inspect to reduce memory consumption.
|
||||||
// https://github.com/kubernetes-sigs/controller-runtime/issues/1159
|
// https://github.com/kubernetes-sigs/controller-runtime/issues/1159
|
||||||
nameserverFilter := handler.EnqueueRequestsFromMapFunc(managedResourceHandlerForType("nameserver"))
|
nameserverFilter := handler.EnqueueRequestsFromMapFunc(managedResourceHandlerForType("nameserver"))
|
||||||
err = builder.ControllerManagedBy(mgr).
|
err = builder.ControllerManagedBy(mgr).
|
||||||
@ -328,11 +336,10 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
Watches(&corev1.ServiceAccount{}, nameserverFilter).
|
Watches(&corev1.ServiceAccount{}, nameserverFilter).
|
||||||
Complete(&NameserverReconciler{
|
Complete(&NameserverReconciler{
|
||||||
recorder: eventRecorder,
|
recorder: eventRecorder,
|
||||||
tsNamespace: tsNamespace,
|
tsNamespace: opts.tailscaleNamespace,
|
||||||
|
Client: mgr.GetClient(),
|
||||||
Client: mgr.GetClient(),
|
logger: opts.log.Named("nameserver-reconciler"),
|
||||||
logger: zlog.Named("nameserver-reconciler"),
|
clock: tstime.DefaultClock{},
|
||||||
clock: tstime.DefaultClock{},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create nameserver reconciler: %v", err)
|
startlog.Fatalf("could not create nameserver reconciler: %v", err)
|
||||||
@ -342,7 +349,7 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
Complete(&ProxyClassReconciler{
|
Complete(&ProxyClassReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
recorder: eventRecorder,
|
recorder: eventRecorder,
|
||||||
logger: zlog.Named("proxyclass-reconciler"),
|
logger: opts.log.Named("proxyclass-reconciler"),
|
||||||
clock: tstime.DefaultClock{},
|
clock: tstime.DefaultClock{},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -355,12 +362,12 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
dnsRREpsOpts := handler.EnqueueRequestsFromMapFunc(dnsRecordsReconcilerEndpointSliceHandler)
|
dnsRREpsOpts := handler.EnqueueRequestsFromMapFunc(dnsRecordsReconcilerEndpointSliceHandler)
|
||||||
// On DNSConfig changes, reconcile all headless Services for
|
// On DNSConfig changes, reconcile all headless Services for
|
||||||
// ingress/egress proxies in operator namespace.
|
// ingress/egress proxies in operator namespace.
|
||||||
dnsRRDNSConfigOpts := handler.EnqueueRequestsFromMapFunc(enqueueAllIngressEgressProxySvcsInNS(tsNamespace, mgr.GetClient(), logger))
|
dnsRRDNSConfigOpts := handler.EnqueueRequestsFromMapFunc(enqueueAllIngressEgressProxySvcsInNS(opts.tailscaleNamespace, mgr.GetClient(), logger))
|
||||||
// On Service events, if it is an ingress/egress proxy headless Service, reconcile it.
|
// On Service events, if it is an ingress/egress proxy headless Service, reconcile it.
|
||||||
dnsRRServiceOpts := handler.EnqueueRequestsFromMapFunc(dnsRecordsReconcilerServiceHandler)
|
dnsRRServiceOpts := handler.EnqueueRequestsFromMapFunc(dnsRecordsReconcilerServiceHandler)
|
||||||
// On Ingress events, if it is a tailscale Ingress or if tailscale is the default ingress controller, reconcile the proxy
|
// On Ingress events, if it is a tailscale Ingress or if tailscale is the default ingress controller, reconcile the proxy
|
||||||
// headless Service.
|
// headless Service.
|
||||||
dnsRRIngressOpts := handler.EnqueueRequestsFromMapFunc(dnsRecordsReconcilerIngressHandler(tsNamespace, isDefaultLoadBalancer, mgr.GetClient(), logger))
|
dnsRRIngressOpts := handler.EnqueueRequestsFromMapFunc(dnsRecordsReconcilerIngressHandler(opts.tailscaleNamespace, opts.proxyActAsDefaultLoadBalancer, mgr.GetClient(), logger))
|
||||||
err = builder.ControllerManagedBy(mgr).
|
err = builder.ControllerManagedBy(mgr).
|
||||||
Named("dns-records-reconciler").
|
Named("dns-records-reconciler").
|
||||||
Watches(&corev1.Service{}, dnsRRServiceOpts).
|
Watches(&corev1.Service{}, dnsRRServiceOpts).
|
||||||
@ -369,9 +376,9 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
Watches(&tsapi.DNSConfig{}, dnsRRDNSConfigOpts).
|
Watches(&tsapi.DNSConfig{}, dnsRRDNSConfigOpts).
|
||||||
Complete(&dnsRecordsReconciler{
|
Complete(&dnsRecordsReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
tsNamespace: tsNamespace,
|
tsNamespace: opts.tailscaleNamespace,
|
||||||
logger: zlog.Named("dns-records-reconciler"),
|
logger: opts.log.Named("dns-records-reconciler"),
|
||||||
isDefaultLoadBalancer: isDefaultLoadBalancer,
|
isDefaultLoadBalancer: opts.proxyActAsDefaultLoadBalancer,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
startlog.Fatalf("could not create DNS records reconciler: %v", err)
|
startlog.Fatalf("could not create DNS records reconciler: %v", err)
|
||||||
@ -382,6 +389,42 @@ func runReconcilers(zlog *zap.SugaredLogger, s *tsnet.Server, tsNamespace string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type reconcilerOpts struct {
|
||||||
|
log *zap.SugaredLogger
|
||||||
|
tsServer *tsnet.Server
|
||||||
|
tsClient *tailscale.Client
|
||||||
|
tailscaleNamespace string // namespace in which operator resources will be deployed
|
||||||
|
restConfig *rest.Config // config for connecting to the kube API server
|
||||||
|
proxyImage string // <proxy-image-repo>:<proxy-image-tag>
|
||||||
|
// proxyPriorityClassName isPriorityClass to be set for proxy Pods. This
|
||||||
|
// is a legacy mechanism for cluster resource configuration options -
|
||||||
|
// going forward use ProxyClass.
|
||||||
|
// https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass
|
||||||
|
proxyPriorityClassName string
|
||||||
|
// proxyTags are ACL tags to tag proxy auth keys. Multiple tags should
|
||||||
|
// be provided as a string with comma-separated tag values. Proxy tags
|
||||||
|
// default to tag:k8s.
|
||||||
|
// https://tailscale.com/kb/1085/auth-keys
|
||||||
|
proxyTags string
|
||||||
|
// proxyActAsDefaultLoadBalancer determines whether this operator
|
||||||
|
// instance should act as the default ingress controller when looking at
|
||||||
|
// Ingress resources with unset ingress.spec.ingressClassName.
|
||||||
|
// TODO (irbekrm): this setting does not respect the default
|
||||||
|
// IngressClass.
|
||||||
|
// https://kubernetes.io/docs/concepts/services-networking/ingress/#default-ingress-class
|
||||||
|
// We should fix that and preferably integrate with that mechanism as
|
||||||
|
// well - perhaps make the operator itself create the default
|
||||||
|
// IngressClass if this is set to true.
|
||||||
|
proxyActAsDefaultLoadBalancer bool
|
||||||
|
// proxyFirewallMode determines whether non-userspace proxies should use
|
||||||
|
// iptables or nftables for firewall configuration. Accepted values are
|
||||||
|
// iptables, nftables and auto. If set to auto, proxy will automatically
|
||||||
|
// determine which mode is supported for a given host (prefer nftables).
|
||||||
|
// Auto is usually the best choice, unless you want to explicitly set
|
||||||
|
// specific mode for debugging purposes.
|
||||||
|
proxyFirewallMode string
|
||||||
|
}
|
||||||
|
|
||||||
// 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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user