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. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. 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.

  5. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  6. Enable the GKE API:

    gcloud services enable container.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. 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.

  10. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  11. 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