1 package main
2
3 import (
4 "context"
5 "flag"
6 "net"
7 "os"
8 "os/signal"
9 "strings"
10 "syscall"
11
12 "github.com/linkerd/linkerd2/controller/k8s"
13 "github.com/linkerd/linkerd2/pkg/admin"
14 "github.com/linkerd/linkerd2/pkg/flags"
15 "github.com/linkerd/linkerd2/pkg/trace"
16 api "github.com/linkerd/linkerd2/viz/metrics-api"
17 promApi "github.com/prometheus/client_golang/api"
18 promv1 "github.com/prometheus/client_golang/api/prometheus/v1"
19 log "github.com/sirupsen/logrus"
20 )
21
22 func main() {
23 cmd := flag.NewFlagSet("metrics-api", flag.ExitOnError)
24
25 addr := cmd.String("addr", ":8085", "address to serve on")
26 kubeConfigPath := cmd.String("kubeconfig", "", "path to kube config")
27 prometheusURL := cmd.String("prometheus-url", "", "prometheus url")
28 metricsAddr := cmd.String("metrics-addr", ":9995", "address to serve scrapable metrics on")
29 controllerNamespace := cmd.String("controller-namespace", "linkerd", "namespace in which Linkerd is installed")
30 ignoredNamespaces := cmd.String("ignore-namespaces", "kube-system", "comma separated list of namespaces to not list pods from")
31 clusterDomain := cmd.String("cluster-domain", "cluster.local", "kubernetes cluster domain")
32 enablePprof := cmd.Bool("enable-pprof", false, "Enable pprof endpoints on the admin server")
33
34 traceCollector := flags.AddTraceFlags(cmd)
35
36 flags.ConfigureAndParse(cmd, os.Args[1:])
37
38 ready := false
39 adminServer := admin.NewServer(*metricsAddr, *enablePprof, &ready)
40
41 go func() {
42 log.Infof("starting admin server on %s", *metricsAddr)
43 if err := adminServer.ListenAndServe(); err != nil {
44 log.Errorf("failed to start metrics API admin server: %s", err)
45 }
46 }()
47
48 ctx := context.Background()
49
50 stop := make(chan os.Signal, 1)
51 signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
52
53 k8sAPI, err := k8s.InitializeAPI(
54 ctx,
55 *kubeConfigPath,
56 true,
57 "local",
58 k8s.CJ, k8s.DS, k8s.Deploy, k8s.Job, k8s.NS, k8s.Pod, k8s.RC, k8s.RS, k8s.Svc, k8s.SS, k8s.SP,
59 )
60 if err != nil {
61 log.Fatalf("Failed to initialize K8s API: %s", err)
62 }
63
64 var prometheusClient promApi.Client
65 if *prometheusURL != "" {
66 prometheusClient, err = promApi.NewClient(promApi.Config{Address: *prometheusURL})
67 if err != nil {
68 log.Fatal(err.Error())
69 }
70 }
71
72 log.Infof("prometheusClient: %#v", prometheusClient)
73 log.Info("Using cluster domain: ", *clusterDomain)
74
75 if *traceCollector != "" {
76 if err := trace.InitializeTracing("linkerd-public-api", *traceCollector); err != nil {
77 log.Warnf("failed to initialize tracing: %s", err)
78 }
79 }
80
81 var promAPI promv1.API
82 if prometheusClient != nil {
83 promAPI = promv1.NewAPI(prometheusClient)
84 }
85
86 server := api.NewGrpcServer(
87 promAPI,
88 k8sAPI,
89 *controllerNamespace,
90 *clusterDomain,
91 strings.Split(*ignoredNamespaces, ","),
92 )
93
94 k8sAPI.Sync(nil)
95
96 lis, err := net.Listen("tcp", *addr)
97 if err != nil {
98 log.Fatalf("Failed to listen on %s: %s", *addr, err)
99 }
100 go func() {
101 log.Infof("starting HTTP server on %+v", *addr)
102
103 if err := server.Serve(lis); err != nil {
104 log.Errorf("failed to start metrics API HTTP server: %s", err)
105 }
106 }()
107
108 ready = true
109
110 <-stop
111
112 log.Infof("shutting down HTTP server on %+v", *addr)
113 server.GracefulStop()
114 adminServer.Shutdown(ctx)
115 }
116
View as plain text