Criar um web app de várias camadas com Redis e PHP


Neste tutorial, mostramos como criar um aplicativo da Web de várias camadas usando o Google Kubernetes Engine (GKE).

Neste tutorial, você faz as ações a seguir:

  • Configure um aplicativo da Web com um endereço IP externo e um balanceador de carga.
  • Crie um cluster Redis com um único mestre (líder) e várias réplicas (seguidores).

O exemplo descreve os seguintes conceitos do Kubernetes:

  • Configuração declarativa usando arquivos de manifestos YAML.
  • Implantações, que são recursos do Kubernetes que determinam a configuração de um conjunto de pods replicados.
  • Serviços para criar balanceadores de cargas internos e externos em um conjunto de pods.

Objetivos

Para implantar e executar o aplicativo no GKE:

  1. Configurar o líder do Redis
  2. Configurar dois seguidores do Redis
  3. Configurar o front-end da Web
  4. Acesse o site
  5. Escalonar o front-end da Web

No diagrama a seguir, mostramos uma visão geral da arquitetura de cluster que você cria ao concluir estes objetivos:

Arquitetura do cluster do GKE

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

O Cloud Shell vem pré-instalado com o software necessário para este tutorial, incluindo kubectl e gcloud CLI. Se você não usa o Cloud Shell, é necessário instalar a gcloud CLI.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.
  3. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  4. To initialize the gcloud CLI, run the following command:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the GKE API:

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.
  9. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  10. To initialize the gcloud CLI, run the following command:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Make sure that billing is enabled for your Google Cloud project.

  13. Enable the GKE API:

    gcloud services enable container.googleapis.com

prepare o ambiente

Para configurar o ambiente, siga estas etapas:

  1. Defina as variáveis de ambiente:

    export PROJECT_ID=PROJECT_ID
    export COMPUTE_LOCATION=COMPUTE_LOCATION
    

    Substitua:

  2. Clone o repositório do GitHub:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  3. Mude para o diretório de trabalho:

    cd kubernetes-engine-samples/quickstarts/guestbook/
    

Crie um cluster do GKE

Crie um cluster do Autopilot ou do GKE padrão:

Piloto automático

gcloud container clusters create-auto guestbook \
    --location=${COMPUTE_LOCATION} \

Standard

gcloud container clusters create guestbook \
    --location=${COMPUTE_LOCATION} \
    --num-nodes=4

Conectar ao cluster

Configure kubectl para se comunicar com o cluster:

gcloud container clusters get-credentials guestbook \
    --location=${COMPUTE_LOCATION}

Configurar o líder do Redis

No aplicativo, o Redis é usado para armazenar os dados. O aplicativo grava os dados em uma instância líder do Redis e lê os dados de várias instâncias de seguidores do Redis.

  1. No manifesto a seguir, descrevemos uma implantação do Kubernetes que executa um pod líder do Redis de réplica única:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-leader
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
            role: leader
            tier: backend
        spec:
          containers:
          - name: leader
            image: "docker.io/redis:6.0.5"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 6379

    Aplique o manifesto ao cluster:

    kubectl apply -f redis-leader-deployment.yaml
    
  2. Verifique se o pod líder do Redis está em execução:

    kubectl get pods
    

    O resultado será assim:

    NAME                           READY     STATUS    RESTARTS   AGE
    redis-leader-343230949-qfvrq   1/1       Running   0          43s
    

    Pode levar vários minutos para que STATUS mude de Pending para Running.

Criar o serviço de líder do Redis

O aplicativo precisa se comunicar com o líder do Redis para gravar os dados. É possível criar um serviço para redirecionar o tráfego ao pod do líder do Redis.

