istio.io/istio@v0.0.0-20240520182934-d79c90f27776/security/pkg/nodeagent/sds/server.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package sds 16 17 import ( 18 "net" 19 "time" 20 21 "go.uber.org/atomic" 22 "google.golang.org/grpc" 23 24 mesh "istio.io/api/mesh/v1alpha1" 25 "istio.io/istio/pkg/security" 26 "istio.io/istio/pkg/uds" 27 ) 28 29 const ( 30 maxStreams = 100000 31 maxRetryTimes = 5 32 ) 33 34 // Server is the gPRC server that exposes SDS through UDS. 35 type Server struct { 36 workloadSds *sdsservice 37 38 grpcWorkloadListener net.Listener 39 40 grpcWorkloadServer *grpc.Server 41 stopped *atomic.Bool 42 } 43 44 // NewServer creates and starts the Grpc server for SDS. 45 func NewServer(options *security.Options, workloadSecretCache security.SecretManager, pkpConf *mesh.PrivateKeyProvider) *Server { 46 s := &Server{stopped: atomic.NewBool(false)} 47 s.workloadSds = newSDSService(workloadSecretCache, options, pkpConf) 48 s.initWorkloadSdsService() 49 return s 50 } 51 52 func (s *Server) OnSecretUpdate(resourceName string) { 53 if s.workloadSds == nil { 54 return 55 } 56 57 sdsServiceLog.Debugf("Trigger on secret update, resource name: %s", resourceName) 58 s.workloadSds.push(resourceName) 59 } 60 61 // Stop closes the gRPC server and debug server. 62 func (s *Server) Stop() { 63 if s == nil { 64 return 65 } 66 s.stopped.Store(true) 67 if s.grpcWorkloadServer != nil { 68 s.grpcWorkloadServer.Stop() 69 } 70 if s.grpcWorkloadListener != nil { 71 s.grpcWorkloadListener.Close() 72 } 73 if s.workloadSds != nil { 74 s.workloadSds.Close() 75 } 76 } 77 78 func (s *Server) initWorkloadSdsService() { 79 s.grpcWorkloadServer = grpc.NewServer(s.grpcServerOptions()...) 80 s.workloadSds.register(s.grpcWorkloadServer) 81 var err error 82 s.grpcWorkloadListener, err = uds.NewListener(security.WorkloadIdentitySocketPath) 83 go func() { 84 sdsServiceLog.Info("Starting SDS grpc server") 85 waitTime := time.Second 86 started := false 87 for i := 0; i < maxRetryTimes; i++ { 88 if s.stopped.Load() { 89 return 90 } 91 serverOk := true 92 setUpUdsOK := true 93 if s.grpcWorkloadListener == nil { 94 if s.grpcWorkloadListener, err = uds.NewListener(security.WorkloadIdentitySocketPath); err != nil { 95 sdsServiceLog.Errorf("SDS grpc server for workload proxies failed to set up UDS: %v", err) 96 setUpUdsOK = false 97 } 98 } 99 if s.grpcWorkloadListener != nil { 100 if err = s.grpcWorkloadServer.Serve(s.grpcWorkloadListener); err != nil { 101 sdsServiceLog.Errorf("SDS grpc server for workload proxies failed to start: %v", err) 102 serverOk = false 103 } 104 } 105 if serverOk && setUpUdsOK { 106 sdsServiceLog.Infof("SDS server for workload certificates started, listening on %q", security.WorkloadIdentitySocketPath) 107 started = true 108 break 109 } 110 time.Sleep(waitTime) 111 waitTime *= 2 112 } 113 if !started { 114 sdsServiceLog.Warn("SDS grpc server could not be started") 115 } 116 }() 117 } 118 119 func (s *Server) grpcServerOptions() []grpc.ServerOption { 120 grpcOptions := []grpc.ServerOption{ 121 grpc.MaxConcurrentStreams(uint32(maxStreams)), 122 } 123 124 return grpcOptions 125 }