Como executar servidores dedicados de jogos no Kubernetes Engine

O empacotamento de aplicativos de servidor como imagens de contêiner está rapidamente ganhando força em todo o panorama tecnológico. Muitas empresas de jogos também estão interessadas em usar contêineres para melhorar a utilização de VMs, bem como aproveitar o paradigma do tempo de execução isolado oferecido por contêineres. Porém, mesmo com esse alto interesse, muitas empresas de jogos não sabem por onde começar. Recomendamos usar a biblioteca de orquestração de contêineres Kubernetes para implantar frotas em escala de produção de servidores dedicados de jogos.

Neste tutorial, você verá uma descrição de uma arquitetura expansível para executar servidores dedicados de jogos multijogador baseados em sessão em tempo real no Google Kubernetes Engine. Um processo administrador de dimensionamento inicia e para automaticamente instâncias de máquina virtual conforme necessário. A configuração das máquinas como nodes do Kubernetes é processada automaticamente por grupos de instâncias gerenciados.

A estrutura do jogo on-line apresentada neste tutorial é intencionalmente simples. Dessa maneira, é fácil entendê-la e implementá-la. Quando apropriado, indicaremos os lugares em que pode ser útil ter mais complexidade.

Objetivos

  • Criar uma imagem de contêiner do OpenArena, um conhecido servidor dedicado de jogos (DGS, na sigla em inglês) no Linux usando o Docker. Essa imagem de contêiner adiciona apenas os binários e as bibliotecas necessárias a uma imagem básica do Linux.
  • Armazenar os recursos em um volume de disco permanente separado somente leitura e montá-los no contêiner no prazo de validade.
  • Configurar e definir processos básicos do programador usando as APIs Kubernetes e Google Cloud Platform com o intuito de aumentar e diminuir nós para atender à demanda.

Custos

Neste tutorial, serão utilizados os seguintes componentes faturáveis do Google Cloud Platform:

Use a calculadora de preços para gerar uma estimativa de custo com base no uso projetado.

Antes de começar

Este tutorial precisa ser executado em um ambiente Linux ou macOS.

  1. Selecione ou crie um projeto do Google Cloud Platform.

    Acessar a página Gerenciar recursos

  2. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform.

    Saiba como ativar o faturamento

  3. Ativar Compute Engine API.

    Ativar a API

  4. Instale e inicialize o SDK do Cloud.

    Observação: para este tutorial, não é possível usar o Cloud Shell. É necessário instalar o Cloud SDK.

  5. Instale kubectl, a interface da linha de comando do Kubernetes (em inglês):
    gcloud components install kubectl
  6. Clone o repositório do tutorial do GitHub:
    git clone https://github.com/GoogleCloudPlatform/gke-dedicated-game-server.git
    
  7. Instalar o Docker

    Neste tutorial, não executamos comandos do Docker como o usuário raiz. Por isso, siga também as instruções de pós-instalação para gerenciar o Docker como um usuário não raiz.
  8. (Opcional) Se você quiser testar uma conexão com o servidor de jogos ao final do tutorial, instale o cliente de jogo OpenArena. A execução do cliente de jogo requer um ambiente de área de trabalho. Neste tutorial, incluímos instruções para testes usando Linux ou macOS.

Arquitetura

solução de visão geral do jogo

A página Visão geral da infraestrutura aborda os componentes gerais que são comuns a muitas arquiteturas de jogos on-line. Neste tutorial, você implementa um serviço de front-end de cluster DGS do Kubernetes e um serviço de back-end administrador de escalonamento. Uma infraestrutura completa de jogos de produção também incluiria muitos outros serviços de front-end e back-end, mas eles estão fora do escopo deste tutorial.

Restrições de design para este tutorial

