Ejecuta servidores dedicados para videojuegos en GKE

Empaquetar aplicaciones de servidor como imágenes de contenedor está ganando terreno con rapidez en la escena tecnológica. Muchas empresas de videojuegos también están interesadas en usar contenedores para mejorar el uso de las VM. Además, aprovechan el paradigma de tiempo de ejecución aislado que ofrecen los contenedores. A pesar de este gran interés, muchas empresas de videojuegos no saben por dónde empezar. Recomendamos usar el framework de organización de contenedores Kubernetes a fin de implementar flotas a escala de producción de servidores dedicados para videojuegos.

En este instructivo, se describe una arquitectura extensible a fin de ejecutar servidores dedicados para videojuegos multijugador en tiempo real y basados en sesiones con Google Kubernetes Engine. Un proceso de administrador de escalamiento inicia y detiene de forma automática las instancias de máquina virtual, según sea necesario. La configuración de las máquinas como nodos de Kubernetes se gestiona de forma automática mediante grupos de instancias administrados.

La estructura del videojuego en línea que se presenta en este instructivo es simple con la intención de que sea fácil de entender y de implementar. Las partes en que una mayor complejidad podría resultar útil se señalan cuando corresponde.

Objetivos

  • Crear una imagen de contenedor de OpenArena, un servidor dedicado para videojuegos (DGS), popular y de código abierto, en Linux mediante Docker. Esta imagen de contenedor agrega solo los objetos binarios y las bibliotecas necesarias a una imagen base de Linux
  • Almacenar los recursos en un volumen de disco persistente independiente de solo lectura y activarlos en el contenedor durante el tiempo de ejecución
  • Establece y configura procesos básicos del programador mediante las API de Kubernetes y Google Cloud para crear o apagar nodos a fin de satisfacer la demanda.

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

Puedes usar la calculadora de precios para generar una estimación de costos según el uso previsto.

Antes de comenzar

Este instructivo está diseñado para ejecutarse desde un entorno Linux o macOS.

  1. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir a la página del selector de proyectos

  2. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  3. Habilita la API Compute Engine.

    Habilita la API

  4. Instala e inicializa el SDK de Cloud.

    Nota: No puedes usar Cloud Shell para este instructivo. Debes instalar el SDK de Cloud.

  5. Instala kubectl, la interfaz de línea de comandos para Kubernetes:
    gcloud components install kubectl
  6. Clona el repositorio del instructivo de GitHub:
    git clone https://github.com/GoogleCloudPlatform/gke-dedicated-game-server.git
    
  7. Instala Docker

    En este instructivo, no se ejecutan comandos de Docker como usuario raíz, por lo tanto, asegúrate de seguir las instrucciones posteriores a la instalación para administrar Docker como un usuario no raíz.
  8. Si deseas probar una conexión al servidor de videojuegos al final del instructivo, instala el cliente de juego OpenArena (opcional). Ejecutar el cliente de juego requiere un entorno de computadora de escritorio. En este instructivo, se incluyen instrucciones para realizar pruebas mediante Linux o macOS.

Arquitectura

solución de descripción general del juego

En la página Descripción general de la infraestructura de videojuegos en Cloud, se analizan los componentes de alto nivel comunes a muchas arquitecturas de videojuegos en línea. En este instructivo, implementarás un servicio de frontend del clúster de DGS perteneciente a Kubernetes y un servicio de backend de administrador del escalamiento. Una infraestructura de videojuegos de producción completa también incluiría muchos otros servicios de frontend y backend que no se tratan en este instructivo.

Restricciones de diseño para este instructivo

