Skip to content

Commit 5791909

Browse files
authored
[ws-proxy] Implement graceful shutdown (#18583)
* [ws-proxy] Implement graceful shutdown * Align termination grace period with http shutdown timeout * Address feedback * Configure http server timeouts
1 parent bc12275 commit 5791909

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed

components/ws-proxy/cmd/run.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"time"
1414

1515
"github.com/bombsimon/logrusr/v2"
16-
"github.com/gitpod-io/golang-crypto/ssh"
1716
"github.com/spf13/cobra"
1817
"google.golang.org/grpc"
1918
"google.golang.org/grpc/credentials"
@@ -36,6 +35,7 @@ import (
3635
"github.com/gitpod-io/gitpod/ws-proxy/pkg/config"
3736
"github.com/gitpod-io/gitpod/ws-proxy/pkg/proxy"
3837
"github.com/gitpod-io/gitpod/ws-proxy/pkg/sshproxy"
38+
"github.com/gitpod-io/golang-crypto/ssh"
3939
)
4040

4141
var (
@@ -159,11 +159,15 @@ var runCmd = &cobra.Command{
159159
}
160160
}
161161

162-
go proxy.NewWorkspaceProxy(cfg.Ingress, cfg.Proxy, proxy.HostBasedRouter(cfg.Ingress.Header, cfg.Proxy.GitpodInstallation.WorkspaceHostSuffix, cfg.Proxy.GitpodInstallation.WorkspaceHostSuffixRegex), infoprov, signers).MustServe()
163-
log.Infof("started proxying on %s", cfg.Ingress.HTTPAddress)
162+
ctrlCtx := ctrl.SetupSignalHandler()
163+
164+
go func() {
165+
log.Infof("startint proxying on %s", cfg.Ingress.HTTPAddress)
166+
proxy.NewWorkspaceProxy(cfg.Ingress, cfg.Proxy, proxy.HostBasedRouter(cfg.Ingress.Header, cfg.Proxy.GitpodInstallation.WorkspaceHostSuffix, cfg.Proxy.GitpodInstallation.WorkspaceHostSuffixRegex), infoprov, signers).MustServe(ctrlCtx)
167+
}()
164168

165169
log.Info("🚪 ws-proxy is up and running")
166-
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
170+
if err := mgr.Start(ctrlCtx); err != nil {
167171
log.WithError(err).Fatal(err, "problem starting ws-proxy")
168172
}
169173

components/ws-proxy/pkg/proxy/proxy.go

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ package proxy
66

77
import (
88
"bytes"
9+
"context"
910
"crypto/tls"
11+
"errors"
1012
stdlog "log"
1113
"net/http"
1214
"os"
1315
"path/filepath"
16+
"time"
1417

1518
"github.com/gorilla/mux"
1619
"github.com/klauspost/cpuid/v2"
@@ -49,13 +52,26 @@ func redirectToHTTPS(w http.ResponseWriter, r *http.Request) {
4952
}
5053

5154
// MustServe starts the proxy and ends the process if doing so fails.
52-
func (p *WorkspaceProxy) MustServe() {
55+
func (p *WorkspaceProxy) MustServe(ctx context.Context) {
5356
handler, err := p.Handler()
5457
if err != nil {
5558
log.WithError(err).Fatal("cannot initialize proxy - this is likely a configuration issue")
5659
return
5760
}
58-
srv := &http.Server{
61+
62+
httpServer := &http.Server{
63+
Addr: p.Ingress.HTTPAddress,
64+
Handler: http.HandlerFunc(redirectToHTTPS),
65+
ErrorLog: stdlog.New(logrusErrorWriter{}, "", 0),
66+
ReadTimeout: 1 * time.Second,
67+
WriteTimeout: 1 * time.Second,
68+
IdleTimeout: 0,
69+
ReadHeaderTimeout: 2 * time.Second,
70+
}
71+
72+
httpServer.SetKeepAlivesEnabled(false)
73+
74+
httpsServer := &http.Server{
5975
Addr: p.Ingress.HTTPSAddress,
6076
Handler: handler,
6177
TLSConfig: &tls.Config{
@@ -77,17 +93,35 @@ func (p *WorkspaceProxy) MustServe() {
7793
crt = filepath.Join(tproot, crt)
7894
key = filepath.Join(tproot, key)
7995
}
96+
8097
go func() {
81-
err := http.ListenAndServe(p.Ingress.HTTPAddress, http.HandlerFunc(redirectToHTTPS))
82-
if err != nil {
98+
err := httpServer.ListenAndServe()
99+
if err != nil && !errors.Is(err, http.ErrServerClosed) {
83100
log.WithError(err).Fatal("cannot start http proxy")
84101
}
85102
}()
86103

87-
err = srv.ListenAndServeTLS(crt, key)
104+
go func() {
105+
err = httpsServer.ListenAndServeTLS(crt, key)
106+
if err != nil && !errors.Is(err, http.ErrServerClosed) {
107+
log.WithError(err).Fatal("cannot start proxy")
108+
return
109+
}
110+
}()
111+
112+
<-ctx.Done()
113+
114+
shutDownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
115+
defer cancel()
116+
117+
err = httpServer.Shutdown(shutDownCtx)
88118
if err != nil {
89-
log.WithError(err).Fatal("cannot start proxy")
90-
return
119+
log.WithError(err).Fatal("cannot stop HTTP server")
120+
}
121+
122+
err = httpsServer.Shutdown(shutDownCtx)
123+
if err != nil {
124+
log.WithError(err).Fatal("cannot stop HTTPS server")
91125
}
92126
}
93127

install/installer/pkg/components/ws-proxy/deployment.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {
7070
SecurityContext: &corev1.PodSecurityContext{
7171
RunAsUser: pointer.Int64(31002),
7272
},
73+
TerminationGracePeriodSeconds: pointer.Int64(360),
7374
Volumes: append([]corev1.Volume{
7475
{
7576
Name: "config",

0 commit comments

Comments
 (0)