volcano.sh/volcano@v1.9.0/cmd/webhook-manager/app/server.go (about) 1 /* 2 Copyright 2018 The Volcano Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package app 18 19 import ( 20 "fmt" 21 "net/http" 22 "os" 23 "os/signal" 24 "strconv" 25 "syscall" 26 27 v1 "k8s.io/api/core/v1" 28 corev1 "k8s.io/client-go/kubernetes/typed/core/v1" 29 "k8s.io/client-go/tools/record" 30 "k8s.io/klog/v2" 31 32 "volcano.sh/apis/pkg/apis/helpers" 33 "volcano.sh/apis/pkg/apis/scheduling/scheme" 34 "volcano.sh/volcano/cmd/webhook-manager/app/options" 35 "volcano.sh/volcano/pkg/kube" 36 commonutil "volcano.sh/volcano/pkg/util" 37 "volcano.sh/volcano/pkg/version" 38 wkconfig "volcano.sh/volcano/pkg/webhooks/config" 39 "volcano.sh/volcano/pkg/webhooks/router" 40 ) 41 42 // Run start the service of admission controller. 43 func Run(config *options.Config) error { 44 if config.PrintVersion { 45 version.PrintVersionAndExit() 46 return nil 47 } 48 49 if config.EnableHealthz { 50 if err := helpers.StartHealthz(config.HealthzBindAddress, "volcano-admission", config.CaCertData, config.CertData, config.KeyData); err != nil { 51 return err 52 } 53 } 54 55 if config.WebhookURL == "" && config.WebhookNamespace == "" && config.WebhookName == "" { 56 return fmt.Errorf("failed to start webhooks as both 'url' and 'namespace/name' of webhook are empty") 57 } 58 59 restConfig, err := kube.BuildConfig(config.KubeClientOptions) 60 if err != nil { 61 return fmt.Errorf("unable to build k8s config: %v", err) 62 } 63 64 admissionConf := wkconfig.LoadAdmissionConf(config.ConfigPath) 65 if admissionConf == nil { 66 klog.Errorf("loadAdmissionConf failed.") 67 } else { 68 klog.V(2).Infof("loadAdmissionConf:%v", admissionConf.ResGroupsConfig) 69 } 70 71 vClient := getVolcanoClient(restConfig) 72 kubeClient := getKubeClient(restConfig) 73 74 broadcaster := record.NewBroadcaster() 75 broadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")}) 76 recorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: commonutil.GenerateComponentName(config.SchedulerNames)}) 77 if err := router.ForEachAdmission(config, func(service *router.AdmissionService) error { 78 if service.Config != nil { 79 service.Config.VolcanoClient = vClient 80 service.Config.KubeClient = kubeClient 81 service.Config.SchedulerNames = config.SchedulerNames 82 service.Config.Recorder = recorder 83 service.Config.ConfigData = admissionConf 84 } 85 86 klog.V(3).Infof("Registered '%s' as webhook.", service.Path) 87 http.HandleFunc(service.Path, service.Handler) 88 89 klog.V(3).Infof("Add CaCert for webhook <%s>", service.Path) 90 if err = addCaCertForWebhook(kubeClient, service, config.CaCertData); err != nil { 91 return fmt.Errorf("failed to add caCert for webhook %v", err) 92 } 93 return nil 94 }); err != nil { 95 return err 96 } 97 98 klog.V(3).Infof("Successfully added caCert for all webhooks") 99 100 webhookServeError := make(chan struct{}) 101 stopChannel := make(chan os.Signal, 1) 102 signal.Notify(stopChannel, syscall.SIGTERM, syscall.SIGINT) 103 104 server := &http.Server{ 105 Addr: config.ListenAddress + ":" + strconv.Itoa(config.Port), 106 TLSConfig: configTLS(config, restConfig), 107 } 108 go func() { 109 err = server.ListenAndServeTLS("", "") 110 if err != nil && err != http.ErrServerClosed { 111 klog.Fatalf("ListenAndServeTLS for admission webhook failed: %v", err) 112 close(webhookServeError) 113 } 114 115 klog.Info("Volcano Webhook manager started.") 116 }() 117 118 if config.ConfigPath != "" { 119 go wkconfig.WatchAdmissionConf(config.ConfigPath, stopChannel) 120 } 121 122 select { 123 case <-stopChannel: 124 if err := server.Close(); err != nil { 125 return fmt.Errorf("close admission server failed: %v", err) 126 } 127 return nil 128 case <-webhookServeError: 129 return fmt.Errorf("unknown webhook server error") 130 } 131 }