1 package controllers
2
3 import (
4 "flag"
5 "net/http"
6 "net/http/pprof"
7 "os"
8
9 certmgr "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
10 serverv1beta1 "github.com/linkerd/linkerd2/controller/gen/apis/server/v1beta1"
11 serverauthv1beta1 "github.com/linkerd/linkerd2/controller/gen/apis/serverauthorization/v1beta1"
12 "github.com/peterbourgon/ff/v3"
13 "k8s.io/apimachinery/pkg/runtime"
14 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
15 clientgoscheme "k8s.io/client-go/kubernetes/scheme"
16 ctrl "sigs.k8s.io/controller-runtime"
17
18 v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
19
20 "edge-infra.dev/pkg/edge/component/build"
21 "edge-infra.dev/pkg/edge/linkerd"
22 l5dv1alpha1 "edge-infra.dev/pkg/edge/linkerd/k8s/apis/linkerd/v1alpha1"
23 l5dmetrics "edge-infra.dev/pkg/edge/linkerd/k8s/controllers/metrics"
24 "edge-infra.dev/pkg/k8s/runtime/controller"
25 "edge-infra.dev/pkg/k8s/runtime/controller/metrics"
26 "edge-infra.dev/pkg/k8s/runtime/events"
27 "edge-infra.dev/pkg/lib/logging"
28 )
29
30 type Config struct {
31 Registry *string
32 L5dDirPath *string
33 Pprof *bool
34 }
35
36 func config() (Config, error) {
37 fs := flag.NewFlagSet("linkerdctl", flag.ExitOnError)
38 c := Config{
39 Registry: fs.String("registry", build.DefaultPublicContainerRegistry, "the registry to pull container images from i.e. us-east1-docker.pkg.dev/ret-edge-pltf-infra/thirdparty"),
40 L5dDirPath: fs.String("l5d-dir", "/etc/l5d", "l5d persistent volume dir path"),
41 Pprof: fs.Bool("enable-pprof", false, "enables pprod endpoint"),
42 }
43
44 if err := ff.Parse(fs, os.Args[1:], ff.WithEnvVarNoPrefix(), ff.WithIgnoreUndefined(true)); err != nil {
45 return Config{}, err
46 }
47 return c, nil
48 }
49
50
51
52 func Run(opts ...controller.Option) error {
53 ctrl.SetLogger(logging.NewLogger().Logger)
54 log := ctrl.Log.WithName("setup")
55
56 l5dcfg, err := config()
57 if err != nil {
58 log.Error(err, "failed to parse startup configuration")
59 return err
60 }
61
62 if l5dcfg.Pprof != nil && *l5dcfg.Pprof {
63 log.Info("serving pprof on /debug/pprof/")
64 opts = append(opts, controller.WithPProf("/", handlerPprof()))
65 }
66
67 mgr, err := CreateControllerManager(opts...)
68 if err != nil {
69 log.Error(err, "failed to create controller manager")
70 return err
71 }
72
73 mgr, err = RegisterControllers(l5dcfg, mgr)
74 if err != nil {
75 log.Error(err, "failed to register controllers")
76 return err
77 }
78
79 log.Info("starting manager")
80 if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
81 log.Error(err, "failed to start contoller manager")
82 return err
83 }
84
85 return nil
86 }
87
88
89 func handlerPprof() *http.ServeMux {
90 pprofMux := http.NewServeMux()
91 pprofMux.HandleFunc("/debug/pprof/", pprof.Index)
92 pprofMux.HandleFunc("/debug/pprof/{action}", pprof.Index)
93 pprofMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
94 return pprofMux
95 }
96
97
98
99 func CreateControllerManager(o ...controller.Option) (ctrl.Manager, error) {
100 cfg, opts := controller.ProcessOptions(o...)
101 opts.LeaderElectionID = "linkerd103zx.edge.ncr.com"
102 opts.Scheme = createScheme()
103 return ctrl.NewManager(cfg, opts)
104 }
105
106 func RegisterControllers(l5dcfg Config, mgr ctrl.Manager) (ctrl.Manager, error) {
107 ctrl.SetLogger(logging.NewLogger().Logger)
108 log := ctrl.Log.WithName("setup")
109
110 metrics := metrics.New(mgr, "linkerd",
111 metrics.WithSuspend(),
112 metrics.WithCollectors(
113 l5dmetrics.LinkerdReadinessMetric,
114 l5dmetrics.TrustAnchorExpiry,
115 l5dmetrics.WorkloadInjectionReadinessMetric,
116 ),
117 )
118 eventRecorder := events.NewRecorder(mgr, ctrl.Log, linkerd.LinkerdControllerName)
119
120 if err := newL5dReconciler(mgr, l5dcfg, metrics, eventRecorder).SetupWithManager(mgr); err != nil {
121 log.Error(err, "unable to create linkerd controller")
122 return nil, err
123 }
124
125 if err := newL5dWorkloadInjectionReconciler(mgr, metrics, eventRecorder).SetupWithManager(mgr); err != nil {
126 log.Error(err, "unable to create workloadinjection controller")
127 return nil, err
128 }
129
130 return mgr, nil
131 }
132
133 func createScheme() *runtime.Scheme {
134 scheme := runtime.NewScheme()
135 utilruntime.Must(clientgoscheme.AddToScheme(scheme))
136 utilruntime.Must(v1.AddToScheme(scheme))
137 utilruntime.Must(l5dv1alpha1.AddToScheme(scheme))
138 utilruntime.Must(certmgr.AddToScheme(scheme))
139 utilruntime.Must(serverv1beta1.AddToScheme(scheme))
140 utilruntime.Must(serverauthv1beta1.AddToScheme(scheme))
141 return scheme
142 }
143
View as plain text