Para ofrecer un ejemplo que sea lo suficientemente informativo y simple de entender, en este instructivo, se dan por sentadas las siguientes restricciones de videojuegos:

  • Este es un videojuego en tiempo real basado en partidas con un DGS autorizado que simula el estado del juego.
  • El DGS se comunica con el cliente a través de UDP.
  • Cada proceso del DGS ejecuta 1 partida.
  • Todos los procesos del DGS generan aproximadamente la misma carga.
  • Las partidas tienen una duración máxima de tiempo.
  • El tiempo de inicio del DGS es insignificante, y no es necesaria una preparación previa del proceso del servidor dedicado para videojuegos.
  • Cuando se reduce el escalamiento después de un pico, las partidas no finalizan antes de tiempo en un intento de ahorrar costos. La prioridad es evitar el impacto en la experiencia del jugador.
  • Si un proceso del DGS experimenta un error y no puede continuar, se pierde el estado de la partida y se espera que el jugador use el cliente de juego para unirse a otra partida.
  • El proceso del DGS carga los recursos estáticos del disco y no requiere acceso de escritura a los recursos.

Todas estas restricciones tienen precedentes dentro de la industria de los videojuegos y representan un caso práctico en el mundo real.

Prepara el entorno de trabajo de GCP

Con el fin de facilitar la ejecución de los comandos de gcloud, puedes configurar propiedades a fin de no tener que proporcionar opciones para estas propiedades con cada comando.

  1. Establece tu proyecto predeterminado con tu ID del proyecto para [PROJECT_ID]:

    gcloud config set project [PROJECT_ID]
  2. Configura la zona predeterminada de Compute Engine mediante la zona elegida para [ZONE]:

    gcloud config set compute/zone [ZONE]

Crea contenedores en el servidor dedicado para juegos

En este instructivo, usarás OpenArena, que se describe como “un FPS de combate producido por la comunidad y basado en la tecnología idTech3 de GPL”. Aunque la tecnología de este juego tiene más de quince años, sigue siendo un buen ejemplo de un patrón de DGS común:

  • Un objeto binario de servidor se compila desde la misma base de código que el cliente de juego.
  • Los únicos recursos de datos que se incluyen en el objeto binario de servidor son los necesarios para que el servidor ejecute la simulación.
  • La imagen de contenedor del servidor de videojuegos agrega solo los objetos binarios y las bibliotecas a la imagen de contenedor del SO base que se requieren para ejecutar el proceso del servidor.
  • Los recursos se activan desde un volumen independiente.

Esta arquitectura presenta muchos beneficios: acelera la distribución de imágenes, reduce la carga de actualización porque solo se reemplazan los objetos binarios, y ocupa menos espacio en el disco.

Crea la imagen de contenedor

Un Dockerfile describe la imagen que se desea compilar. El Dockerfile para este instructivo se proporciona en el repositorio en openarena/Dockerfile. En el directorio openarena/, ejecuta el comando de compilación de Docker para generar la imagen de contenedor y etiquétalo como versión 0.8.8 del servidor OpenArena:

docker build -t openarena:0.8.8 .

Genera un disco de recursos

