github.com/Azure/aad-pod-identity@v1.8.17/cmd/nmi/main.go (about)

     1  package main
     2  
     3  import (
     4  	goflag "flag"
     5  	"net/http"
     6  	_ "net/http/pprof" // #nosec
     7  	"os"
     8  	"strings"
     9  
    10  	"github.com/Azure/aad-pod-identity/pkg/log"
    11  	"github.com/Azure/aad-pod-identity/pkg/metrics"
    12  	"github.com/Azure/aad-pod-identity/pkg/nmi"
    13  	server "github.com/Azure/aad-pod-identity/pkg/nmi/server"
    14  	"github.com/Azure/aad-pod-identity/pkg/probes"
    15  	"github.com/Azure/aad-pod-identity/pkg/utils"
    16  	"github.com/Azure/aad-pod-identity/version"
    17  
    18  	"github.com/spf13/pflag"
    19  	"k8s.io/klog/v2"
    20  )
    21  
    22  const (
    23  	defaultMetadataIP                         = "169.254.169.254"
    24  	defaultMetadataPort                       = "80"
    25  	defaultNmiHost                            = "127.0.0.1"
    26  	defaultNmiPort                            = "2579"
    27  	defaultIPTableUpdateTimeIntervalInSeconds = 60
    28  	defaultlistPodIDsRetryAttemptsForCreated  = 16
    29  	defaultlistPodIDsRetryAttemptsForAssigned = 4
    30  	defaultlistPodIDsRetryIntervalInSeconds   = 5
    31  )
    32  
    33  var (
    34  	versionInfo                        = pflag.Bool("version", false, "prints the version information")
    35  	nmiHost                            = pflag.String("nmi-listen-address", defaultNmiHost, "NMI listen address")
    36  	nmiPort                            = pflag.String("nmi-port", defaultNmiPort, "NMI application port")
    37  	metadataIP                         = pflag.String("metadata-ip", defaultMetadataIP, "instance metadata host ip")
    38  	metadataPort                       = pflag.String("metadata-port", defaultMetadataPort, "instance metadata host ip")
    39  	nodename                           = pflag.String("node", "", "node name")
    40  	ipTableUpdateTimeIntervalInSeconds = pflag.Int("ipt-update-interval-sec", defaultIPTableUpdateTimeIntervalInSeconds, "update interval of iptables")
    41  	forceNamespaced                    = pflag.Bool("forceNamespaced", false, "Forces mic to namespace identities, binding, and assignment")
    42  	micNamespace                       = pflag.String("MICNamespace", "default", "MIC namespace to short circuit MIC token requests")
    43  	httpProbePort                      = pflag.String("http-probe-port", "8080", "Http health and liveness probe port")
    44  	retryAttemptsForCreated            = pflag.Int("retry-attempts-for-created", defaultlistPodIDsRetryAttemptsForCreated, "Number of retries in NMI to find assigned identity in CREATED state")
    45  	retryAttemptsForAssigned           = pflag.Int("retry-attempts-for-assigned", defaultlistPodIDsRetryAttemptsForAssigned, "Number of retries in NMI to find assigned identity in ASSIGNED state")
    46  	findIdentityRetryIntervalInSeconds = pflag.Int("find-identity-retry-interval", defaultlistPodIDsRetryIntervalInSeconds, "Retry interval to find assigned identities in seconds")
    47  	enableProfile                      = pflag.Bool("enableProfile", false, "Enable/Disable pprof profiling")
    48  	enableScaleFeatures                = pflag.Bool("enableScaleFeatures", true, "Enable/Disable features for scale clusters")
    49  	blockInstanceMetadata              = pflag.Bool("block-instance-metadata", false, "Block instance metadata endpoints")
    50  	metadataHeaderRequired             = pflag.Bool("metadata-header-required", true, "Metadata header required for querying Azure Instance Metadata service")
    51  	prometheusPort                     = pflag.String("prometheus-port", "9090", "Prometheus port for metrics")
    52  	operationMode                      = pflag.String("operation-mode", "standard", "NMI operation mode")
    53  	allowNetworkPluginKubenet          = pflag.Bool("allow-network-plugin-kubenet", false, "Allow running aad-pod-identity in cluster with kubenet")
    54  	kubeletConfig                      = pflag.String("kubelet-config", "/etc/default/kubelet", "Path to kubelet default config")
    55  	setRetryAfterHeader                = pflag.Bool("set-retry-after-header", false, "Set Retry-After header in NMI responses")
    56  	enableConntrackDeletion            = pflag.Bool("enable-conntrack-deletion", false, "Enable/Disable deletion of conntrack entries for pre-existing connections to metadata endpoint")
    57  )
    58  
    59  func main() {
    60  	klog.InitFlags(nil)
    61  	defer klog.Flush()
    62  
    63  	logOptions := log.NewOptions()
    64  	logOptions.AddFlags()
    65  
    66  	// this is done for glog used by client-go underneath
    67  	pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
    68  
    69  	pflag.Parse()
    70  
    71  	if err := logOptions.Apply(); err != nil {
    72  		klog.Fatalf("unable to apply logging options, error: %+v", err)
    73  	}
    74  
    75  	if *versionInfo {
    76  		version.PrintVersionAndExit()
    77  	}
    78  
    79  	// check if the cni is kubenet from the --network-plugin defined in kubelet config
    80  	if !*allowNetworkPluginKubenet {
    81  		isKubenet, err := utils.IsKubenetCNI(*kubeletConfig)
    82  		if err != nil {
    83  			klog.Fatalf("failed to check if CNI plugin is kubenet, error: %+v", err)
    84  		}
    85  		if isKubenet {
    86  			klog.Fatalf("AAD Pod Identity is not supported for Kubenet. Review https://azure.github.io/aad-pod-identity/docs/configure/aad_pod_identity_on_kubenet/ for more details.")
    87  		}
    88  	}
    89  
    90  	klog.Infof("starting nmi process. Version: %v. Build date: %v.", version.NMIVersion, version.BuildDate)
    91  
    92  	if *enableProfile {
    93  		profilePort := "6060"
    94  		klog.Infof("starting profiling on port %s", profilePort)
    95  		go func() {
    96  			addr := "localhost:" + profilePort
    97  			if err := http.ListenAndServe(addr, nil); err != nil {
    98  				klog.Errorf("failed to listen and serve %s, error: %+v", addr, err)
    99  			}
   100  		}()
   101  	}
   102  	if *enableScaleFeatures {
   103  		klog.Infof("features for scale clusters enabled")
   104  	}
   105  
   106  	// normalize operation mode
   107  	*operationMode = strings.ToLower(*operationMode)
   108  
   109  	client, err := nmi.GetKubeClient(*nodename, *operationMode, *enableScaleFeatures)
   110  	if err != nil {
   111  		klog.Fatalf("failed to get kube client, error: %+v", err)
   112  	}
   113  
   114  	exit := make(<-chan struct{})
   115  	client.Start(exit)
   116  	*forceNamespaced = *forceNamespaced || "true" == os.Getenv("FORCENAMESPACED")
   117  	klog.Infof("running NMI in namespaced mode: %v", *forceNamespaced)
   118  
   119  	s := server.NewServer(*micNamespace, *blockInstanceMetadata, *metadataHeaderRequired, *setRetryAfterHeader)
   120  	s.KubeClient = client
   121  	s.MetadataIP = *metadataIP
   122  	s.MetadataPort = *metadataPort
   123  	s.NMIHost = *nmiHost
   124  	s.NMIPort = *nmiPort
   125  	s.NodeName = *nodename
   126  	s.IPTableUpdateTimeIntervalInSeconds = *ipTableUpdateTimeIntervalInSeconds
   127  	s.EnableConntrackDeletion = *enableConntrackDeletion
   128  
   129  	nmiConfig := nmi.Config{
   130  		Mode:                               strings.ToLower(*operationMode),
   131  		RetryAttemptsForCreated:            *retryAttemptsForCreated,
   132  		RetryAttemptsForAssigned:           *retryAttemptsForAssigned,
   133  		FindIdentityRetryIntervalInSeconds: *findIdentityRetryIntervalInSeconds,
   134  		Namespaced:                         *forceNamespaced,
   135  	}
   136  
   137  	// Create new token client based on the nmi mode
   138  	tokenClient, err := nmi.GetTokenClient(client, nmiConfig)
   139  	if err != nil {
   140  		klog.Fatalf("failed to initialize token client, error: %+v", err)
   141  	}
   142  	s.TokenClient = tokenClient
   143  
   144  	// Health probe will always report success once its started. The contents
   145  	// will report "Active" once the iptables rules are set
   146  	probes.InitAndStart(*httpProbePort, &s.Initialized)
   147  
   148  	// Register and expose metrics views
   149  	if err = metrics.RegisterAndExport(*prometheusPort); err != nil {
   150  		klog.Fatalf("failed to register and export metrics on port %s, error: %+v", *prometheusPort, err)
   151  	}
   152  	if err := s.Run(); err != nil {
   153  		klog.Fatalf("%s", err)
   154  	}
   155  }