Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into dz-iss2142
Browse files Browse the repository at this point in the history
  • Loading branch information
zaratsian committed Oct 13, 2021
2 parents 31ee49a + ddd9806 commit 660ec13
Show file tree
Hide file tree
Showing 51 changed files with 966 additions and 248 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ build/allocation
/release
debug.test
obj
test/sdk/cpp/sdk/
97 changes: 82 additions & 15 deletions CHANGELOG.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#

# base version target. This is usually the next release.
base_version = 1.18.0
base_version = 1.19.0

# agones image release registry
release_registry = gcr.io/agones-images
Expand Down Expand Up @@ -328,11 +328,11 @@ install: $(ensure-build-image) install-custom-pull-secret
--set agones.image.controller.pullPolicy=$(IMAGE_PULL_POLICY),agones.image.sdk.alwaysPull=$(ALWAYS_PULL_SIDECAR) \
--set agones.image.controller.pullSecret=$(IMAGE_PULL_SECRET) \
--set agones.ping.http.serviceType=$(PING_SERVICE_TYPE),agones.ping.udp.serviceType=$(PING_SERVICE_TYPE) \
--set agones.allocator.http.serviceType=$(ALLOCATOR_SERVICE_TYPE) \
--set agones.allocator.service.serviceType=$(ALLOCATOR_SERVICE_TYPE) \
--set agones.controller.logLevel=$(LOG_LEVEL) \
--set agones.crds.cleanupOnDelete=$(CRD_CLEANUP) \
--set agones.featureGates=$(FEATURE_GATES) \
--set agones.allocator.http.loadBalancerIP=$(EXTERNAL_IP) \
--set agones.allocator.service.loadBalancerIP=$(EXTERNAL_IP) \
$(HELM_ARGS) \
agones $(mount_path)/install/helm/agones/

Expand Down
2 changes: 1 addition & 1 deletion build/build-image/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ RUN curl -L ${HELM_URL} > /tmp/helm.tar.gz \
RUN echo "source <(helm completion bash)" >> /root/.bashrc

# install golang-ci linter
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin v1.30.0
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin v1.42.1

#
# \ \ / /__| |__ ___(_) |_ ___
Expand Down
1 change: 1 addition & 0 deletions build/includes/website.mk
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ site-images: $(site_path)/static/diagrams/gameserver-reserved.puml.png
site-images: $(site_path)/static/diagrams/canary-testing.puml.png
site-images: $(site_path)/static/diagrams/allocation-player-capacity.puml.png
site-images: $(site_path)/static/diagrams/reusing-gameservers.puml.png
site-images: $(site_path)/static/diagrams/high-density.puml.png

# generate pngs from dot files
%.dot.png: %.dot
Expand Down
2 changes: 1 addition & 1 deletion cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ steps:
#