En la mayoría de los juegos, los objetos binarios son órdenes de magnitud más pequeñas que los recursos. Debido a esto, tiene sentido crear una imagen de contenedor que contenga solo objetos binarios. Los recursos se pueden colocar en un disco persistente y se pueden adjuntar a varias instancias de VM que ejecutan el contenedor del DGS. Esta arquitectura ahorra dinero y elimina la necesidad de distribuir recursos a todas las instancias de VM.

  1. Crea una instancia de VM pequeña de Compute Engine con gcloud:

    gcloud compute instances create openarena-asset-builder \
        --machine-type f1-micro --image-family debian-9 \
        --image-project debian-cloud
  2. Crea un disco persistente:

    gcloud compute disks create openarena-assets --size=50GB \
        --type=pd-ssd --description="OpenArena data disk. \
        Mount read-only at /usr/share/games/openarena/baseoa/"

    El disco persistente debe estar separado del disco de arranque, y debes configurarlo para que no se borre cuando se quite la máquina virtual. La funcionalidad persistentVolume de Kubernetes funciona mejor en GKE con discos persistentes. Según Compute Engine, estos discos persistentes consisten en un solo sistema de archivos ext4 sin una tabla de partición.

  3. Adjunta el disco persistente openarena-assets a la instancia de VM openarena-asset-builder:

    gcloud compute instances attach-disk openarena-asset-builder \
        --disk openarena-assets
  4. Formatea el disco nuevo.

    1. Accede a la instancia de VM openarena-asset-builder y formatea el disco.

      gcloud compute ssh openarena-asset-builder
    2. Debido a que el comando mkfs.ext4 en el siguiente paso es destructivo, asegúrate de confirmar el ID de dispositivo para el disco openarena-assets. Si sigues este instructivo desde el principio y usas un proyecto nuevo, el ID es /dev/sdb. Verifica esto mediante el comando lsblk para ver los discos conectados y sus particiones:

      sudo lsblk

      En el resultado, se muestra el disco del SO de 10 GB sda con 1 partición sda1 y el disco openarena-assets de 50 GB sin partición como dispositivo sdb:

      NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
      sda 8:0 0 10G 0 disk
      └─sda1 8:1 0 10G 0 part /
      sdb 8:16 0 50G 0 disk
    3. Formatea el disco openarena-assets:

      sudo mkfs.ext4 -m 0 -F -E \
          lazy_itable_init=0,lazy_journal_init=0,discard /dev/[DEVICE_ID]
  5. Instala OpenArena en la instancia de VM openarena-asset-builder y copia los archivos de recursos comprimidos en el disco persistente openarena-assets.

    Para este juego, los recursos son archivos .pk3 ubicados en el directorio /usr/share/games/openarena/baseoa/. Para ahorrar algo de trabajo, con la siguiente secuencia de comandos, se activa el disco de recursos en este directorio antes de realizar la instalación, por lo que todos los archivos .pk3 se colocan en el disco mediante el proceso de instalación. Asegúrate de usar el ID de dispositivo que verificaste con anterioridad.

    sudo mkdir -p /usr/share/games/openarena/baseoa/
    
    sudo mount -o discard,defaults /dev/[DEVICE_ID] \
        /usr/share/games/openarena/baseoa/
    
    sudo apt-get update && sudo apt-get -y install openarena-server
  6. Sal de la instancia y, luego, bórrala:

    exit
    gcloud compute instances delete openarena-asset-builder

    El disco está listo para usarse como un volumen persistente en Kubernetes.

Cuando implementas discos persistentes como parte de la canalización del desarrollo del videojuego, configura el sistema de compilación para crear el disco persistente con todos los archivos de recursos en una estructura de directorio adecuada. Esto puede tener el formato de una secuencia de comandos que ejecuta comandos de gcloud, o un complemento específico de GCP para el sistema de compilación que elegiste. También recomendamos que crees varias copias del disco persistente y tengas instancias de VM conectadas a estas copias de manera equilibrada para lograr una capacidad de procesamiento adicional y administrar el riesgo de falla.

Configura un clúster de Kubernetes

Kubernetes es un proyecto comunitario de código abierto y, como tal, se puede configurar para que se ejecute en la mayoría de los entornos, incluido el local.

Crea un clúster de Kubernetes en Kubernetes Engine

En este instructivo, se usa un clúster de Kubernetes Engine estándar equipado con el tipo de máquina n1-highcpu, que se ajusta al perfil de uso de OpenArena.

  1. Crea una red de VPC para el videojuego llamada game:

    gcloud compute networks create game
  2. Crea una regla de firewall para OpenArena:

    gcloud compute firewall-rules create openarena-dgs --network game \
        --allow udp:27961-28061
  3. Usa gcloud para crear un clúster de 3 nodos con 4 núcleos de CPU virtuales en cada uno, que use la red de game:

    gcloud container clusters create openarena-cluster \
        --network game --num-nodes 3 --machine-type n1-highcpu-4 \
        --addons KubernetesDashboard
  4. Después de iniciar el clúster, configura tu shell local con las credenciales de autenticación de Kubernetes adecuadas para controlar el clúster nuevo:

    gcloud container clusters get-credentials openarena-cluster