Um serviço é uma abstração do Kubernetes que define um conjunto lógico de pods e uma política para permitir o acesso aos pods. Ao criar um serviço, você descreve quais pods proxy com base nos rótulos.

  1. O manifesto a seguir descreve um serviço para o líder do Redis:

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-leader
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      ports:
      - port: 6379
        targetPort: 6379
      selector:
        app: redis
        role: leader
        tier: backend

    Esse manifesto inclui um conjunto de seletores de rótulos. Esses rótulos são iguais ao conjunto implantado na etapa anterior. Portanto, esse serviço faz o roteamento do tráfego de rede para o pod do líder do Redis criado em uma etapa anterior.

    A seção ports do manifesto apresenta um único mapeamento de porta. O serviço encaminha o tráfego em port: 6379 para targetPort: 6379 dos contêineres que correspondem aos rótulos selector especificados. O containerPort usado na implantação precisa corresponder a targetPort para rotear o tráfego para a implantação.

    Aplique o manifesto ao cluster:

    kubectl apply -f redis-leader-service.yaml
    
  2. Verifique se o GKE criou o serviço:

    kubectl get service
    

    O resultado será assim:

    NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes     10.51.240.1     <none>        443/TCP    42s
    redis-leader   10.51.242.233   <none>        6379/TCP   12s
    

Configurar seguidores do Redis

Embora o líder do Redis seja um único pod, é possível torná-lo altamente disponível e atender às demandas de tráfego adicionando algumas réplicas ou seguidores do Redis.

  1. No manifesto a seguir, descrevemos uma implantação para os pods de seguidores do Redis:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-follower
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
            role: follower
            tier: backend
        spec:
          containers:
          - name: follower
            image: us-docker.pkg.dev/google-samples/containers/gke/gb-redis-follower:v2
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 6379
  2. Aplique o manifesto ao cluster:

    kubectl apply -f redis-follower-deployment.yaml
    
  3. Verifique se as duas réplicas de seguidores do Redis estão em execução:

    kubectl get pods
    

    O resultado será assim:

    NAME                              READY   STATUS    RESTARTS   AGE
    redis-follower-76588f55b7-bnsq6   1/1     Running   0          27s
    redis-follower-76588f55b7-qvtws   1/1     Running   0          27s
    redis-leader-dd446dc55-kl7nl      1/1     Running   0          119s
    

    Pode levar vários minutos para que STATUS mude de Pending para Running.

Criar o serviço de seguidor do Redis

O aplicativo da Web precisa se comunicar com os seguidores do Redis para ler os dados. Para que os seguidores do Redis possam ser descobertos, configure um serviço.

  1. O manifesto a seguir descreve um serviço para os seguidores do Redis:

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-follower
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      ports:
        # the port that this service should serve on
      - port: 6379
      selector:
        app: redis
        role: follower
        tier: backend

    Esse manifesto especifica que o serviço é executado na porta 6379. O campo selector do serviço corresponde aos pods de seguidores do Redis criados na etapa anterior.

    Aplique o manifesto ao cluster:

    kubectl apply -f redis-follower-service.yaml
    
  2. Verifique se o GKE criou o serviço:

    kubectl get service
    

    O resultado será assim:

    NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes     10.51.240.1     <none>        443/TCP    1m
    redis-leader   10.51.242.233   <none>        6379/TCP   49s
    redis-follower 10.51.247.238   <none>        6379/TCP   3s
    

Configurar o front-end da Web do aplicativo

Agora que você tem o armazenamento Redis para seu aplicativo, inicie os servidores da Web. Assim como os seguidores do Redis, o front-end é implantado usando uma implantação do Kubernetes.

O aplicativo da Web usa um front-end PHP, que é configurado para se comunicar com os serviços de líder ou seguidor do Redis, dependendo de a solicitação ser de leitura ou gravação. O front-end apresenta uma interface JSON e veicula uma IU baseada em jQuery-Ajax.

  1. O manifesto a seguir descreve uma implantação para o servidor da Web:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
    spec:
      replicas: 3
      selector:
        matchLabels:
            app: guestbook
            tier: frontend
      template:
        metadata:
          labels:
            app: guestbook
            tier: frontend
        spec:
          containers:
          - name: php-redis
            image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5
            env:
            - name: GET_HOSTS_FROM
              value: "dns"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 80

    O arquivo de manifesto especifica a variável de ambiente GET_HOSTS_FROM=dns. Quando você fornece a configuração para o aplicativo de front-end da Web, o aplicativo de front-end usa os nomes de host redis-follower e redis-leader para realizar uma busca DNS. A busca DNS encontra os endereços IP dos serviços criados nas etapas anteriores. Esse conceito é chamado de descoberta de serviços DNS.

    Aplique o manifesto ao cluster:

    kubectl apply -f frontend-deployment.yaml
    
  2. Verifique se as réplicas estão em execução:

    kubectl get pods -l app=guestbook -l tier=frontend
    

    O resultado será assim:

    NAME                        READY   STATUS    RESTARTS   AGE
    frontend-7b78458576-8kp8s   1/1     Running   0          37s
    frontend-7b78458576-gg86q   1/1     Running   0          37s
    frontend-7b78458576-hz87g   1/1     Running   0          37s
    

