Skip to content

Commit

Permalink
Add Security Context to game server sidecar (#3869)
Browse files Browse the repository at this point in the history
* Add Security Context to controller sidecar
  • Loading branch information
peterzhongyi committed Jun 17, 2024
1 parent 6bc20a1 commit 77e4f43
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 5 deletions.
8 changes: 7 additions & 1 deletion cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const (
sidecarCPULimitFlag = "sidecar-cpu-limit"
sidecarMemoryRequestFlag = "sidecar-memory-request"
sidecarMemoryLimitFlag = "sidecar-memory-limit"
sidecarRunAsUserFlag = "sidecar-run-as-user"
sdkServerAccountFlag = "sdk-service-account"
pullSidecarFlag = "always-pull-sidecar"
minPortFlag = "min-port"
Expand Down Expand Up @@ -214,7 +215,7 @@ func main() {
gsController := gameservers.NewController(controllerHooks, health,
ctlConf.PortRanges, ctlConf.SidecarImage, ctlConf.AlwaysPullSidecar,
ctlConf.SidecarCPURequest, ctlConf.SidecarCPULimit,
ctlConf.SidecarMemoryRequest, ctlConf.SidecarMemoryLimit, ctlConf.SdkServiceAccount,
ctlConf.SidecarMemoryRequest, ctlConf.SidecarMemoryLimit, ctlConf.SidecarRunAsUser, ctlConf.SdkServiceAccount,
kubeClient, kubeInformerFactory, extClient, agonesClient, agonesInformerFactory)
gsSetController := gameserversets.NewController(health, gsCounter,
kubeClient, extClient, agonesClient, agonesInformerFactory)
Expand Down Expand Up @@ -260,6 +261,7 @@ func parseEnvFlags() config {
viper.SetDefault(sidecarCPULimitFlag, "0")
viper.SetDefault(sidecarMemoryRequestFlag, "0")
viper.SetDefault(sidecarMemoryLimitFlag, "0")
viper.SetDefault(sidecarRunAsUserFlag, "1000")
viper.SetDefault(pullSidecarFlag, false)
viper.SetDefault(sdkServerAccountFlag, "agones-sdk")
viper.SetDefault(certFileFlag, filepath.Join(base, "certs", "server.crt"))
Expand All @@ -284,6 +286,7 @@ func parseEnvFlags() config {
pflag.String(sidecarCPURequestFlag, viper.GetString(sidecarCPURequestFlag), "Flag to overwrite the GameServer sidecar container's cpu request. Can also use SIDECAR_CPU_REQUEST env variable")
pflag.String(sidecarMemoryLimitFlag, viper.GetString(sidecarMemoryLimitFlag), "Flag to overwrite the GameServer sidecar container's memory limit. Can also use SIDECAR_MEMORY_LIMIT env variable")
pflag.String(sidecarMemoryRequestFlag, viper.GetString(sidecarMemoryRequestFlag), "Flag to overwrite the GameServer sidecar container's memory request. Can also use SIDECAR_MEMORY_REQUEST env variable")
pflag.Int32(sidecarRunAsUserFlag, viper.GetInt32(sidecarRunAsUserFlag), "Flag to indicate the GameServer sidecar container's UID. Can also use SIDECAR_RUN_AS_USER env variable")
pflag.Bool(pullSidecarFlag, viper.GetBool(pullSidecarFlag), "For development purposes, set the sidecar image to have a ImagePullPolicy of Always. Can also use ALWAYS_PULL_SIDECAR env variable")
pflag.String(sdkServerAccountFlag, viper.GetString(sdkServerAccountFlag), "Overwrite what service account default for GameServer Pods. Defaults to Can also use SDK_SERVICE_ACCOUNT")
pflag.Int32(minPortFlag, 0, "Required. The minimum port that that a GameServer can be allocated to. Can also use MIN_PORT env variable.")
Expand Down Expand Up @@ -315,6 +318,7 @@ func parseEnvFlags() config {
runtime.Must(viper.BindEnv(sidecarCPURequestFlag))
runtime.Must(viper.BindEnv(sidecarMemoryLimitFlag))
runtime.Must(viper.BindEnv(sidecarMemoryRequestFlag))
runtime.Must(viper.BindEnv(sidecarRunAsUserFlag))
runtime.Must(viper.BindEnv(pullSidecarFlag))
runtime.Must(viper.BindEnv(sdkServerAccountFlag))
runtime.Must(viper.BindEnv(minPortFlag))
Expand Down Expand Up @@ -378,6 +382,7 @@ func parseEnvFlags() config {
SidecarCPULimit: limitCPU,
SidecarMemoryRequest: requestMemory,
SidecarMemoryLimit: limitMemory,
SidecarRunAsUser: int(viper.GetInt32(sidecarRunAsUserFlag)),
SdkServiceAccount: viper.GetString(sdkServerAccountFlag),
AlwaysPullSidecar: viper.GetBool(pullSidecarFlag),
KeyFile: viper.GetString(keyFileFlag),
Expand Down Expand Up @@ -430,6 +435,7 @@ type config struct {
SidecarCPULimit resource.Quantity
SidecarMemoryRequest resource.Quantity
SidecarMemoryLimit resource.Quantity
SidecarRunAsUser int
SdkServiceAccount string
AlwaysPullSidecar bool
PrometheusMetrics bool
Expand Down
2 changes: 2 additions & 0 deletions install/helm/agones/templates/controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ spec:
value: {{ .Values.agones.image.sdk.memoryRequest | quote }}
- name: SIDECAR_MEMORY_LIMIT
value: {{ .Values.agones.image.sdk.memoryLimit | quote }}
- name: SIDECAR_RUN_AS_USER
value: "1000"
- name: SDK_SERVICE_ACCOUNT
value: {{ .Values.agones.serviceaccount.sdk.name | quote }}
- name: PROMETHEUS_EXPORTER
Expand Down
2 changes: 2 additions & 0 deletions install/yaml/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17084,6 +17084,8 @@ spec:
value: "0"
- name: SIDECAR_MEMORY_LIMIT
value: "0"
- name: SIDECAR_RUN_AS_USER
value: "1000"
- name: SDK_SERVICE_ACCOUNT
value: "agones-sdk"
- name: PROMETHEUS_EXPORTER
Expand Down
11 changes: 11 additions & 0 deletions pkg/gameservers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"k8s.io/utils/pointer"
)

const (
Expand Down Expand Up @@ -83,6 +84,7 @@ type Controller struct {
sidecarCPULimit resource.Quantity
sidecarMemoryRequest resource.Quantity
sidecarMemoryLimit resource.Quantity
sidecarRunAsUser int
sdkServiceAccount string
crdGetter apiextclientv1.CustomResourceDefinitionInterface
podGetter typedcorev1.PodsGetter
Expand Down Expand Up @@ -114,6 +116,7 @@ func NewController(
sidecarCPULimit resource.Quantity,
sidecarMemoryRequest resource.Quantity,
sidecarMemoryLimit resource.Quantity,
sidecarRunAsUser int,
sdkServiceAccount string,
kubeClient kubernetes.Interface,
kubeInformerFactory informers.SharedInformerFactory,
Expand All @@ -133,6 +136,7 @@ func NewController(
sidecarCPURequest: sidecarCPURequest,
sidecarMemoryLimit: sidecarMemoryLimit,
sidecarMemoryRequest: sidecarMemoryRequest,
sidecarRunAsUser: sidecarRunAsUser,
alwaysPullSidecarImage: alwaysPullSidecarImage,
sdkServiceAccount: sdkServiceAccount,
crdGetter: extClient.ApiextensionsV1().CustomResourceDefinitions(),
Expand Down Expand Up @@ -763,6 +767,13 @@ func (c *Controller) sidecar(gs *agonesv1.GameServer) corev1.Container {
if c.alwaysPullSidecarImage {
sidecar.ImagePullPolicy = corev1.PullAlways
}

sidecar.SecurityContext = &corev1.SecurityContext{
AllowPrivilegeEscalation: pointer.Bool(false),
RunAsNonRoot: pointer.Bool(true),
RunAsUser: pointer.Int64(int64(c.sidecarRunAsUser)),
}

return sidecar
}

Expand Down
12 changes: 8 additions & 4 deletions pkg/gameservers/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ import (
)

const (
ipFixture = "12.12.12.12"
ipv6Fixture = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
nodeFixtureName = "node1"
ipFixture = "12.12.12.12"
ipv6Fixture = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
nodeFixtureName = "node1"
sidecarRunAsUser = 1000
)

var GameServerKind = metav1.GroupVersionKind(agonesv1.SchemeGroupVersion.WithKind("GameServer"))
Expand Down Expand Up @@ -1306,6 +1307,9 @@ func TestControllerCreateGameServerPod(t *testing.T) {
assert.Equal(t, "FEATURE_GATES", sidecarContainer.Env[2].Name)
assert.Equal(t, "LOG_LEVEL", sidecarContainer.Env[3].Name)
assert.Equal(t, string(fixture.Spec.SdkServer.LogLevel), sidecarContainer.Env[3].Value)
assert.Equal(t, *sidecarContainer.SecurityContext.AllowPrivilegeEscalation, false)
assert.Equal(t, *sidecarContainer.SecurityContext.RunAsNonRoot, true)
assert.Equal(t, *sidecarContainer.SecurityContext.RunAsUser, int64(sidecarRunAsUser))

gsContainer := pod.Spec.Containers[1]
assert.Equal(t, fixture.Spec.Ports[0].HostPort, gsContainer.Ports[0].HostPort)
Expand Down Expand Up @@ -2257,7 +2261,7 @@ func newFakeController() (*Controller, agtesting.Mocks) {
map[string]portallocator.PortRange{agonesv1.DefaultPortRange: {MinPort: 10, MaxPort: 20}},
"sidecar:dev", false,
resource.MustParse("0.05"), resource.MustParse("0.1"),
resource.MustParse("50Mi"), resource.MustParse("100Mi"), "sdk-service-account",
resource.MustParse("50Mi"), resource.MustParse("100Mi"), sidecarRunAsUser, "sdk-service-account",
m.KubeClient, m.KubeInformerFactory, m.ExtClient, m.AgonesClient, m.AgonesInformerFactory)
c.recorder = m.FakeRecorder
return c, m
Expand Down

0 comments on commit 77e4f43

Please sign in to comment.