Fix panic when routes is called in single-namespace mode (#2123)

Fixes #2119 

When Linkerd is installed in single-namespace mode, the public-api container panics when it attempts to access watch service profiles.

In single-namespace mode, we no longer watch service profiles and return an informative error when the TopRoutes API is called.

Signed-off-by: Alex Leong <alex@buoyant.io>
This commit is contained in:
Alex Leong 2019-01-23 16:47:05 -08:00 committed by GitHub
parent b227c85a5b
commit 32efab41b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 45 additions and 31 deletions

View File

@ -30,6 +30,7 @@ type (
k8sAPI *k8s.API k8sAPI *k8s.API
controllerNamespace string controllerNamespace string
ignoredNamespaces []string ignoredNamespaces []string
singleNamespace bool
} }
) )
@ -52,6 +53,7 @@ func newGrpcServer(
k8sAPI *k8s.API, k8sAPI *k8s.API,
controllerNamespace string, controllerNamespace string,
ignoredNamespaces []string, ignoredNamespaces []string,
singleNamespace bool,
) *grpcServer { ) *grpcServer {
return &grpcServer{ return &grpcServer{
prometheusAPI: promAPI, prometheusAPI: promAPI,
@ -59,6 +61,7 @@ func newGrpcServer(
k8sAPI: k8sAPI, k8sAPI: k8sAPI,
controllerNamespace: controllerNamespace, controllerNamespace: controllerNamespace,
ignoredNamespaces: ignoredNamespaces, ignoredNamespaces: ignoredNamespaces,
singleNamespace: singleNamespace,
} }
} }

View File

@ -243,6 +243,7 @@ spec:
k8sAPI, k8sAPI,
"linkerd", "linkerd",
[]string{}, []string{},
false,
) )
k8sAPI.Sync() k8sAPI.Sync()
@ -343,6 +344,7 @@ metadata:
k8sAPI, k8sAPI,
"linkerd", "linkerd",
[]string{}, []string{},
false,
) )
k8sAPI.Sync() k8sAPI.Sync()

View File