En un clúster de producción, la cantidad de CPU virtuales que ejecutarás en cada máquina depende en gran medida de dos factores:

  • La mayor cantidad de pods de DGS simultáneos que piensas ejecutar Existe un límite para la cantidad de nodos que puede haber en un grupo de clústeres de Kubernetes (aunque en el proyecto de Kubernetes se planea aumentarlo en versiones futuras). Por ejemplo, si ejecutas 1 DGS por CPU virtual, un clúster de 1,000 nodos de máquinas n1-highcpu-2 proporciona capacidad para solo 2,000 pods del DGS. Por el contrario, un clúster de 1,000 nodos de máquinas n1-highcpu-32 proporciona capacidad para hasta 32,000 pods.

  • El nivel de detalle de tu instancia de VM. La forma más simple de agregar o quitar los recursos del clúster es en incrementos de una sola instancia de VM del tipo elegido durante la creación del clúster Por lo tanto, no elijas una máquina de 32 CPU virtuales si deseas poder agregar o quitar capacidad en cantidades menores a 32 CPU virtuales a la vez.

La característica de los grupos de instancias administrados que GKE usa de forma predeterminada incluye el ajuste de escala automático de instancia de VM y el balanceo de cargas de HTTP. Sin embargo, el comando que usaste para crear el clúster de Kubernetes inhabilitó estas características mediante la marca --disable-addons HttpLoadBalancing,HorizontalPodAutoscaling.

El balanceo de cargas de HTTP no es necesario porque el DGS se comunica con los clientes mediante UDP, y no mediante TCP. Por el momento, el escalador automático solo puede escalar el grupo de instancias según el uso de CPU, lo que puede ser un indicador engañoso de la carga del DGS. Muchos DGS están diseñados para consumir ciclos de inactividad a fin de optimizar la simulación del videojuego.

Como resultado, muchos desarrolladores de videojuegos implementan un proceso de administración de escalamiento personalizado adaptado al DGS para tratar los requisitos específicos de este tipo de carga de trabajo. Sin embargo, el grupo de instancias administrado aún cumple una función importante: su plantilla de imagen de GKE predeterminada incluye todo el software de Kubernetes necesario y registra de forma automática el nodo con el plano de control en el inicio.

Sube la imagen de contenedor a Google Cloud

Google ofrece almacenamiento privado de imagen de Docker en Container Registry (gcr.io).

  1. Selecciona la región gcr.io más cercana al clúster de GKE (por ejemplo: us si es Estados Unidos, eu si es Europa o asia si es Asia, como se indica en la documentación) y coloca la información de la región en una variable de entorno junto con el ID del proyecto.

    export GCR_REGION=[GCR_REGION] PROJECT_ID=[PROJECT_ID]
  2. Etiqueta tu imagen de contenedor con el nombre de registro gcr.io:

    docker tag openarena:0.8.8 \
        ${GCR_REGION}.gcr.io/${PROJECT_ID}/openarena:0.8.8
  3. Configura la autenticación de Docker para Container Registry:

    gcloud auth configure-docker
  4. Sube la imagen de contenedor al repositorio de imágenes:

    docker push ${GCR_REGION}.gcr.io/${PROJECT_ID}/openarena:0.8.8

Después de que se completa el envío, la imagen de contenedor estará disponible para ejecutarse en tu clúster de GKE. Toma nota de la etiqueta final de la imagen de contenedor, ya que la ubicarás en el archivo de especificaciones del pod más adelante.

Configura el disco de recursos en Kubernetes

El DGS típico no necesita acceso de escritura a los recursos del videojuego, por lo que puedes hacer que cada pod de DGS active el mismo disco persistente que contiene recursos de solo lectura. Esto se logra mediante los recursos persistentVolume y persistentVolumeClaim en Kubernetes.

  1. Aplica asset-volume.yaml, que contiene la definición de un recurso persistentVolume de Kubernetes que se vincula al disco de recursos que creaste antes:

    kubectl apply -f openarena/k8s/asset-volume.yaml
  2. Aplica asset-volumeclaim.yaml. Contiene la definición de un recurso persistentVolumeClaim de Kubernetes, lo que permite que los pods activen el disco de recursos:

    kubectl apply -f openarena/k8s/asset-volumeclaim.yaml

    Para confirmar que el volumen esté en estado Bound, ejecuta el siguiente comando:

    kubectl get persistentVolume

    Resultado esperado:

    NAME           CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM                      STORAGECLASS   REASON    AGE
    asset.volume   50Gi       ROX           Retain          Bound     default/asset.disk.claim   assets                   3m

    Del mismo modo, confirma que la reclamación esté en estado de vínculo:

    kubectl get persistentVolumeClaim

    Resultado esperado:

    NAME               STATUS    VOLUME         CAPACITY   ACCESSMODES   STORAGECLASS   AGE
    asset.disk.claim   Bound     asset.volume   50Gi       ROX           assets         25s

