1
1
package main
2
2
3
3
import (
4
- "context"
5
4
"flag"
6
5
"fmt"
7
6
"net"
8
7
"net/http"
8
+ "os"
9
9
"strconv"
10
10
11
11
"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -14,6 +14,7 @@ import (
14
14
"inference.networking.x-k8s.io/gateway-api-inference-extension/api/v1alpha1"
15
15
"inference.networking.x-k8s.io/gateway-api-inference-extension/pkg/ext-proc/backend"
16
16
"inference.networking.x-k8s.io/gateway-api-inference-extension/pkg/ext-proc/backend/vllm"
17
+ "inference.networking.x-k8s.io/gateway-api-inference-extension/pkg/ext-proc/internal/runnable"
17
18
"inference.networking.x-k8s.io/gateway-api-inference-extension/pkg/ext-proc/metrics"
18
19
runserver "inference.networking.x-k8s.io/gateway-api-inference-extension/pkg/ext-proc/server"
19
20
"k8s.io/apimachinery/pkg/runtime"
@@ -23,6 +24,7 @@ import (
23
24
"k8s.io/component-base/metrics/legacyregistry"
24
25
klog "k8s.io/klog/v2"
25
26
ctrl "sigs.k8s.io/controller-runtime"
27
+ "sigs.k8s.io/controller-runtime/pkg/manager"
26
28
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
27
29
)
28
30
@@ -79,17 +81,25 @@ func init() {
79
81
}
80
82
81
83
func main () {
84
+ if err := run (); err != nil {
85
+ os .Exit (1 )
86
+ }
87
+ }
88
+
89
+ func run () error {
82
90
klog .InitFlags (nil )
83
91
flag .Parse ()
84
92
85
93
ctrl .SetLogger (klog .TODO ())
86
94
cfg , err := ctrl .GetConfig ()
87
95
if err != nil {
88
- klog .Fatalf ("Failed to get rest config: %v" , err )
96
+ klog .ErrorS (err , "Failed to get rest config" )
97
+ return err
89
98
}
90
99
// Validate flags
91
100
if err := validateFlags (); err != nil {
92
- klog .Fatalf ("Failed to validate flags: %v" , err )
101
+ klog .ErrorS (err , "Failed to validate flags" )
102
+ return err
93
103
}
94
104
95
105
// Print all flag values
@@ -114,101 +124,95 @@ func main() {
114
124
Config : ctrl .GetConfigOrDie (),
115
125
Datastore : datastore ,
116
126
}
117
- serverRunner .Setup ()
118
-
119
- // Start health and ext-proc servers in goroutines
120
- healthSvr := startHealthServer (datastore , * grpcHealthPort )
121
- extProcSvr := serverRunner .Start (
122
- datastore ,
123
- & vllm.PodMetricsClientImpl {},
124
- )
125
- // Start metrics handler
126
- metricsSvr := startMetricsHandler (* metricsPort , cfg )
127
-
128
- // Start manager, blocking
129
- serverRunner .StartManager ()
127
+ if err := serverRunner .Setup (); err != nil {
128
+ klog .ErrorS (err , "Failed to setup ext-proc server" )
129
+ return err
130
+ }
131
+ mgr := serverRunner .Manager
130
132
131
- // Gracefully shutdown servers
132
- if healthSvr != nil {
133
- klog .Info ("Health server shutting down" )
134
- healthSvr .GracefulStop ()
133
+ // Register health server.
134
+ if err := registerHealthServer (mgr , datastore , * grpcHealthPort ); err != nil {
135
+ return err
135
136
}
136
- if extProcSvr != nil {
137
- klog .Info ("Ext-proc server shutting down" )
138
- extProcSvr .GracefulStop ()
137
+
138
+ // Register ext-proc server.
139
+ if err := mgr .Add (serverRunner .AsRunnable (datastore , & vllm.PodMetricsClientImpl {})); err != nil {
140
+ klog .ErrorS (err , "Failed to register ext-proc server" )
141
+ return err
139
142
}
140
- if metricsSvr != nil {
141
- klog .Info ("Metrics server shutting down" )
142
- if err := metricsSvr .Shutdown (context .Background ()); err != nil {
143
- klog .Infof ("Metrics server Shutdown: %v" , err )
144
- }
143
+
144
+ // Register metrics handler.
145
+ if err := registerMetricsHandler (mgr , * metricsPort , cfg ); err != nil {
146
+ return err
145
147
}
146
148
147
- klog .Info ("All components shutdown" )
149
+ // Start the manager.
150
+ return serverRunner .StartManager (ctrl .SetupSignalHandler ())
148
151
}
149
152
150
- // startHealthServer starts the gRPC health probe server in a goroutine.
151
- func startHealthServer (ds * backend.K8sDatastore , port int ) * grpc.Server {
152
- svr := grpc .NewServer ()
153
- healthPb .RegisterHealthServer (svr , & healthServer {datastore : ds })
154
-
155
- go func () {
156
- lis , err := net .Listen ("tcp" , fmt .Sprintf (":%d" , port ))
157
- if err != nil {
158
- klog .Fatalf ("Health server failed to listen: %v" , err )
159
- }
160
- klog .Infof ("Health server listening on port: %d" , port )
161
-
162
- // Blocking and will return when shutdown is complete.
163
- if err := svr .Serve (lis ); err != nil && err != grpc .ErrServerStopped {
164
- klog .Fatalf ("Health server failed: %v" , err )
165
- }
166
- klog .Info ("Health server shutting down" )
167
- }()
168
- return svr
153
+ // registerHealthServer adds the Health gRPC server as a Runnable to the given manager.
154
+ func registerHealthServer (mgr manager.Manager , ds * backend.K8sDatastore , port int ) error {
155
+ srv := grpc .NewServer ()
156
+ healthPb .RegisterHealthServer (srv , & healthServer {datastore : ds })
157
+ if err := mgr .Add (
158
+ runnable .NoLeaderElection (runnable .GRPCServer ("health" , srv , port ))); err != nil {
159
+ klog .ErrorS (err , "Failed to register health server" )
160
+ return err
161
+ }
162
+ return nil
169
163
}
170
164
171
- func startMetricsHandler (port int , cfg * rest.Config ) * http.Server {
165
+ // registerMetricsHandler adds the metrics HTTP handler as a Runnable to the given manager.
166
+ func registerMetricsHandler (mgr manager.Manager , port int , cfg * rest.Config ) error {
172
167
metrics .Register ()
173
168
174
- var svr * http.Server
175
- go func () {
176
- klog .Info ("Starting metrics HTTP handler ..." )
177
-
178
- mux := http .NewServeMux ()
179
- mux .Handle (defaultMetricsEndpoint , metricsHandlerWithAuthenticationAndAuthorization (cfg ))
180
-
181
- svr = & http.Server {
182
- Addr : net .JoinHostPort ("" , strconv .Itoa (port )),
183
- Handler : mux ,
184
- }
185
- if err := svr .ListenAndServe (); err != http .ErrServerClosed {
186
- klog .Fatalf ("failed to start metrics HTTP handler: %v" , err )
187
- }
188
- }()
189
- return svr
169
+ // Init HTTP server.
170
+ h , err := metricsHandlerWithAuthenticationAndAuthorization (cfg )
171
+ if err != nil {
172
+ return err
173
+ }
174
+
175
+ mux := http .NewServeMux ()
176
+ mux .Handle (defaultMetricsEndpoint , h )
177
+
178
+ srv := & http.Server {
179
+ Addr : net .JoinHostPort ("" , strconv .Itoa (port )),
180
+ Handler : mux ,
181
+ }
182
+
183
+ if err := mgr .Add (& manager.Server {
184
+ Name : "metrics" ,
185
+ Server : srv ,
186
+ }); err != nil {
187
+ klog .ErrorS (err , "Failed to register metrics HTTP handler" )
188
+ return err
189
+ }
190
+ return nil
190
191
}
191
192
192
- func metricsHandlerWithAuthenticationAndAuthorization (cfg * rest.Config ) http.Handler {
193
+ func metricsHandlerWithAuthenticationAndAuthorization (cfg * rest.Config ) ( http.Handler , error ) {
193
194
h := promhttp .HandlerFor (
194
195
legacyregistry .DefaultGatherer ,
195
196
promhttp.HandlerOpts {},
196
197
)
197
198
httpClient , err := rest .HTTPClientFor (cfg )
198
199
if err != nil {
199
- klog .Fatalf ("failed to create http client for metrics auth: %v" , err )
200
+ klog .ErrorS (err , "Failed to create http client for metrics auth" )
201
+ return nil , err
200
202
}
201
203
202
204
filter , err := filters .WithAuthenticationAndAuthorization (cfg , httpClient )
203
205
if err != nil {
204
- klog .Fatalf ("failed to create metrics filter for auth: %v" , err )
206
+ klog .ErrorS (err , "Failed to create metrics filter for auth" )
207
+ return nil , err
205
208
}
206
209
metricsLogger := klog .LoggerWithValues (klog .NewKlogr (), "path" , defaultMetricsEndpoint )
207
210
metricsAuthHandler , err := filter (metricsLogger , h )
208
211
if err != nil {
209
- klog .Fatalf ("failed to create metrics auth handler: %v" , err )
212
+ klog .ErrorS (err , "Failed to create metrics auth handler" )
213
+ return nil , err
210
214
}
211
- return metricsAuthHandler
215
+ return metricsAuthHandler , nil
212
216
}
213
217
214
218
func validateFlags () error {
0 commit comments