Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Security Context to game server sidecar #3869

Merged
merged 5 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
zmerlynn marked this conversation as resolved.
Show resolved Hide resolved
- 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
Loading