Configura el pod de DGS

Debido a que las tareas de programación y de red son controladas por Kubernetes, y los tiempos de inicio y apagado de los contenedores del DGS son insignificantes, en este instructivo, las instancias del DGS se inician a pedido.

Cada instancia de DGS solo tiene la duración de una única partida de juego, y una partida de juego tiene un límite de tiempo definido especificado en el archivo de configuración del servidor del DGS de OpenArena. Cuando se completa la partida, el contenedor sale con éxito. Si los jugadores desean volver a jugar, solicitan otro juego. Este diseño simplifica algunos aspectos del ciclo de vida del pod y constituye la base de la política de ajuste de escala automático que se analiza más adelante en la sección del administrador de escalamiento.

Aunque este flujo no es óptimo con OpenArena, esto solo se debe a que en el instructivo no se bifurca ni se cambia el código del cliente de juego. En un juego comercial, la solicitud de otra partida se haría invisible para el usuario detrás de las pantallas de resultados de la partida anterior y los tiempos de carga. El código que requiere que el cliente se conecte a una instancia de servidor nueva entre las partidas no representa un tiempo de desarrollo adicional, ya que ese código, de todos modos, es obligatorio para controlar las reconexiones del cliente ante circunstancias imprevistas, como problemas de red o servidores fallidos.

Para hacerlo más simple, en este instructivo, se supone que los nodos de GKE tienen la configuración de red predeterminada, que asigna una dirección IP pública a cada nodo y permite las conexiones de clientes.

Administra el proceso del servidor dedicado para juegos

En los servidores de videojuegos producidos de forma comercial, todas las funcionalidades adicionales que no sean del DGS que hacen que un DGS se ejecute con éxito en un contenedor, se integran directamente en los objetos binarios del DGS siempre que sea posible.

Como práctica recomendada, el DGS debe evitar comunicarse directamente con el creador de partidas o el administrador de escalamiento y, en su lugar, debe exponer su estado a la API de Kubernetes. Los procesos externos deben leer el estado del DGS desde los extremos adecuados de Kubernetes en lugar de consultar directamente al servidor. Puedes obtener más información sobre cómo acceder directamente a la API de Kubernetes, consulta la documentación de Kubernetes.

A simple vista, un solo proceso que se ejecuta en un contenedor con un ciclo de vida limitado y criterios de éxito definidos parece ser un caso de uso para los trabajos de Kubernetes, pero en la práctica no es necesario usar los trabajos. Los procesos del DGS no requieren la funcionalidad de ejecución paralela de los trabajos. Tampoco requieren la capacidad de garantizar funcionamientos correctos cuando se reinician de forma automática (por regla general, cuando un DGS basado en una sesión muere por algún motivo, el estado se pierde y los jugadores solo se unen a otro DGS). Debido a estos factores, es preferible programar pods de Kubernetes individuales para este caso de uso.

En producción, el creador de partidas inicia directamente los pods de DGS con la API de Kubernetes. Para los propósitos de este instructivo, se incluye un archivo YAML legible que describe el recurso de pod del DGS en el repositorio de instructivos en openarena/k8s/openarena-pod.yaml. Cuando creas una configuración relacionada con pods de servidores de videojuegos, presta mucha atención a las propiedades del volumen a fin de asegurarte de que el disco de recursos se pueda activar como solo lectura en varios pods.

Configura el administrador de escalamiento

