1 package api
2
3 import (
4 "context"
5 "flag"
6 "fmt"
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 log "github.com/sirupsen/logrus"
17 )
18
19 const defaultDomain = "cluster.local"
20
21
22 func Main(args []string) {
23 cmd := flag.NewFlagSet("tap", flag.ExitOnError)
24 apiServerAddr := cmd.String("apiserver-addr", ":8089", "address to serve the apiserver on")
25 metricsAddr := cmd.String("metrics-addr", ":9998", "address to serve scrapable metrics on")
26 kubeConfigPath := cmd.String("kubeconfig", "", "path to kube config")
27 apiNamespace := cmd.String("api-namespace", "linkerd", "namespace in which Linkerd is installed")
28 tapPort := cmd.Uint("tap-port", 4190, "proxy tap port to connect to")
29 disableCommonNames := cmd.Bool("disable-common-names", false, "disable checks for Common Names (for development)")
30 trustDomain := cmd.String("identity-trust-domain", defaultDomain, "configures the name suffix used for identities")
31 enablePprof := cmd.Bool("enable-pprof", false, "Enable pprof endpoints on the admin server")
32
33 var ignoreHeaders = &stringMap{}
34 cmd.Var(ignoreHeaders, "ignore-headers", "list of headers to ignore")
35
36 traceCollector := flags.AddTraceFlags(cmd)
37 flags.ConfigureAndParse(cmd, args)
38
39 ready := false
40 adminServer := admin.NewServer(*metricsAddr, *enablePprof, &ready)
41
42 go func() {
43 log.Infof("starting admin server on %s", *metricsAddr)
44 if err := adminServer.ListenAndServe(); err != nil {
45 log.Errorf("failed to start tap admin server: %s", err)
46 }
47 }()
48
49 ctx := context.Background()
50 stop := make(chan os.Signal, 1)
51 signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
52 k8sAPI, err := k8s.InitializeAPI(
53 ctx,
54 *kubeConfigPath,
55 true,
56 "local",
57 k8s.CJ,
58 k8s.DS,
59 k8s.SS,
60 k8s.Deploy,
61 k8s.Job,
62 k8s.NS,
63 k8s.Pod,
64 k8s.RC,
65 k8s.Svc,
66 k8s.RS,
67 k8s.Node,
68 )
69 if err != nil {
70 log.Fatalf("Failed to initialize K8s API: %s", err)
71 }
72 log.Infof("Using trust domain: %s", *trustDomain)
73 if *traceCollector != "" {
74 if err := trace.InitializeTracing("linkerd-tap", *traceCollector); err != nil {
75 log.Warnf("failed to initialize tracing: %s", err)
76 }
77 }
78 grpcTapServer, err := NewGrpcTapServer(*tapPort, *apiNamespace, *trustDomain, k8sAPI, *ignoreHeaders)
79 if err != nil {
80 log.Fatal(err.Error())
81 }
82 apiServer, err := NewServer(ctx, *apiServerAddr, k8sAPI, grpcTapServer, *disableCommonNames)
83 if err != nil {
84 log.Fatal(err.Error())
85 }
86 k8sAPI.Sync(nil)
87 go apiServer.Start(ctx)
88
89 ready = true
90
91 <-stop
92 log.Infof("shutting down APIServer on %s", *apiServerAddr)
93 apiServer.Shutdown(ctx)
94 adminServer.Shutdown(ctx)
95 }
96
97 type stringMap map[string]bool
98
99 func (m stringMap) String() string {
100 return fmt.Sprintf("%v", map[string]bool(m))
101 }
102
103 func (m stringMap) Set(value string) error {
104 parts := strings.Split(value, ",")
105 for _, p := range parts {
106 m[p] = true
107 }
108 return nil
109 }
110
View as plain text