- name: 'e2e-runner'
args: ['PlayerTracking=true&SDKWatchSendOnExecute=false&RollingUpdateOnReady=false&NodeExternalDNS=true&StateAllocationFilter=true&PlayerAllocationFilter=true&CustomFasSyncInterval=true', 'e2e-test-cluster']
args: ['PlayerTracking=true&SDKWatchSendOnExecute=false&NodeExternalDNS=true&StateAllocationFilter=true&PlayerAllocationFilter=true&CustomFasSyncInterval=true', 'e2e-test-cluster']
id: e2e-feature-gates
waitFor:
- push-images
Expand Down
126 changes: 107 additions & 19 deletions cmd/allocator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"crypto/x509"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"path/filepath"
Expand All @@ -43,6 +44,7 @@ import (
"go.opencensus.io/plugin/ocgrpc"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/status"
"gopkg.in/fsnotify.v1"
Expand All @@ -53,14 +55,11 @@ import (
"k8s.io/client-go/rest"
)

var (
logger = runtime.NewLoggerWithSource("main")
)
var logger = runtime.NewLoggerWithSource("main")

const (
certDir = "/home/allocator/client-ca/"
tlsDir = "/home/allocator/tls/"
sslPort = "8443"
)

// grpcHandlerFunc returns an http.Handler that delegates to grpcServer on incoming gRPC
Expand All @@ -80,7 +79,7 @@ func main() {
conf := parseEnvFlags()

logger.WithField("version", pkg.Version).WithField("ctlConf", conf).
WithField("featureGates", runtime.EncodeFeatures()).WithField("sslPort", sslPort).
WithField("featureGates", runtime.EncodeFeatures()).
Info("Starting agones-allocator")

logger.WithField("logLevel", conf.LogLevel).Info("Setting LogLevel configuration")
Expand All @@ -92,6 +91,10 @@ func main() {
runtime.SetLevel(logrus.InfoLevel)
}

if !validPort(conf.GRPCPort) && !validPort(conf.HTTPPort) {
logger.WithField("grpc-port", conf.GRPCPort).WithField("http-port", conf.HTTPPort).Fatal("Must specify a valid gRPC port or an HTTP port for the allocator service")
}

health, closer := setupMetricsRecorder(conf)
defer closer()

Expand Down Expand Up @@ -181,17 +184,53 @@ func main() {
}
}

opts := h.getServerOptions()
// If grpc and http use the same port then use a mux.
if conf.GRPCPort == conf.HTTPPort {
runMux(h, conf.HTTPPort)
} else {
// Otherwise, run each on a dedicated port.
if validPort(conf.HTTPPort) {
runREST(h, conf.HTTPPort)
}
if validPort(conf.GRPCPort) {
runGRPC(h, conf.GRPCPort)
}
}

// Finally listen on 8080 (http) and block the main goroutine
// this is used to serve /live and /ready handlers for Kubernetes probes.
err = http.ListenAndServe(":8080", http.DefaultServeMux)
logger.WithError(err).Fatal("allocation service crashed")
}

func validPort(port int) bool {
const maxPort = 65535
return port >= 0 && port < maxPort
}

grpcServer := grpc.NewServer(opts...)
func runMux(h *serviceHandler, httpPort int) {
logger.Infof("Running the mux handler on port %d", httpPort)
grpcServer := grpc.NewServer(h.getMuxServerOptions()...)
pb.RegisterAllocationServiceServer(grpcServer, h)

mux := gw_runtime.NewServeMux()
err = pb.RegisterAllocationServiceHandlerServer(context.Background(), mux, h)
if err != nil {
if err := pb.RegisterAllocationServiceHandlerServer(context.Background(), mux, h); err != nil {
panic(err)
}

runHTTP(h, httpPort, grpcHandlerFunc(grpcServer, mux))
}

func runREST(h *serviceHandler, httpPort int) {
logger.WithField("port", httpPort).Info("Running the rest handler")
mux := gw_runtime.NewServeMux()
if err := pb.RegisterAllocationServiceHandlerServer(context.Background(), mux, h); err != nil {
panic(err)
}
runHTTP(h, httpPort, mux)
}

func runHTTP(h *serviceHandler, httpPort int, handler http.Handler) {
cfg := &tls.Config{}
if !h.tlsDisabled {
cfg.GetCertificate = h.getTLSCert
Expand All @@ -201,30 +240,44 @@ func main() {
cfg.VerifyPeerCertificate = h.verifyClientCertificate
}

// Create a Server instance to listen on port 8443 with the TLS config
// Create a Server instance to listen on the http port with the TLS config.
server := &http.Server{
Addr: ":8443",
Addr: fmt.Sprintf(":%d", httpPort),
TLSConfig: cfg,
Handler: grpcHandlerFunc(grpcServer, mux),
Handler: handler,
}

go func() {
var err error
if !h.tlsDisabled {
err = server.ListenAndServeTLS("", "")
} else {
err = server.ListenAndServe()
}

if err != nil {
logger.WithError(err).Fatal("unable to start HTTP/HTTPS listener")
logger.WithError(err).Fatal("Unable to start HTTP/HTTPS listener")
os.Exit(1)
}
}()
}

// Finally listen on 8080 (http) and block the main goroutine
// this is used to serve /live and /ready handlers for Kubernetes probes.
err = http.ListenAndServe(":8080", http.DefaultServeMux)
logger.WithError(err).Fatal("allocation service crashed")
func runGRPC(h *serviceHandler, grpcPort int) {
logger.WithField("port", grpcPort).Info("Running the grpc handler on port")
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort))
if err != nil {
logger.WithError(err).Fatalf("failed to listen on TCP port %d", grpcPort)
os.Exit(1)
}

grpcServer := grpc.NewServer(h.getGRPCServerOptions()...)
pb.RegisterAllocationServiceServer(grpcServer, h)

go func() {
err := grpcServer.Serve(listener)
logger.WithError(err).Fatal("allocation service crashed")
os.Exit(1)
}()
}