El administrador de escalamiento es un proceso que escala la cantidad de máquinas virtuales utilizadas como nodos de GKE en función de la carga del DGS actual. El escalamiento se realiza mediante un conjunto de secuencias de comandos que se ejecutan de forma permanente, inspeccionan la cantidad total de pods del DGS que se ejecutan y solicitan, y cambian el tamaño del grupo de nodos según sea necesario. Las secuencias de comandos están empaquetadas en imágenes de contenedor de Docker que incluyen las bibliotecas adecuadas y el SDK de Cloud. Las imágenes de Docker se pueden crear y enviar a gcr.io mediante el siguiente procedimiento.

  1. Si es necesario, coloca el valor GCR_REGION de gcr.io y el PROJECT_ID en las variables de entorno para la secuencia de comandos de compilación y envío. Puedes omitir este paso si ya lo hiciste antes cuando subiste la imagen del contenedor.

    export REGION=[GCR_REGION] PROJECT_ID=[PROJECT_ID]
  2. Cambia al directorio de la secuencia de comandos:

    cd scaling-manager
  3. Ejecuta la secuencia de comandos de compilación para compilar todas las imágenes de contenedor y envíalas a gcr.io:

    ./build-and-push.sh
  4. Con un editor de texto, abre el archivo de implementación de Kubernetes en scaling-manager/k8s/openarena-scaling-manager-deployment.yaml.

    Las secuencias de comandos del administrador de escalamiento están diseñadas para ejecutarse dentro de una implementación de Kubernetes, lo que garantiza que estos procesos se reinicien en caso de una falla.

  5. Cambia las variables de entorno a valores para tu implementación, como se muestra en la siguiente tabla:

    Variable de entorno Valor predeterminado Notas
    REGION [GCR_REGION] Requiere reemplazo. La región de tu repositorio gcr.io.
    PROJECT_ID [PROJECT_ID] Requiere reemplazo. El nombre de tu proyecto.
    GKE_BASE_INSTANCE_NAME gke-openarena-cluster-default-pool-[REPLACE_ME] Requiere reemplazo. Diferente para cada clúster de GKE. Para obtener el valor de [REPLACE_ME], ejecuta el comando gcloud compute instance-groups managed list.
    GCP_ZONE [ZONE] Requiere reemplazo. El nombre de la zona GCP que especificaste al comienzo de este instructivo.
    K8S_CLUSTER openarena-cluster El nombre del clúster de Kubernetes.
  6. Regresa al directorio superior:

    cd ..
  7. Agrega la implementación a tu clúster de Kubernetes:

    kubectl apply \
        -f scaling-manager/k8s/openarena-scaling-manager-deployment.yaml

Cómo se escalan los nodos

A fin de escalar los nodos, el administrador de escalamiento usa la API de Kubernetes para observar el uso actual del nodo. Según sea necesario, el administrador cambia el tamaño del grupo de instancias administrado del clúster de Kubernetes Engine que ejecuta las máquinas virtuales subyacentes.

Problemas de escalamiento de los pods del DGS

A continuación, se indican los puntos de conflicto comunes para el escalamiento del DGS:

  • Las métricas de uso de memoria y CPU estándar a veces no logran capturar suficiente información para impulsar el escalamiento de la instancia del servidor de videojuegos.
  • Mantener disponible un búfer de nodos con poco uso es fundamental, porque la programación de un contenedor del DGS optimizado en un nodo existente toma solo unos segundos. Sin embargo, agregar un nodo puede tardar minutos, que es una latencia inaceptable para un jugador en espera.
  • Muchos escaladores automáticos no pueden controlar los cierres de pod con facilidad. Es importante desviar los pods de nodos que se están quitando. Cerrar un nodo, incluso con una partida en ejecución, suele ser inaceptable.

Si bien las secuencias de comandos que se proporcionan en este instructivo son básicas, su diseño simple facilita agregar una lógica adicional. Los DGS típicos presentan características de rendimiento muy comprensibles, y cuando se convierten en métricas, puedes determinar cuándo agregar o quitar instancias de VM. Las métricas de escalamiento común son la cantidad de instancias de DGS por CPU, como se usa en este instructivo, o la cantidad de ranuras de jugador disponibles.