Para produzir um exemplo que seja instrutivo e simples o suficiente para ser estendido, pressupomos as seguintes restrições de jogo:

  • Este é um jogo em tempo real baseado em partidas com um DGS autoritativo que simula o estado do jogo.
  • O DGS se comunica com o cliente via UDP.
  • Cada processo do DGS executa uma partida.
  • Todos os processos do DGS geram aproximadamente a mesma carga.
  • As partidas têm um tempo máximo.
  • O tempo de inicialização do DGS é insignificante e não é necessário pré-aquecimento do processo do servidor dedicado de jogos.
  • Durante o escalonamento após o pico, as partidas não são finalizadas prematuramente para tentar economizar custos. A prioridade é evitar o impacto sobre a experiência do jogador.
  • Se um processo do DGS encontrar um erro e não puder continuar, o estado da partida será perdido e o jogador usará o cliente de jogo para entrar em outra partida.
  • O processo do DGS carrega recursos estáticos do disco, mas não obriga que haja acesso de gravação para eles.

Essas restrições têm precedentes na indústria de jogos e representam um caso de uso real.

Como preparar o ambiente de trabalho do GCP

Para facilitar a execução de comandos gcloud, defina propriedades, de maneira que você não precise fornecer opções para essas propriedades com cada comando.

  1. Defina o projeto padrão usando o código do projeto de [PROJECT_ID]:

    gcloud config set project [PROJECT_ID]
  2. Defina a zona padrão do Compute Engine usando a zona preferida de [ZONE]:

    gcloud config set compute/zone [ZONE]

Inserir o servidor dedicado de jogos em um contêiner

Neste tutorial, você usará o OpenArena, que é descrito como "um QPS de mata-mata produzido por comunidade baseado na tecnologia GPL idTech3". Embora tenha mais de 15 anos, a tecnologia desse jogo ainda é um bom exemplo de um padrão comum do DGS:

  • Um binário de servidor é compilado na mesma base de código do cliente de jogo.
  • Os únicos recursos de dados incluídos no binário de servidor são aqueles necessários para o servidor executar a simulação.
  • A imagem de contêiner do servidor de jogos adiciona à imagem de contêiner do SO base apenas os binários e bibliotecas obrigatórios para executar o processo do servidor.
  • Os recursos são montados em um volume separado.

Essa arquitetura tem muitos benefícios: acelera a distribuição de imagens, reduz a carga de atualização porque somente os binários são substituídos e consome menos espaço em disco.

Como criar a imagem do contêiner

Um Dockerfile descreve a imagem a ser construída. O Dockerfile deste tutorial é fornecido no repositório em openarena/Dockerfile. No diretório openarena/, execute o comando de criação do Docker (em inglês) para gerar a imagem do contêiner e marque-a como a versão 0.8.8 do servidor OpenArena:

docker build -t openarena:0.8.8 .

Como gerar um disco de recursos

Na maioria dos jogos, binários são ordens de grandeza menores que recursos. Por causa disso, faz sentido criar uma imagem de contêiner que tenha apenas binários. Os recursos podem ser colocados em um disco permanente e anexados a várias instâncias de VM que executam o contêiner do DGS. Essa arquitetura economiza dinheiro e elimina a necessidade de distribuir recursos para todas as instâncias de VM.

  1. Crie uma instância pequena de VM do Compute Engine usando gcloud:

    gcloud compute instances create openarena-asset-builder \
        --machine-type f1-micro --image-family debian-9 \
        --image-project debian-cloud
  2. Crie um disco permanente:

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

    O disco permanente precisa ser separado do disco de inicialização, e você precisa configurá-lo para permanecer não excluído quando a máquina virtual é removida. A funcionalidade persistentVolume do Kubernetes funciona melhor no GKE com discos permanentes. De acordo com o Compute Engine, esses discos permanentes precisam consistir em um único sistema de arquivos ext4 sem uma tabela de partições.

  3. Anexe o disco permanente openarena-assets à instância de VM openarena-asset-builder:

    gcloud compute instances attach-disk openarena-asset-builder \
        --disk openarena-assets
  4. Formate o novo disco.

    1. Faça login na instância de VM openarena-asset-builder e formate o disco.

      gcloud compute ssh openarena-asset-builder
    2. O comando mkfs.ext4 na próxima etapa é destrutivo. Por isso, não se esqueça de confirmar o código do dispositivo do disco openarena-assets. Se você estiver seguindo este tutorial desde o início e usando um projeto novo, o código será /dev/sdb. Verifique isso usando o comando lsblk para examinar os discos anexados e as partições deles:

      sudo lsblk

      A saída precisa mostrar o disco de SO de 10 GB sda com uma partição sda1 e o disco de 50 GB openarena-assets sem partição como sdb de dispositivo:

      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. Formate o disco openarena-assets:

      sudo mkfs.ext4 -m 0 -F -E \
          lazy_itable_init=0,lazy_journal_init=0,discard /dev/[DEVICE_ID]
  5. Instale o OpenArena na instância de VM openarena-asset-builder e copie os arquivos de recursos compactados para o disco permanente openarena-assets.

    Para este jogo, os recursos são arquivos .pk3 localizados no diretório /usr/share/games/openarena/baseoa/. Para poupar trabalho, a sequência de comandos a seguir ativa o disco de recursos nesse diretório antes da instalação. Dessa maneira, todos os arquivos .pk3 são colocados no disco pelo processo de instalação. Use o código do dispositivo verificado 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. Saia da instância e a exclua:

    exit
    gcloud compute instances delete openarena-asset-builder

    O disco está pronto para ser usado como um volume permanente no Kubernetes.

Ao implementar discos permanentes como parte do canal de desenvolvimento de jogos, configure o sistema de compilação para criar o disco permanente com todos os arquivos de recursos em uma estrutura de diretórios apropriada. Ele pode utilizar a forma de um script simples executando comandos gcloud ou um plug-in específico do GCP para o sistema de criação escolhido. Também é recomendável criar várias cópias do disco permanente e ter instâncias de VM conectadas a essas cópias de maneira equilibrada, tanto para ter mais capacidade quanto para gerenciar o risco de falha.

Como configurar um cluster do Kubernetes

Kubernetes é um projeto da comunidade de código aberto e, assim, pode ser configurado para ser executado na maioria dos ambientes, inclusive no local.

Como criar um cluster do Kubernetes no Kubernetes Engine

Neste tutorial, usamos um cluster padrão do Kubernetes Engine equipado com o tipo de máquina n1-highcpu, que se ajusta ao perfil de uso do OpenArena.

  1. Crie uma rede da VPC para o jogo chamada game:

    gcloud compute networks create game
  2. Crie uma regra de firewall para o OpenArena:

    gcloud compute firewall-rules create openarena-dgs --network game \
        --allow udp:27961-28061
  3. Use gcloud para criar um cluster de três nós (com quatro núcleos de CPU virtual em cada um) que usa a rede game:

    gcloud container clusters create openarena-cluster \
        --network game --num-nodes 3 --machine-type n1-highcpu-4 \
        --addons KubernetesDashboard
  4. Depois que o cluster for iniciado, configure o shell local com as credenciais de autenticação apropriadas do Kubernetes para controlar o novo cluster:

    gcloud container clusters get-credentials openarena-cluster

Em um cluster de produção, o número de vCPUs que você executará em cada máquina é amplamente influenciado por dois fatores:

  • O maior número de pods do DGS simultâneos que você planeja executar. Há um limite no número de nós em um conjunto de clusters do Kubernetes (em inglês), que o projeto do Kubernetes planeja aumentar em versões futuras. Por exemplo, se você executar um DGS por CPU virtual (vCPU), um cluster de 1.000 nós de máquinas n1-highcpu-2 fornecerá capacidade para apenas 2.000 pods do DGS. Por outro lado, um cluster de 1.000 nós de máquinas n1-highcpu-32 permite até 32.000 pods.

  • A granularidade da instância de VM. A maneira mais simples de adicionar ou remover recursos do cluster é em incrementos de uma única instância de VM do tipo escolhido durante a criação do cluster. Por isso, não escolha uma máquina de 32 vCPUs se você quiser adicionar ou remover capacidade em quantidades menores que 32 vCPUs por vez.

O recurso de grupos de instâncias gerenciadas usado por padrão pelo GKE inclui recursos de dimensionamento automático de instâncias de VM e balanceamento de carga HTTP. No entanto, o comando usado para criar o cluster do Kubernetes desativou esses recursos usando a sinalização --disable-addons HttpLoadBalancing,HorizontalPodAutoscaling.

