Ejecutar servidores dedicados para juegos en Kubernetes Engine

Empaquetar aplicaciones de servidor como imágenes de contenedor está ganando terreno rápidamente en el panorama tecnológico. Muchas empresas de juegos también están interesadas en utilizar contenedores para mejorar la utilización de VM. También aprovechan el paradigma de tiempo de ejecución aislado que ofrecen los contenedores. A pesar de este gran interés, muchas empresas de juegos no saben por dónde empezar. Recomendamos utilizar el marco de trabajo de organización de contenedores Kubernetes para implementar flotas a escala de producción de servidores de juegos dedicados.

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

La estructura del juego en línea que se presenta en este instructivo es intencionalmente simple para 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 popular servidor de juegos dedicado (DGS) de código abierto en Linux con 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 de solo lectura separado y activarlos en el contenedor en tiempo de ejecución.
  • Establecer y configurar los procesos básicos del programador con las API de Kubernetes y Google Cloud Platform, de modo que los nodos aumenten o disminuyan para satisfacer la demanda.

Costos

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

Puedes usar la calculadora de precios para realizar 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. Selecciona o crea un proyecto de GCP.

    Ir a la página Administrar recursos

  2. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

  3. Habilita las Compute Engine API necesarias.

    Habilita las API

  4. Realiza la instalación y la inicialización del 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.

    Este instructivo no ejecuta comandos de Docker como usuario raíz, por lo que asegúrate de seguir también las instrucciones posteriores a la instalación para administrar Docker como un usuario sin raíz.
  8. (Opcional) Si deseas probar una conexión al servidor de juegos al final del instructivo, instala el cliente de juego OpenArena. Ejecutar el cliente de juego requiere un entorno de computadora de escritorio. Este instructivo incluye instrucciones para realizar pruebas con Linux o macOS.

Arquitectura

solución de descripción general del juego

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

Restricciones de diseño en el instructivo

Para ofrecer un ejemplo que sea lo suficientemente informativo y simple de entender, este instructivo supone las siguientes restricciones de juego:

  • Este es un juego 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 de DGS ejecuta 1 partida.
  • Todos los procesos de DGS generan aproximadamente la misma carga.
  • Las partidas tienen una duración máxima de tiempo.
  • El tiempo de inicio de DGS es insignificante, y no es necesaria una preparación previa del proceso del servidor de juegos dedicado.
  • Cuando se reduce la escala después de un pico, las partidas no finalizan prematuramente en un intento de ahorrar costos. La prioridad es evitar el impacto en la experiencia del jugador.
  • Si un proceso DGS encuentra 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 DGS carga recursos estáticos desde el disco, pero no requiere acceso de escritura a ellos.

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

Preparar tu 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 tu zona predeterminada de Compute Engine con tu zona elegida para [ZONE]:

    gcloud config set compute/zone [ZONE]

Crear contenedores para el servidor de juego elegido

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 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 incluidos en el objeto binario del servidor son los necesarios para que el servidor ejecute la simulación.
  • La imagen de contenedor del servidor de juegos 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 separado.

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 consume menos espacio de disco.

Crear 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. Desde 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 .

Generar 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 de DGS. Esta arquitectura ahorra dinero y elimina la necesidad de distribuir recursos a todas las instancias de VM.

  1. Crea una instancia pequeña de VM 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 elimine cuando se quite la máquina virtual. La funcionalidad persistentVolume de Kubernetes funciona en GKE con discos persistentes. Según Compute Engine, estos discos persistentes deben consistir 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 de openarena-asset-builder y formatea el disco.

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

      sudo lsblk

      El resultado debe mostrar el disco de 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, la secuencia de comandos siguiente activa el disco de recursos en este directorio antes de 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 del dispositivo que verificaste anteriormente.

    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 de tu juego, 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 parecerse a una secuencia de comandos simple que ejecuta comandos de gcloud o a un complemento específico de GCP para el sistema de compilación que elegiste. También se recomienda que crees varias copias del disco persistente y tengas instancias de VM conectadas a estas copias de manera equilibrada para una lograr una capacidad de procesamiento adicional y administrar el riesgo de falla.

Configurar un clúster de Kubernetes

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

Crear un clúster de Kubernetes en Kubernetes Engine