Escalamiento vertical

El escalamiento vertical no requiere un tratamiento especial en este instructivo. Para que resulte más simple, en este instructivo, se configuran las propiedades del pod limits y requests en el archivo YAML del pod (openarena/k8s/openarena-pod.yaml) a fin de reservar alrededor de 1 CPU virtual por cada DGS, que es suficiente para OpenArena.

Debido a que el clúster se creó mediante la familia de instancias n1-highcpu, que tiene una proporción fija de 600 MB de memoria por cada CPU virtual, hay suficiente memoria si se programa 1 pod de DGS por cada CPU virtual. Por lo tanto, puedes escalar verticalmente en función de la cantidad de pods en el clúster en comparación con la cantidad de CPU en todos los nodos del clúster. Esta proporción determina los recursos restantes disponibles, lo que te permite agregar más nodos si el valor disminuye por debajo del umbral. En este instructivo, se agregan nodos si más del 70% de las CPU virtuales están asignadas a pods en el momento.

En el backend de un videojuego de producción en línea, se recomienda que crees un perfil preciso del uso de la red, la memoria y la CPU del DGS y, luego, establezcas las propiedades de pods de limits y requests de forma adecuada. En muchos juegos, tiene sentido crear varios tipos de pod para diferentes situaciones del DGS con perfiles de uso distintos, como tipos de juego, mapas específicos o cantidad de ranuras para jugadores. Tales consideraciones no se tratan en este instructivo.

Disminución del escalamiento

A diferencia del escalamiento vertical, la disminución del escalamiento es un proceso de varios pasos y uno de los principales motivos para ejecutar un administrador de escalamiento del DGS personalizado adaptado a Kubernetes. En este instructivo, scaling-manager.sh controla de forma automática las siguientes acciones:

  1. Seleccionar un nodo apropiado para su eliminación. Debido a que en este instructivo no se incluye un programador de Kubernetes personalizado completo adaptado al videojuego, los nodos se seleccionan en el orden en que los muestra la API

  2. Marcar el nodo seleccionado como no disponible en Kubernetes. Esto evita que se inicien pods adicionales en el nodo.

  3. Quitar el nodo seleccionado del grupo de instancias administrado mediante el comando abandon-instance. Esto evita que el grupo de instancias administrado vuelva a crear la instancia

Por su lado, la secuencia de comandos node-stopper.sh supervisa los nodos cancelados y no programados por la ausencia de pods del DGS. Después de que finalicen todas las partidas en un nodo y los pods se cierren, la secuencia de comandos cerrará la instancia de VM.

Escalamiento de la cantidad de pods del DGS

En los backends de videojuegos de producción típicos, el creador de partidas controla cuándo se agregan instancias nuevas del DGS. Debido a que los pods del DGS están configurados para salir cuando las partidas finalizan (consulta las restricciones de diseño anteriores), no se necesita ninguna acción explícita para reducir la cantidad de pods del DGS. Si no hay suficientes solicitudes de jugadores que ingresen al sistema del creador de partidas para generar partidas nuevas, los pods del DGS se quitan con lentitud del clúster de Kubernetes a medida que finalizan las partidas.

Prueba la configuración

Hasta ahora, creaste la imagen de contenedor de OpenArena, la enviaste al Container Registry, y también iniciaste el clúster de Kubernetes del DGS. Además, generaste el disco de recursos del videojuego y lo configuraste para su uso en Kubernetes. Por otro lado, iniciaste la implementación del administrador de escalamiento. En este punto, es hora de comenzar los pods del DGS para realizar pruebas.

Solicita una instancia de DGS nueva