O balanceamento de carga HTTP não é necessário porque o DGS se comunica com clientes usando UDP, e não TCP. O autoescalador só pode dimensionar o grupo de instâncias atualmente com base no uso da CPU, o que pode ser um indicador enganoso de carga do DGS. Muitos DGSs foram projetados para consumir ciclos ociosos em um esforço para otimizar a simulação do jogo.

Dessa maneira, muitos desenvolvedores de jogos implementam um processo administrador de dimensionamento personalizado ciente do DGS para processar os requisitos específicos desse tipo de carga de trabalho. No entanto, o grupo de instâncias gerenciadas ainda tem uma função importante: o modelo de imagem padrão do GKE inclui todo o software do Kubernetes necessário e registra automaticamente o nó com o mestre na inicialização.

Fazer upload da imagem do contêiner para o GCP

O Google oferece armazenamento particular de imagens do Docker no Container Registry (gcr.io).

  1. Selecione a região do gcr.io mais próxima do cluster do GKE, por exemplo, us para os Estados Unidos, eu para a Europa ou asia para a Ásia, conforme observado na documentação. Em seguida, coloque as informações da região em uma variável de ambiente com o ID do projeto:

    export GCR_REGION=[GCR_REGION] PROJECT_ID=[PROJECT_ID]
  2. Marque a imagem de contêiner com o nome de registro do gcr.io:

    docker tag openarena:0.8.8 \
        ${GCR_REGION}.gcr.io/${PROJECT_ID}/openarena:0.8.8
  3. Faça upload da imagem de contêiner no repositório de imagens:

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

Depois que o envio for concluído, a imagem do contêiner estará disponível para execução no cluster do GKE. Anote a tag de imagem final do contêiner, porque você precisará colocá-la no arquivo de especificação do pod mais tarde.

Como configurar o disco de recursos no Kubernetes

O DGS típico não precisa de acesso de gravação aos recursos do jogo. Dessa maneira, é possível montar cada pod do DGS no mesmo disco permanente que contém recursos somente leitura. Isso é feito usando os recursos persistentVolume (em inglês) e persistentVolumeClaim (em inglês) no Kubernetes.

  1. Aplique asset-volume.yaml, que contém a definição de um recurso persistentVolume do Kubernetes que será vinculado ao disco de recursos criado antes:

    kubectl apply -f openarena/k8s/asset-volume.yaml
  2. Aplique asset-volumeclaim.yaml. Ele contém a definição de um recurso persistentVolumeClaim do Kubernetes, que permitirá que os pods montem o disco de recursos:

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

    Confirme se o volume está no status Bound executando o seguinte 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

    Da mesma maneira, confirme se a declaração está com o status vinculado:

    kubectl get persistentVolumeClaim

    Resultado esperado:

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

Como configurar o pod do DGS

Como as tarefas de reprogramação e rede são processadas pelo Kubernetes e como os tempos de inicialização e desligamento dos contêineres do DGS são insignificantes, neste tutorial, as instâncias do DGS aumentam sob demanda.

Cada instância do DGS dura apenas uma única partida, que tem um limite de tempo definido especificado no arquivo de configuração do servidor do DGS OpenArena. Quando a partida termina, o contêiner é encerrado. Se quiserem jogar novamente, os jogadores solicitarão outro jogo. Esse design simplifica vários aspectos do ciclo de vida do pod e forma a base da política de escalonamento automático abordada posteriormente na seção do administrador de escalonamento.

Esse fluxo não é perfeito com o OpenArena apenas porque o tutorial não se divide e altera o código do cliente de jogo. Em um jogo lançado comercialmente, a solicitação de outra partida seria invisível para o usuário, por trás de tempos de carregamento e telas de resultados de partidas anteriores. O código que requer que o cliente se conecte a uma nova instância de servidor entre partidas não representa um tempo de desenvolvimento extra, porque esse código é sempre obrigatório para processar reconexões de clientes em circunstâncias imprevistas, como problemas de rede ou servidores com falha.

Para simplificar, neste tutorial pressupomos que os nós do GKE têm a configuração de rede padrão, que atribui a cada nó um endereço IP público e permite conexões de cliente.

Como gerenciar o processo do servidor dedicado de jogos