func newServiceHandler(kubeClient kubernetes.Interface, agonesClient versioned.Interface, health healthcheck.Handler, mTLSDisabled bool, tlsDisabled bool, remoteAllocationTimeout time.Duration, totalRemoteAllocationTimeout time.Duration) *serviceHandler {
Expand Down Expand Up @@ -288,9 +341,10 @@ func readTLSCert() (*tls.Certificate, error) {
return &tlsCert, nil
}

// getServerOptions returns a list of GRPC server options.
// getMuxServerOptions returns a list of GRPC server option to use when
// serving gRPC and REST over an HTTP multiplexer.
// Current options are opencensus stats handler.
func (h *serviceHandler) getServerOptions() []grpc.ServerOption {
func (h *serviceHandler) getMuxServerOptions() []grpc.ServerOption {
// Add options for OpenCensus stats handler to enable stats and tracing.
// The keepalive options are useful for efficiency purposes (keeping a single connection alive
// instead of constantly recreating connections), when placing the Agones allocator behind load balancers.
Expand All @@ -307,6 +361,40 @@ func (h *serviceHandler) getServerOptions() []grpc.ServerOption {
}
}

// getGRPCServerOptions returns a list of GRPC server options to use when
// only serving gRPC requests.
// Current options are TLS certs and opencensus stats handler.
func (h *serviceHandler) getGRPCServerOptions() []grpc.ServerOption {
// Add options for OpenCensus stats handler to enable stats and tracing.
// The keepalive options are useful for efficiency purposes (keeping a single connection alive
// instead of constantly recreating connections), when placing the Agones allocator behind load balancers.
opts := []grpc.ServerOption{
grpc.StatsHandler(&ocgrpc.ServerHandler{}),
grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
MinTime: 1 * time.Minute,
PermitWithoutStream: true,
}),
grpc.KeepaliveParams(keepalive.ServerParameters{
MaxConnectionIdle: 5 * time.Minute,
Timeout: 10 * time.Minute,
}),
}
if h.tlsDisabled {
return opts
}

cfg := &tls.Config{
GetCertificate: h.getTLSCert,
}

if !h.mTLSDisabled {
cfg.ClientAuth = tls.RequireAnyClientCert
cfg.VerifyPeerCertificate = h.verifyClientCertificate
}

return append([]grpc.ServerOption{grpc.Creds(credentials.NewTLS(cfg))}, opts...)
}

func (h *serviceHandler) getTLSCert(ch *tls.ClientHelloInfo) (*tls.Certificate, error) {
h.tlsMutex.RLock()
defer h.tlsMutex.RUnlock()
Expand Down
12 changes: 12 additions & 0 deletions cmd/allocator/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
)