En un sistema de producción típico, cuando el proceso del creador de partidas tiene jugadores apropiados para una partida, solicita directamente una instancia mediante la API de Kubernetes. Para probar la configuración de este instructivo, puedes realizar directamente la solicitud de una instancia.

  1. Abre openarena/k8s/openarena-pod.yaml en un editor de texto y busca la línea que especifica la imagen de contenedor que se ejecutará.

  2. Cambia el valor para que coincida con tu etiqueta de imagen de contenedor openarena mediante la ejecución del comando docker tag como se describió antes en este instructivo.

  3. Ejecuta el comando kubectl apply y especifica el archivo openarena-pod.yaml:

    kubectl apply -f openarena/k8s/openarena-pod.yaml
  4. Espera un momento y, luego, confirma el estado del pod:

    kubectl get pods

    La salida es similar a la siguiente:

    NAME             READY     STATUS    RESTARTS   AGE
    openarena.dgs    1/1       Running   0          25s

Conéctate al DGS

Una vez que el pod haya iniciado, puedes verificar que te puedes conectar al DGS mediante el inicio del cliente OpenArena.

Desde una computadora de escritorio macOS o Linux:

export NODE_NAME=$(kubectl get pod openarena.dgs \
    -o jsonpath="{.spec.nodeName}")
export DGS_IP=$(gcloud compute instances list \
    --filter="name=( ${NODE_NAME} )" \
    --format='table[no-heading](EXTERNAL_IP)')
openarena +connect ${DGS_IP}

Prueba el administrador de escalamiento

El administrador de escalamiento escala la cantidad de instancias de VM en el clúster de Kubernetes según la cantidad de pods del DGS. Por lo tanto, probar el administrador de escalamiento requiere realizar solicitudes para una cantidad de pods durante un período y verificar que la cantidad de nodos se escala de manera adecuada. Para ver cómo se vuelven a reducir los nodos, la duración de la partida en el archivo de configuración del servidor debe tener un límite de tiempo. El archivo de configuración del servidor del instructivo en openarena/single-match.cfg establece un límite de 5 minutos en la partida, y los pods del DGS del instructivo lo usan de forma predeterminada. Para realizar una prueba, ejecuta la siguiente secuencia de comandos, que agrega pods del DGS a intervalos periódicos durante 5 minutos:

./scaling-manager/tests/test-loader.sh

Deberías poder ver la cantidad de nodos que escalan verticalmente y se vuelven a reducir si ejecutas kubectl get nodes en intervalos regulares.

Realiza una limpieza

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en este instructivo:

Borra el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, sigue estos pasos:

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a la página Administrar recursos

  2. En la lista de proyectos, selecciona el proyecto que deseas borrar y haz clic en Borrar .
  3. En el cuadro de diálogo, escribe el ID del proyecto y haz clic en Cerrar para borrar el proyecto.

Borra el clúster de GKE

Si no quieres borrar todo el proyecto, ejecuta el siguiente comando para borrar el clúster de GKE:

gcloud container clusters delete openarena-cluster

Borra tus discos persistentes

Para borrar un disco persistente, realiza los siguientes pasos:

  1. En Cloud Console, ve a la página Discos de Compute Engine.

    Ir a Discos de Compute Engine

  2. Selecciona el disco que deseas borrar.

  3. Haz clic en el botón Borrar en la parte superior de la página.

Próximos pasos

En este instructivo, se esboza la arquitectura básica a fin de ejecutar servidores de videojuegos en contenedores y realizar un ajuste de escala automático de un clúster de Kubernetes basado en la carga del juego. Puedes agregar muchas características, como la transición de jugadores de una sesión a otra sin interrupciones, mediante la programación de asistencia básica del lado del cliente. Para agregar otras funciones, como permitir a los jugadores formar grupos y mover los grupos de un servidor a otro, puedes crear un servicio de plataforma independiente que conviva con el servicio de creación de partidas. A continuación, puedes usar el servicio a fin de formar grupos; enviar, aceptar o rechazar invitaciones a grupos; y enviar grupos de jugadores a instancias de servidores dedicados para videojuegos.

Otra característica común es un programador de Kubernetes personalizado capaz de seleccionar nodos para los pods del DGS de manera más inteligente y centrada en el videojuego. En la mayoría de los videojuegos, lo más conveniente es contar con un programador personalizado que agrupe los pods, lo que te permite priorizar el orden en el que se deben quitar los nodos cuando se reduce el escalamiento después de un pico.

Más guías para ejecutar un DGS en GCP: