itzg / docker-minecraft-server

Docker image that provides a Minecraft Server that will automatically download selected version at startup
https://docker-minecraft-server.readthedocs.io/
Apache License 2.0
9.13k stars 1.51k forks source link

Not setting newly optional MEMORY causes OOM errors with 1GB of container limit #1161

Closed daniellavoie closed 2 years ago

daniellavoie commented 2 years ago

Describe the problem

According to the latest release note, #742 lets java caculcate heap memory limits by itself thanks to latest JVM optimization goodness.

That said, I'm under the impression that this is not a good behaviour since I have the feeling minecraft does non heap stuff which overlaps with the the default memory calculation.

Prior to itzg/minecraft-server:java17, I would set MEMORY to half of my container memory limits so I could leave breathing room for non heap.

My conclusion is that we shouldn't deprecate MEMORY given that default JVM heap sizing doesn't cope well with a standard 1GB container limit.

Container definition

spec:
  containers:
  - env:
    - name: RCON_PASSWORD
      valueFrom:
        secretKeyRef:
          key: rconPassword
          name: test
          optional: false
    - name: SPAWN_NPCS
      value: "true"
    - name: ALLOW_NETHER
      value: "true"
    - name: RCON_ENABLED
      value: "true"
    - name: GENERATE_STRUCTURES
      value: "true"
    - name: EULA
      value: "true"
    - name: MODE
      value: survival
    - name: PVP
      value: "true"
    - name: FORCE_GAMEMODE
      value: "true"
    - name: VIEW_DISTANCE
      value: "10"
    - name: DIFFICULTY
      value: normal
    - name: OPS
    - name: MEMORY
    - name: SPAWN_ANIMALS
      value: "true"
    - name: SERVER_NAME
      value: test
    - name: ICON
    - name: HARDCORE
      value: "false"
    - name: WHITELIST
    - name: OVERRIDE_ICON
      value: "true"
    - name: OVERRIDE_SERVER_PROPERTIES
      value: "true"
    - name: ANNOUNCE_PLAYER_ACHIEVEMENTS
      value: "false"
    - name: MAX_WORLD_SIZE
      value: "29999984"
    - name: ENABLE_JMX
      value: "true"
    - name: JVM_OPTS
      value: -javaagent:/home/minecraft/bin/jmx_prometheus_javaagent-0.16.1.jar=8080:/home/minecraft/config/jmx-exporter-config.yaml
    - name: MAX_BUILD_HEIGHT
      value: "256"
    - name: SPAWN_MONSTERS
      value: "true"
    - name: MAX_PLAYERS
      value: "20"
    - name: VERSION
      value: 1.17.1
    - name: ENABLE_COMMAND_BLOCK
      value: "false"
    image: itzg/minecraft-server:java17
    imagePullPolicy: Always
    name: server
    ports:
    - containerPort: 25565
      name: server
      protocol: TCP
    - containerPort: 7091
      name: jmx
      protocol: TCP
    - containerPort: 8080
      name: prometheus
      protocol: TCP
    - containerPort: 25575
      name: rcon
      protocol: TCP
    resources:
      limits:
        cpu: "1"
        memory: 1G
      requests:
        cpu: "1"
        memory: 1G
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /data
      name: data
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-p2p58
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  hostname: test-0
  nodeName: minikube
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  subdomain: test
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: data-test-0
  - name: kube-api-access-p2p58
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace

Container logs

[init] Running as uid=1000 gid=1000 with /data as 'drwxrwxrwx 4 1000 1000 4096 Dec 5 01:02 /data'
[init] Resolved version given 1.17.1 into 1.17.1
[init] Resolving type given VANILLA
[init] Disabling whitelist
[init] Setting whitelist to 'false' in /data/server.properties
[init] Setting white-list to 'false' in /data/server.properties
[init] Setting server-name to 'test' in /data/server.properties
[init] Setting allow-nether to 'true' in /data/server.properties
[init] Adding announce-player-achievements with 'false' in /data/server.properties
[init] Setting enable-command-block to 'false' in /data/server.properties
[init] Setting spawn-animals to 'true' in /data/server.properties
[init] Setting spawn-monsters to 'true' in /data/server.properties
[init] Setting spawn-npcs to 'true' in /data/server.properties
[init] Setting generate-structures to 'true' in /data/server.properties
[init] Setting view-distance to '10' in /data/server.properties
[init] Setting hardcore to 'false' in /data/server.properties
[init] Setting max-build-height to '256' in /data/server.properties
[init] Setting force-gamemode to 'true' in /data/server.properties
[init] Setting enable-rcon to 'true' in /data/server.properties
[init] Setting rcon.password to 'e9e581f0-8efb-4d63-ab04-a3496fc2c585' in /data/server.properties
[init] Setting rcon.port to '25575' in /data/server.properties
[init] Setting max-players to '20' in /data/server.properties
[init] Setting max-world-size to '29999984' in /data/server.properties
[init] Setting pvp to 'true' in /data/server.properties
[init] Setting enable-jmx-monitoring to 'true' in /data/server.properties
[init] Setting motd to 'A Vanilla Minecraft Server powered by Docker' in /data/server.properties
[init] Setting difficulty to 'normal' in /data/server.properties
[init] Setting mode
[init] Setting gamemode to 'survival' in /data/server.properties
[init] Checking for JSON files.
[init] JMX is enabled. Make sure you have port forwarding for 7091
[init] Starting the Minecraft server...
[01:09:15] [main/INFO]: Environment: authHost='https://authserver.mojang.com', accountsHost='https://api.mojang.com', sessionHost='https://sessionserver.mojang.com', servicesHost='https://api.minecraftservices.com', name='PROD'
[01:09:17] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[01:09:17] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, targets] with inputs: [0.1 -0.5 .9, 0 0 0]
[01:09:17] [main/WARN]: Ambiguity between arguments [teleport, destination] and [teleport, targets] with inputs: [Player, 0123, @e, dd12be42-52a9-4a91-a8a1-11c01849e498]
[01:09:17] [main/WARN]: Ambiguity between arguments [teleport, targets] and [teleport, destination] with inputs: [Player, 0123, dd12be42-52a9-4a91-a8a1-11c01849e498]
[01:09:17] [main/WARN]: Ambiguity between arguments [teleport, targets, location] and [teleport, targets, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[01:09:17] [main/INFO]: Reloading ResourceManager: Default
[01:09:18] [Worker-Main-2/INFO]: Loaded 7 recipes
[01:09:20] [Worker-Main-2/INFO]: Loaded 1137 advancements
[01:09:27] [Server thread/INFO]: Starting minecraft server version 1.17.1
[01:09:27] [Server thread/WARN]: To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar"
[01:09:27] [Server thread/INFO]: Loading properties
[01:09:27] [Server thread/INFO]: Default game type: SURVIVAL
[01:09:27] [Server thread/INFO]: Generating keypair
[01:09:28] [Server thread/INFO]: Starting Minecraft server on *:25565
[01:09:28] [Server thread/INFO]: Using epoll channel type
[01:09:29] [Server thread/INFO]: Preparing level "world"
[01:09:29] [Server thread/INFO]: Preparing start region for dimension minecraft:overworld
Exception in thread "HTTP-Dispatcher"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "HTTP-Dispatcher"
[01:09:54] [Server thread/INFO]: Stopping server
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Server thread"
2021-12-05T01:10:14.491Z INFO mc-server-runner Done
daniellavoie commented 2 years ago

So it seems like it is well known that 1.18 requires more memory out of the box.

The default behaviour for not setting -Xmx through the MEMORY will only assign 25% of the available container memory to the Heap.

[Global flags]size_t MaxHeapSize = 251658240 {product} {ergonomic}
double MaxRAMPercentage = 25.000000 {product} {default}

I would successfully run 1.17 with a 512mb MEMORY value and 1GB of container limit .

With 1.18, 512mb of heap is clearly not enough. 1GB runs fine (but still need ~350mb headroom within the container).

My conclusion is that the MEMORY should still be kept as a mandatory configuration and should not be deprecated in the future. If MEMORY is not specified, 1.18 requires at least 3GB memory when only 25% will be used. This feels like a waste.

itzg commented 2 years ago

I already talk about this behavior in the memory section. What do you recommend to help further?

https://github.com/itzg/docker-minecraft-server#:~:text=To%20let%20the,general%20best%20practice.

daniellavoie commented 2 years ago

You are absolutely right. Didn't see the specific mention about default behaviour being already documented. Good stuff!

The reason I shared my concerns is because I've came across the description of #742 mentioning future deprecation of MEMORY env variable. I just hope it isn't considered in the future.