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  }