const (
httpPortFlag = "http-port"
grpcPortFlag = "grpc-port"
enableStackdriverMetricsFlag = "stackdriver-exporter"
enablePrometheusMetricsFlag = "prometheus-exporter"
projectIDFlag = "gcp-project-id"
Expand All @@ -47,6 +49,8 @@ func init() {
}

type config struct {
GRPCPort int
HTTPPort int
APIServerSustainedQPS int
APIServerBurstQPS int
TLSDisabled bool
Expand All @@ -62,6 +66,8 @@ type config struct {

func parseEnvFlags() config {

viper.SetDefault(httpPortFlag, -1)
viper.SetDefault(grpcPortFlag, -1)
viper.SetDefault(apiServerSustainedQPSFlag, 400)
viper.SetDefault(apiServerBurstQPSFlag, 500)
viper.SetDefault(enablePrometheusMetricsFlag, true)
Expand All @@ -74,6 +80,8 @@ func parseEnvFlags() config {
viper.SetDefault(totalRemoteAllocationTimeoutFlag, 30*time.Second)
viper.SetDefault(logLevelFlag, "Info")

pflag.Int32(httpPortFlag, viper.GetInt32(httpPortFlag), "Port to listen on for REST requests")
pflag.Int32(grpcPortFlag, viper.GetInt32(grpcPortFlag), "Port to listen on for gRPC requests")
pflag.Int32(apiServerSustainedQPSFlag, viper.GetInt32(apiServerSustainedQPSFlag), "Maximum sustained queries per second to send to the API server")
pflag.Int32(apiServerBurstQPSFlag, viper.GetInt32(apiServerBurstQPSFlag), "Maximum burst queries per second to send to the API server")
pflag.Bool(enablePrometheusMetricsFlag, viper.GetBool(enablePrometheusMetricsFlag), "Flag to activate metrics of Agones. Can also use PROMETHEUS_EXPORTER env variable.")
Expand All @@ -89,6 +97,8 @@ func parseEnvFlags() config {
pflag.Parse()

viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
runtime.Must(viper.BindEnv(httpPortFlag))
runtime.Must(viper.BindEnv(grpcPortFlag))
runtime.Must(viper.BindEnv(apiServerSustainedQPSFlag))
runtime.Must(viper.BindEnv(apiServerBurstQPSFlag))
runtime.Must(viper.BindEnv(enablePrometheusMetricsFlag))
Expand All @@ -104,6 +114,8 @@ func parseEnvFlags() config {
runtime.Must(runtime.ParseFeaturesFromEnv())

return config{
HTTPPort: int(viper.GetInt32(httpPortFlag)),
GRPCPort: int(viper.GetInt32(grpcPortFlag)),
APIServerSustainedQPS: int(viper.GetInt32(apiServerSustainedQPSFlag)),
APIServerBurstQPS: int(viper.GetInt32(apiServerBurstQPSFlag)),
PrometheusMetrics: viper.GetBool(enablePrometheusMetricsFlag),
Expand Down
5 changes: 4 additions & 1 deletion cmd/sdk-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func main() {
}

ctx := signals.NewSigKillContext()

grpcServer := grpc.NewServer()
// don't graceful stop, because if we get a SIGKILL signal
// then the gameserver is being shut down, and we no longer
Expand Down Expand Up @@ -139,7 +140,9 @@ func main() {
if err != nil {
logger.WithError(err).Fatalf("Could not start sidecar")
}

if runtime.FeatureEnabled(runtime.FeatureSDKGracefulTermination) {
ctx = s.NewSDKServerContext(ctx)
}
go func() {
err := s.Run(ctx)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions docs/governance/templates/release_issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ and copy it into a release issue. Fill in relevant values, found inside {}
## Steps

- [ ] Run `make shell` and run `gcloud config configurations activate agones-images`.
- [ ] Review [closed issues with no milestone](https://github.com/googleforgames/agones/issues?q=is%3Aissue+is%3Aclosed+no%3Amilestone) and add relevant ones to the current milestone.
- Issues tagged as `invalid`, `duplicate`, `question`, or `wontfix` can be ignored
- [ ] Review [closed issues with no milestone](https://github.com/googleforgames/agones/issues?q=is%3Aissue+is%3Aclosed+no%3Amilestone++-label%3Ainvalid+-label%3Aduplicate+-label%3Aquestion+-label%3Awontfix++-label%3Aarea%2Fmeta) and add relevant ones to the current milestone.
- Issues tagged as `invalid`, `duplicate`, `question`, `wontfix`, or `area/meta` can be ignored
- [ ] Review closed issues in the current milestone to ensure that they have appropriate tags.
- [ ] Review [merged PRs that have no milestone](https://github.com/googleforgames/agones/pulls?q=is%3Apr+is%3Amerged+no%3Amilestone+) and add them to the current milestone.
- [ ] Review merged PRs in the current milestone to ensure that they have appropriate tags.
Expand Down
4 changes: 2 additions & 2 deletions install/helm/agones/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
# Declare variables to be passed into your templates.

apiVersion: v1
appVersion: "1.18.0-dev"
version: 1.18.0-dev
appVersion: "1.19.0-dev"
version: 1.19.0-dev
name: agones
description: a library for hosting, running and scaling dedicated game servers on Kubernetes.
keywords:
Expand Down
Loading

0 comments on commit 660ec13

Please sign in to comment.