Em servidores de jogos produzidos comercialmente, toda a funcionalidade extra não DGS, que o faz funcionar bem em um contêiner, precisa ser integrada diretamente aos binários do DGS sempre que possível.

Como prática recomendada, o DGS precisa evitar a comunicação direta com o combinador ou o administrador de escalonamento e, em vez disso, expor o estado à Kubernetes API. Os processos externos precisam ler o estado do DGS a partir dos pontos de extremidade apropriados do Kubernetes, em vez de consultar o servidor diretamente. Mais informações sobre como acessar a Kubernetes API diretamente podem ser encontradas na documentação do Kubernetes.

À primeira vista, um único processo em execução em um contêiner com ciclo de vida limitado e critérios de sucesso definidos aparentaria ser um caso de uso para jobs do Kubernetes, mas, na prática, é desnecessário usar jobs. Os processos do DGS não exigem a funcionalidade de execução paralela de jobs. Eles também não exigem a capacidade de garantir sucessos por meio da reinicialização automática. Normalmente quando um DGS baseado em sessão morre por algum motivo, o estado é perdido e os jogadores simplesmente ingressam em outro DGS. Por causa desses fatores, programar pods individuais do Kubernetes é preferível para esse caso de uso.

Na produção, os pods do DGS precisam ser iniciados diretamente pelo combinador usando-se a Kubernetes API. Para os fins deste tutorial, um arquivo YAML legível que descreve o recurso do pod do DGS está incluído no repositório do tutorial em openarena/k8s/openarena-pod.yaml. Ao criar configurações para pods do servidor dedicado de jogos, preste muita atenção nas propriedades do volume para garantir que o disco de recursos possa ser montado no modo somente leitura em vários pods.

Configurar o administrador de dimensionamento

O administrador de dimensionamento é um processo simples que dimensiona o número de máquinas virtuais usadas como nós do GKE, com base na carga atual do DGS. O dimensionamento é realizado usando um conjunto de scripts executados o tempo todo, que inspecionam o número total de pods do DGS em execução e solicitados e que redimensionam o conjunto de nodes conforme necessário. Os scripts são empacotados em imagens de contêiner do Docker que incluem as bibliotecas apropriadas e o SDK do Cloud. As imagens do Docker podem ser criadas e enviadas ao gcr.io usando o procedimento a seguir.

  1. Se necessário, coloque o valor gcr.io GCR_REGION e o PROJECT_ID em variáveis de ambiente do script de construção e envio. Pule esta etapa caso já tenha feito isso quando fez o upload da imagem de contêiner.

    export REGION=[GCR_REGION] PROJECT_ID=[PROJECT_ID]
  2. Altere para o diretório do script:

    cd scaling-manager
  3. Execute o script de criação para criar todas as imagens do contêiner e as envie para gcr.io:

    ./build-and-push.sh
  4. Usando um editor de texto, abra o arquivo de implantação do Kubernetes em scaling-manager/k8s/openarena-scaling-manager-deployment.yaml.

    Os scripts do administrador de escalonamento foram projetados para serem executados em uma implantação do Kubernetes, o que garante que esses processos sejam reiniciados em caso de falha.

  5. Altere as variáveis de ambiente para valores da implementação, conforme listado na seguinte tabela:

    Variável de ambiente Valor padrão Observações
    REGION [GCR_REGION] Requer substituição. A região do repositório do gcr.io.
    PROJECT_ID [PROJECT_ID] Requer substituição. O nome do projeto.
    GKE_BASE_INSTANCE_NAME gke-openarena-cluster-default-pool-[REPLACE_ME] Requer substituição. Diferente para cada cluster do GKE. Para receber o valor de [REPLACE_ME], execute o comando gcloud compute instance-groups managed list.
    GCP_ZONE [ZONE] Requer substituição. O nome da zona do GCP especificada no início deste tutorial.
    K8S_CLUSTER openarena-cluster O nome do cluster do Kubernetes.
  6. Retorne ao diretório pai:

    cd ..
  7. Adicione a implantação ao cluster do Kubernetes:

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

Como os nodes são escalonados

Para escalonar nodes, o gerenciador de escalonamento usa a Kubernetes API para examinar o uso atual do node. Conforme necessário, o gerente redimensiona o grupo de instâncias gerenciadas do cluster do Kubernetes Engine que executa as máquinas virtuais subjacentes.

Preocupações de escalonamento para pods do DGS

Veja alguns dos pontos comuns do escalonamento do DGS:

  • As métricas padrão de uso da CPU e da memória normalmente não capturam informações suficientes para aumentar o escalonamento de instâncias do servidor de jogos.
  • Manter um buffer de nós disponíveis e subutilizados é fundamental, porque a programação de um contêiner do DGS otimizado em um nó atual leva alguns segundos. No entanto, adicionar um nó pode levar alguns minutos, o que é uma latência inaceitável para um jogador em espera.
  • Muitos autoescaladores não são capazes de processar desligamentos de pods tranquilamente. É importante remover pods de nós que estejam sendo removidos. Desligar um nó com pelo menos uma partida em execução costuma ser inaceitável.

Mesmo que os scripts fornecidos por este tutorial sejam básicos, o design simples deles facilita a adição de lógica. Os DGSs típicos têm características de desempenho bem compreendidas e, ao transformá-las em métricas, você pode determinar quando adicionar ou remover instâncias de VM. As métricas de escalonamento comuns são o número de instâncias do DGS por CPU, conforme mostramos neste tutorial, ou o número de slots de jogador disponíveis.

Como expandir

O escalonamento vertical não requer processamento especial neste tutorial. Para simplificar, neste tutorial são definidas as propriedades de pod limits e requests (em inglês) no arquivo YAML do pod (openarena/k8s/openarena-pod.yaml) para reservar aproximadamente uma vCPU para cada DGS, o que é suficiente para o OpenArena.

Como o cluster foi criado usando a família de instâncias n1-highcpu, que tem uma proporção fixa de 600 MB de memória para uma vCPU, é preciso que haja memória suficiente caso um pod do DGS esteja programado por vCPU. Por isso, é possível escalonar verticalmente com base no número de pods no cluster em comparação com o número de CPUs em todos os nós no cluster. Essa proporção determina os recursos restantes disponíveis, permitindo adicionar mais nodes caso o valor fique abaixo de um limite. Este tutorial adicionará nodes se mais de 70% das vCPUs estiverem alocadas a pods atualmente.

Em um back-end de jogo on-line de produção, é recomendável fazer um perfil preciso do uso da CPU, da memória e da rede do DGS, além de definir corretamente as propriedades de pod limits e requests. Para muitos jogos, faz sentido criar vários tipos de pods para cenários do DGS diferentes com perfis de uso distintos, como tipos de jogo, mapas específicos ou número de slots de jogadores. Essas considerações estão fora do escopo deste tutorial.

Como reduzir

A redução, diferentemente da expansão, é um processo de várias etapas e uma das principais razões para executar um administrador de escalonamento do DGS personalizado, ciente do Kubernetes. Neste tutorial, scaling-manger.sh processa automaticamente as seguintes etapas:

  1. Selecionar um nó apropriado para remoção. Como um programador do Kubernetes totalmente personalizado com reconhecimento de jogos está fora do escopo deste tutorial, os nós são selecionados na ordem em que são retornados pela API.

  2. Marcar o nó selecionado como indisponível no Kubernetes. Isso evita que mais pods sejam iniciados no nó.

  3. Remover o nó selecionado do grupo de instâncias gerenciadas usando o comando abandon-instance. Isso evita que o grupo de instâncias gerenciadas tente recriar a instância.

Separadamente, o script node-stopper.sh monitora nós abandonados e não programados em busca da ausência de pods do DGS. Depois que todas as partidas em um node tiverem terminado e os pods saírem, o script desligará a instância da VM.

Como escalonar o número de pods do DGS

Em back-ends de jogos de produção típicos, o combinador controla quando novas instâncias do DGS são adicionadas. Como os pods do DGS são configurados para sair quando as partidas terminarem (consulte as restrições de design apresentadas aqui anteriormente), nenhuma ação explícita é necessária para reduzir o número de pods do DGS. Se não houver solicitações de jogadores suficientes no sistema combinador para gerar novas partidas, os pods do DGS se removerão lentamente do cluster do Kubernetes à medida que as partidas terminarem.

Como testar a configuração

Até agora, você criou a imagem de contêiner do OpenArena e a enviou para o registro do contêiner, além de ter iniciado o cluster do DGS Kubernetes. Além disso, você gerou o disco de recursos do jogo e o configurou para uso no Kubernetes, além de ter iniciado a implantação do gerenciador de escalonamento. Neste momento, é hora de iniciar os pods do DGS para testes.

Como solicitar uma nova instância do DGS

Em um sistema de produção típico, quando o processo de combinação tem jogadores apropriados para uma partida, ele solicita diretamente uma instância usando a Kubernetes API. Para testar a configuração deste tutorial, é possível fazer diretamente a solicitação de uma instância.

  1. Abra openarena/k8s/openarena-pod.yaml em um editor de texto e encontre a linha que especifica a imagem do contêiner a ser executada.

  2. Altere o valor de acordo com a tag de imagem do contêiner openarena. Para isso, basta executar o comando docker tag conforme descrito anteriormente neste tutorial.

  3. Execute o comando kubectl apply, especificando o arquivo openarena-pod.yaml:

    kubectl apply -f openarena/k8s/openarena-pod.yaml
  4. Aguarde um pouco e confirme o status do pod:

    kubectl get pods

    A saída será semelhante a esta:

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

Como se conectar ao DGS

Depois que pod tiver começado, você poderá verificar se pode se conectar ao DGS iniciando o cliente do OpenArena.

De um desktop macOS ou 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}

Como testar o administrador de escalonamento

O administrador de escalonamento dimensiona o número de instâncias de VM no cluster do Kubernetes com base no número de pods do DGS. Portanto, para testar o administrador de escalonamento, é necessário fazer solicitações para vários pods durante um período e verificar se o número de nodes tem o escalonamento correto. Para ver a redução dos nodes, a duração da partida no arquivo de configuração do servidor precisa ter um limite de tempo. O arquivo de configuração do servidor do tutorial em openarena/single-match.cfg coloca um limite de cinco minutos na partida e é usado pelos pods do DGS do tutorial por padrão. Para testar, execute o script a seguir, que adiciona pods do DGS em intervalos regulares por cinco minutos:

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

Você é capaz de ver a expansão e redução do número de nodes executando kubectl get nodes em intervalos regulares.

Como limpar

Para evitar que os recursos usados neste tutorial sejam cobrados na conta do Google Cloud Platform, faça o seguinte:

Excluir o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  1. No Console do GCP, acesse a página Projetos.

    Acessar a página Projetos

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir delete.
  3. Na caixa de diálogo, digite o código do projeto e clique em Encerrar para excluí-lo.

Excluir o cluster do GKE

Se você não quiser excluir o projeto todo, execute o seguinte comando para excluir o cluster do GKE:

gcloud container clusters delete openarena-cluster

Excluir os discos permanentes

Para excluir um disco permanente:

  1. No console do GCP, acesse a página "Discos do Compute Engine".

    Acessar a página "Discos do Compute Engine"

  2. Selecione o disco que você quer excluir.

  3. Clique no botão Excluir na parte superior da página.

Próximas etapas

Neste tutorial, esboçamos uma arquitetura básica para executar servidores dedicados de jogos em contêineres e escalonamento automático de um cluster do Kubernetes com base no carregamento do jogo. Você pode adicionar muitos recursos, como transição perfeita de jogador de sessão para sessão, programando algum suporte básico do lado do cliente. Para adicionar outros recursos, como permitir que os jogadores formem grupos e movam os grupos de servidor para servidor, você pode criar um serviço de plataforma separado ao lado do serviço de combinação. Assim, você pode usar o serviço para formar grupos, enviar, aceitar ou rejeitar convites para grupos e enviar grupos de jogadores para instâncias de servidores dedicados de jogos juntos.

Outro recurso comum é um programador personalizado do Kubernetes capaz de escolher nodes para os pods do DGS de maneira mais inteligente e voltada para o jogo. Para a maioria dos jogos, um programador personalizado que agrupa os pods é altamente desejável, facilitando a priorização da ordem na qual os nós precisam ser removidos durante a redução após o pico.

Mais guias para executar um DGS no GCP:

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…