Expor o front-end em um endereço IP externo

Com a configuração atual, os serviços redis-follower e redis-leader criados nas etapas anteriores só podem ser acessados no cluster do GKE porque o tipo padrão de um serviço é ClusterIP.

Um serviço ClusterIP fornece um único endereço IP para o conjunto de pods para onde o serviço está apontando. Esse endereço IP só é acessível no cluster.

Para tornar o serviço de front-end da Web acessível externamente, é possível especificar type: LoadBalancer ou type: NodePort na configuração do serviço, dependendo de seus requisitos.

O manifesto a seguir descreve um serviço do tipo LoadBalancer.

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  type: LoadBalancer
  ports:
    # the port that this service should serve on
  - port: 80
  selector:
    app: guestbook
    tier: frontend

A declaração de porta na seção ports especifica port: 80 e targetPort não é especificado. Quando você omite a propriedade targetPort, o padrão é o valor do campo port. Nesse caso, o serviço encaminha o tráfego externo da porta 80 para a porta 80 dos contêineres na implantação frontend.

Aplique o manifesto ao cluster:

kubectl apply -f frontend-service.yaml

Quando o serviço frontend é criado, o GKE cria um balanceador de carga e um endereço IP externo. Esses recursos estão sujeitos à cobrança.

Acessar o site do aplicativo

Para acessar o site do aplicativo, veja o endereço IP externo do serviço frontend:

kubectl get service frontend

O resultado será assim:

NAME       CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
frontend   10.51.242.136   109.197.92.229     80:32372/TCP   1m

A coluna EXTERNAL-IP pode mostrar <pending> enquanto o balanceador de carga está sendo criado. Isso pode levar alguns minutos. Se você encontrar erros como Does not have minimum availability, aguarde alguns minutos. Esse erro temporário ocorre porque o GKE recria os nós para fazer as alterações.

Copie o endereço IP e abra a página no navegador:

Aplicativo da Web em execução no GKE

Tente adicionar algumas entradas digitando uma mensagem e clicando em Enviar. A mensagem que você digitou aparece no front-end. Essa mensagem indica que os dados foram adicionados ao Redis por meio dos Serviços que você criou.

Escalonar o front-end da Web

Suponha que seu aplicativo esteja em execução há algum tempo e de repente fique famoso. Você decide que seria uma boa ideia adicionar mais servidores Web ao seu front-end. Para isso, aumente o número de pods.

  1. Amplie o número de pods frontend:

    kubectl scale deployment frontend --replicas=5
    

    O resultado será assim:

    deployment.extensions/frontend scaled
    
  2. Verifique o número de réplicas em execução:

    kubectl get pods
    

    O resultado será assim:

    NAME                             READY     STATUS    RESTARTS   AGE
    frontend-88237173-3s3sc          1/1       Running   0          1s
    frontend-88237173-twgvn          1/1       Running   0          1s
    frontend-88237173-5p257          1/1       Running   0          23m
    frontend-88237173-84036          1/1       Running   0          23m
    frontend-88237173-j3rvr          1/1       Running   0          23m
    redis-leader-343230949-qfvrq     1/1       Running   0          54m
    redis-follower-132015689-dp23k   1/1       Running   0          37m
    redis-follower-132015689-xq9v0   1/1       Running   0          37m
    

    É possível reduzir o número de pods frontend usando o mesmo comando, substituindo 5 por 1.

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Exclua o projeto

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

Excluir recursos individuais

Se você usou um projeto existente e não quer excluí-lo, exclua os recursos individuais.

  1. Exclua o serviço frontend:

    kubectl delete service frontend
    
  2. Exclua o cluster do GKE:

    gcloud container clusters delete guestbook
    

A seguir