Este instructivo 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 juego 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 tu red de game:

    gcloud container clusters create openarena-cluster \
        --network game --num-nodes 3 --machine-type n1-highcpu-4 \
        --addons KubernetesDashboard
  4. Una vez iniciado el clúster, configura tu shell local con las credenciales de autenticación de Kubernetes adecuadas para controlar tu 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. Hay un límite en el número de nodos que pueden estar en un grupo de clústeres Kubernetes (aunque el proyecto Kubernetes planea aumentar esto 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 de DGS. En cambio, un clúster de 1,000 nodos de máquinas n1-highcpu-32 permite hasta 32,000 pods.

  • El nivel de detalle de tu instancia de VM. La forma más sencilla de agregar o quitar recursos del clúster es en incrementos de una única 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 más pequeñas que 32 CPU virtuales a la vez.

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

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

Como resultado, muchos desarrolladores de juegos implementan un proceso de administración de escalamiento personalizado que tiene conocimientos de 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 Kubernetes necesario y registra automáticamente el nodo con la instancia principal en el inicio.

Subir la imagen de contenedor a GCP

Google ofrece almacenamiento privado de imagen de Docker en Container Registry

  1. Selecciona la región gcr.io más cercana a tu 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 un entorno variable junto con tu 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. Sube la imagen de contenedor al repositorio de imágenes:

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

Una vez 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 de la imagen de contenedor final, ya que deberás colocarla en el archivo de especificaciones del pod más adelante.

Configurar el disco de recursos en Kubernetes

El DGS típico no necesita acceso de escritura a los recursos del juego, por lo que puedes hacer que cada pod de DGS active el mismo disco persistente que contiene recursos de solo lectura. Esto se logra con 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 vinculará 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 que permitirá a los pods activar el disco de recursos:

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

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

    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

Configurar 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 de DGS son insignificantes, en este instructivo las instancias de 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 de DGS de OpenArena. Cuando se completa la partida, el contenedor sale de manera satisfactoria. 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 el instructivo no bifurca ni 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, este instructivo 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.

Administrar el proceso del servidor del juego dedicado

En los servidores de juegos para producción comercial, todas las funcionalidades adicionales que no sean DGS que hacen que un DGS se ejecute correctamente en un contenedor deben integrarse directamente en los objetos binarios de DGS siempre que sea posible.

Como una buena práctica, 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 DGS desde los extremos de Kubernetes apropiados en lugar de consultar directamente al servidor. Puedes encontrar más información acerca de cómo acceder directamente a la API de Kubernetes en la documentación de Kubernetes.

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

En producción, los pods de DGS deben iniciarse directamente por su creador de partidas con la API de Kubernetes. En este instructivo se incluye un archivo YAML legible para el usuario que describe el recurso del pod de DGS en el repositorio del instructivo en openarena/k8s/openarena-pod.yaml. Cuando creas configuraciones para pods de servidores de juegos dedicados, presta mucha atención a las propiedades del volumen para asegurarte de que el disco de recursos se pueda activar en solo lectura en varios pods.

Configurar el administrador de escalamiento

El administrador de escalamiento es un proceso simple que escala la cantidad de máquinas virtuales utilizadas como nodos de GKE, según la carga de DGS actual. El escalamiento se realiza con un conjunto de secuencias de comandos que se ejecutan permanentemente, que inspeccionan la cantidad total de pods de DGS que se ejecutan y solicitan, y que 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 procedimiento siguiente.

  1. Si es necesario, coloca el valor GCR_REGION de gcr.io y tu 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 de 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 tabla siguiente:

    Variable del 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. Si deseas obtener el valor para [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 Kubernetes:

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

Cómo se escalan los nodos

Con el 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 de DGS

Los puntos de adhesión comunes para el escalamiento de DGS incluyen lo siguiente:

  • Las métricas de uso de memoria y CPU estándar a menudo no capturan información suficiente para controlar el escalamiento de instancia del servidor del juego.
  • Mantener un búfer de nodos poco utilizados disponibles es crítico, porque la programación de un contenedor de 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 pods de nodos que se están quitando. Cerrar un nodo con incluso una partida en ejecución suele ser inaceptable.

Aunque las secuencias de comandos proporcionadas por este instructivo son básicas, su diseño simple facilita la adición de lógica adicional. Los DGS típicos tienen características de rendimiento bien entendidas y, al convertirlas en métricas, puedes determinar cuándo agregar o quitar instancias de VM. Las métricas de escalamiento común son el número 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, este instructivo establece las propiedades de pod de limits y requests en el archivo YAML del pod (openarena/k8s/openarena-pod.yaml) con el fin de reservar aproximadamente 1 CPU virtual por cada DGS, que es suficiente para OpenArena.

Debido a que el clúster se creó con la familia de instancias n1-highcpu, que tiene una proporción fija de 600 MB de memoria a 1 CPU virtual, debería haber suficiente memoria si se programa 1 pod de DGS por CPU virtual. De este modo, puedes escalar según 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, y esto te permite agregar más nodos si el valor cae por debajo de un umbral. Este instructivo agrega nodos si más del 70% de las CPU virtuales están asignadas a pods actualmente.

En el backend de un juego en línea de producción, se recomienda que crees un perfil preciso del uso de la red, la memoria y la CPU de 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 situaciones de DGS diferentes con perfiles de uso distintos, como tipos de juego, mapas específicos o cantidad de ranuras disponibles para jugadores. Tales consideraciones quedan fuera del alcance de este instructivo.

Disminución del escalamiento

La disminución del escalamiento, al contrario que el escalamiento vertical, es un proceso de varios pasos y una de las razones principales para ejecutar un administrador de escalamiento de DGS personalizado con conocimiento de Kubernetes. En este instructivo, scaling-manger.sh controla automáticamente los siguientes pasos:

  1. Selección de un nodo apropiado para su eliminación. Debido a que un programador de Kubernetes totalmente personalizado y con conocimiento del juego está fuera del alcance de este instructivo, los nodos se seleccionan en el orden que muestra la API.

  2. Marcación del nodo seleccionado como no disponible en Kubernetes. Esto evita que se inicien pods adicionales en el nodo.

  3. Eliminación del nodo seleccionado del grupo de instancias administrado con el comando abandon-instance. Esto evita que el grupo de instancias administrado intente volver a crear la instancia.

Por separado, la secuencia de comandos node-stopper.sh supervisa los nodos no programados y abandonados por la ausencia de pods de DGS. Luego de que todas las partidas en un nodo hayan finalizado y salgan los pods, la secuencia de comandos cierra la instancia de VM.

Escalamiento del número de pods de DGS

En los backend de juegos de producción típicos, el creador de partidas controla cuándo se agregan nuevas instancias de DGS. Debido a que los pods de 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 el número de pods de DGS. Si no hay suficientes solicitudes de jugadores que ingresen al sistema del creador de partidas para generar nuevas partidas, los pods de DGS se quitan lentamente del clúster de Kubernetes a medida que finalizan las partidas.

Probar la configuración

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

Solicitar una instancia de DGS nueva

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

  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 describe anteriormente 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

    El resultado debe ser similar a esto:

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

Conectarse a 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}

Probar 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 de DGS. Por lo tanto, probar el administrador de escalamiento requiere 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 DGS del instructivo lo usa de forma predeterminada. Para probar, ejecuta la siguiente secuencia de comandos, que agrega pods DGS a intervalos regulares 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 a intervalos regulares.

Limpiar

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, haz lo siguiente:

  1. En la GCP Console, dirígete a la página Proyectos.

    Ir a la página Proyectos

  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, luego, haz clic en Cerrar para borrar el proyecto.

Borra el clúster de GKE

Si no deseas borrar todo el proyecto, ejecuta el comando a continuación para eliminar 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 GCP Console, ve a la página Discos de Compute Engine.

    Ir a la página 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.

Pasos siguientes

En este instructivo se esboza una arquitectura esencial para ejecutar servidores de juegos dedicados en contenedores y ajustar la escala automáticamente de un clúster de Kubernetes basado en la carga del juego. Puedes agregar muchas funciones, 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 para formar grupos; enviar, aceptar o rechazar invitaciones a grupos; y enviar grupos de jugadores juntos en instancias de servidores de juegos dedicadas.

Otra función común es un programador Kubernetes personalizado capaz de elegir nodos para sus pods de DGS de una manera más inteligente y centrada en el juego. Para la mayoría de los juegos, un programador personalizado que agrupa los pods es lo que más se busca. Esto facilita la priorización del orden en el que se deben quitar los nodos cuando se reduce el escalamiento luego de un pico.

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

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...