@ -247,6 +247,7 @@ func NewServer(
k8sAPI *k8s.API, k8sAPI *k8s.API,
controllerNamespace string, controllerNamespace string,
ignoredNamespaces []string, ignoredNamespaces []string,
singleNamespace bool,
) *http.Server { ) *http.Server {
baseHandler := &handler{ baseHandler := &handler{
grpcServer: newGrpcServer( grpcServer: newGrpcServer(
@ -255,6 +256,7 @@ func NewServer(
k8sAPI, k8sAPI,
controllerNamespace, controllerNamespace,
ignoredNamespaces, ignoredNamespaces,
singleNamespace,
), ),
} }

View File

@ -776,6 +776,7 @@ status:
k8sAPI, k8sAPI,
"linkerd", "linkerd",
[]string{}, []string{},
false,
) )
_, err := fakeGrpcServer.StatSummary(context.TODO(), &exp.req) _, err := fakeGrpcServer.StatSummary(context.TODO(), &exp.req)
@ -800,6 +801,7 @@ status:
k8sAPI, k8sAPI,
"linkerd", "linkerd",
[]string{}, []string{},
false,
) )
invalidRequests := []statSumExpected{ invalidRequests := []statSumExpected{

View File

@ -281,6 +281,7 @@ func newMockGrpcServer(exp expectedStatRPC) (*mockProm, *grpcServer, error) {
k8sAPI, k8sAPI,
"linkerd", "linkerd",
[]string{}, []string{},
false,
) )
k8sAPI.Sync() k8sAPI.Sync()

View File

@ -42,6 +42,10 @@ type resourceTable struct {
func (s *grpcServer) TopRoutes(ctx context.Context, req *pb.TopRoutesRequest) (*pb.TopRoutesResponse, error) { func (s *grpcServer) TopRoutes(ctx context.Context, req *pb.TopRoutesRequest) (*pb.TopRoutesResponse, error) {
log.Debugf("TopRoutes request: %+v", req) log.Debugf("TopRoutes request: %+v", req)
if s.singleNamespace {
return topRoutesError(req, "Routes are not available in single-namespace mode"), nil
}
errRsp := validateRequest(req) errRsp := validateRequest(req)
if errRsp != nil { if errRsp != nil {
return errRsp, nil return errRsp, nil

View File

@ -7,6 +7,7 @@ import (
"syscall" "syscall"
"github.com/linkerd/linkerd2/controller/api/proxy" "github.com/linkerd/linkerd2/controller/api/proxy"
spclient "github.com/linkerd/linkerd2/controller/gen/client/clientset/versioned"
"github.com/linkerd/linkerd2/controller/k8s" "github.com/linkerd/linkerd2/controller/k8s"
"github.com/linkerd/linkerd2/pkg/admin" "github.com/linkerd/linkerd2/pkg/admin"
"github.com/linkerd/linkerd2/pkg/flags" "github.com/linkerd/linkerd2/pkg/flags"
@ -32,33 +33,27 @@ func main() {
log.Fatal(err.Error()) log.Fatal(err.Error())
} }
var k8sAPI *k8s.API var spClient *spclient.Clientset
restrictToNamespace := ""
resources := []k8s.APIResource{k8s.Endpoint, k8s.Pod, k8s.RS, k8s.Svc}
if *singleNamespace { if *singleNamespace {
k8sAPI = k8s.NewAPI( restrictToNamespace = *controllerNamespace
k8sClient,
nil,
*controllerNamespace,
k8s.Endpoint,
k8s.Pod,
k8s.RS,
k8s.Svc,
)
} else { } else {
spClient, err := k8s.NewSpClientSet(*kubeConfigPath) spClient, err = k8s.NewSpClientSet(*kubeConfigPath)
if err != nil { if err != nil {
log.Fatal(err.Error()) log.Fatal(err.Error())
} }
k8sAPI = k8s.NewAPI(
resources = append(resources, k8s.SP)
}
k8sAPI := k8s.NewAPI(
k8sClient, k8sClient,
spClient, spClient,
"", restrictToNamespace,
k8s.Endpoint, resources...,
k8s.Pod,
k8s.RS,
k8s.Svc,
k8s.SP,
) )
}
done := make(chan struct{}) done := make(chan struct{})

View File

@ -9,6 +9,7 @@ import (
"syscall" "syscall"
"github.com/linkerd/linkerd2/controller/api/public" "github.com/linkerd/linkerd2/controller/api/public"
spclient "github.com/linkerd/linkerd2/controller/gen/client/clientset/versioned"
"github.com/linkerd/linkerd2/controller/k8s" "github.com/linkerd/linkerd2/controller/k8s"
"github.com/linkerd/linkerd2/controller/tap" "github.com/linkerd/linkerd2/controller/tap"
"github.com/linkerd/linkerd2/pkg/admin" "github.com/linkerd/linkerd2/pkg/admin"
@ -41,24 +42,27 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err.Error()) log.Fatal(err.Error())
} }
spClient, err := k8s.NewSpClientSet(*kubeConfigPath)
var spClient *spclient.Clientset
restrictToNamespace := ""
resources := []k8s.APIResource{k8s.Deploy, k8s.Pod, k8s.RC, k8s.RS, k8s.Svc}
if *singleNamespace {
restrictToNamespace = *controllerNamespace
} else {
spClient, err = k8s.NewSpClientSet(*kubeConfigPath)
if err != nil { if err != nil {
log.Fatal(err.Error()) log.Fatal(err.Error())
} }
restrictToNamespace := ""
if *singleNamespace { resources = append(resources, k8s.SP)
restrictToNamespace = *controllerNamespace
} }
k8sAPI := k8s.NewAPI( k8sAPI := k8s.NewAPI(
k8sClient, k8sClient,
spClient, spClient,
restrictToNamespace, restrictToNamespace,
k8s.Deploy, resources...,
k8s.Pod,
k8s.RC,
k8s.RS,
k8s.SP,
k8s.Svc,
) )
prometheusClient, err := promApi.NewClient(promApi.Config{Address: *prometheusURL}) prometheusClient, err := promApi.NewClient(promApi.Config{Address: *prometheusURL})
@ -73,6 +77,7 @@ func main() {
k8sAPI, k8sAPI,
*controllerNamespace, *controllerNamespace,
strings.Split(*ignoredNamespaces, ","), strings.Split(*ignoredNamespaces, ","),
*singleNamespace,
) )
k8sAPI.Sync() // blocks until caches are synced k8sAPI.Sync() // blocks until caches are synced