diff --git a/cmd/backplane/main.go b/cmd/backplane/main.go index c5a77d34..9056a211 100644 --- a/cmd/backplane/main.go +++ b/cmd/backplane/main.go @@ -30,6 +30,7 @@ import ( "github.com/apoxy-dev/apoxy/pkg/apiserver" bpctrl "github.com/apoxy-dev/apoxy/pkg/backplane/controllers" + "github.com/apoxy-dev/apoxy/pkg/backplane/envoy" "github.com/apoxy-dev/apoxy/pkg/backplane/healthchecker" "github.com/apoxy-dev/apoxy/pkg/backplane/kvstore" "github.com/apoxy-dev/apoxy/pkg/backplane/metrics" @@ -66,6 +67,7 @@ var ( proxyName = flag.String("proxy", "", "Name of the Proxy to manage. Must not be used with --proxy_path.") replicaName = flag.String("replica", os.Getenv("HOSTNAME"), "Name of the replica to manage.") envoyReleaseURL = flag.String("envoy_release_url", "", "URL to the Envoy release tarball.") + envoyVersion = flag.String("envoy_version", envoy.DefaultVersion, "Envoy release tag to download from GitHub (e.g. v1.35.13). Empty means latest upstream release — never use that in production. Ignored when --envoy_release_url is set.") downloadEnvoy = flag.Bool("download_envoy_only", false, "Whether to just download Envoy from the release URL and exit.") apiServerAddr = flag.String("apiserver_addr", "host.docker.internal:8443", "APIServer address.") @@ -256,6 +258,9 @@ func main() { if *useEnvoyContrib { proxyOpts = append(proxyOpts, bpctrl.WithEnvoyContrib()) } + if *envoyVersion != "" { + proxyOpts = append(proxyOpts, bpctrl.WithEnvoyVersion(*envoyVersion)) + } if *overloadMaxHeapSizeBytes > 0 { proxyOpts = append(proxyOpts, bpctrl.WithOverloadMaxHeapSizeBytes(*overloadMaxHeapSizeBytes)) } diff --git a/pkg/backplane/controllers/proxy.go b/pkg/backplane/controllers/proxy.go index e930dc51..79720cd1 100644 --- a/pkg/backplane/controllers/proxy.go +++ b/pkg/backplane/controllers/proxy.go @@ -52,6 +52,7 @@ type options struct { apiServerTLSClientConfig *tls.Config goPluginDir string releaseURL string + envoyVersion string useEnvoyContrib bool overloadMaxHeapSizeBytes *uint64 overloadMaxActiveConnections *uint64 @@ -104,6 +105,15 @@ func WithEnvoyContrib() Option { } } +// WithEnvoyVersion pins the Envoy release tag (e.g. "v1.35.13") downloaded +// from GitHub. An empty version falls back to the latest upstream release — +// never do that in production builds; see envoy.DefaultVersion for why. +func WithEnvoyVersion(version string) Option { + return func(o *options) { + o.envoyVersion = version + } +} + // WithOverloadMaxHeapSizeBytes sets the maximum heap size in bytes for the Envoy overload manager. func WithOverloadMaxHeapSizeBytes(size uint64) Option { return func(o *options) { @@ -240,9 +250,10 @@ func (r *ProxyReconciler) Reconcile(ctx context.Context, request reconcile.Reque opts = append(opts, envoy.WithRelease(&envoy.URLRelease{ URL: r.options.releaseURL, })) - } else if r.options.useEnvoyContrib { + } else if r.options.useEnvoyContrib || r.options.envoyVersion != "" { opts = append(opts, envoy.WithRelease(&envoy.GitHubRelease{ - Contrib: true, + Version: r.options.envoyVersion, + Contrib: r.options.useEnvoyContrib, })) } @@ -335,9 +346,10 @@ func (r *ProxyReconciler) DownloadEnvoy(ctx context.Context) error { opts = append(opts, envoy.WithRelease(&envoy.URLRelease{ URL: r.options.releaseURL, })) - } else if r.options.useEnvoyContrib { + } else if r.options.useEnvoyContrib || r.options.envoyVersion != "" { opts = append(opts, envoy.WithRelease(&envoy.GitHubRelease{ - Contrib: true, + Version: r.options.envoyVersion, + Contrib: r.options.useEnvoyContrib, })) } diff --git a/pkg/backplane/envoy/run.go b/pkg/backplane/envoy/run.go index 46147969..b6719f7d 100644 --- a/pkg/backplane/envoy/run.go +++ b/pkg/backplane/envoy/run.go @@ -31,6 +31,16 @@ import ( const ( githubURL = "github.com/envoyproxy/envoy/releases/download" + // DefaultVersion pins the Envoy release baked into backplane images and + // downloaded at runtime. Envoy versions must never float: the 1.35.3 → + // 1.38.x jump (picked up implicitly via GetLatestRelease when the + // v0.11.22/23 images were built) regressed the golang filter with a + // tcmalloc SIGSEGV on the cgo thread-adoption path (x_cgo_getstackbound + // → pthread_getattr_np → calloc). 1.35.13 is the same minor as the + // last known-good 1.35.3 plus upstream security backports. Bump only + // after soak-testing the golang filter under listener-reload churn. + DefaultVersion = "v1.35.13" + accessLogsPath = "/var/log/accesslogs" tapsPath = "/var/log/taps"