Crie uma aplicação Web de vários níveis com o Redis e o PHP

Este tutorial demonstra como criar uma aplicação Web de vários níveis usando o Google Kubernetes Engine (GKE).

Neste tutorial, vai fazer o seguinte:

  • Configure uma aplicação 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:

Objetivos

Para implementar e executar a aplicação no GKE:

  1. Configure o líder do Redis
  2. Configure dois seguidores do Redis
  3. Configure a interface Web
  4. Visite o Website
  5. Aumente a escala da interface Web

O diagrama seguinte mostra uma vista geral da arquitetura de cluster que cria ao concluir estes objetivos:

Arquitetura do cluster do GKE

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização prevista, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação gratuita.

Quando terminar as tarefas descritas neste documento, pode evitar a faturação contínua eliminando os recursos que criou. Para mais informações, consulte o artigo Limpe.

Antes de começar

O Cloud Shell está pré-instalado com o software necessário para este tutorial, incluindo kubectl e a CLI gcloud. Se não usar o Cloud Shell, tem de instalar a CLI gcloud.

  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. Se estiver a usar um fornecedor de identidade (IdP) externo, tem primeiro de iniciar sessão na CLI gcloud com a sua identidade federada.

  4. Para inicializar a CLI gcloud, execute o seguinte comando:

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • 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. Verify that billing is enabled for your Google Cloud project.

  7. Enable the GKE API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.

  9. Se estiver a usar um fornecedor de identidade (IdP) externo, tem primeiro de iniciar sessão na CLI gcloud com a sua identidade federada.

  10. Para inicializar a CLI gcloud, execute o seguinte comando:

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • 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. Verify that billing is enabled for your Google Cloud project.

  13. Enable the GKE API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable container.googleapis.com
  14. Prepare o ambiente

    Para configurar o seu ambiente, siga estes passos:

    1. Defina variáveis de ambiente:

      export PROJECT_ID=PROJECT_ID
      export COMPUTE_LOCATION=COMPUTE_LOCATION
      

      Substitua o seguinte:

    2. Clone o repositório do GitHub:

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

      cd kubernetes-engine-samples/quickstarts/guestbook/
      

    Crie um cluster do GKE

    Crie um cluster do GKE Autopilot ou Standard:

    Autopilot

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

    Padrão

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

    Estabeleça ligação ao cluster

    Configure o kubectl para comunicar com o cluster:

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

    Configure o líder do Redis

    A aplicação usa o Redis para armazenar os respetivos dados. A aplicação escreve os respetivos dados numa instância principal do Redis e lê dados de várias instâncias seguidoras do Redis.

    1. O manifesto seguinte descreve uma implementaçã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 é semelhante ao seguinte:

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

      A alteração do STATUS de Pending para Running pode demorar vários minutos.

    Crie o serviço líder do Redis

    A aplicação Web tem de comunicar com o líder do Redis para escrever os respetivos dados. Pode criar um serviço para encaminhar o tráfego para o pod principal 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. Quando cria um serviço, descreve que pods encaminhar com base nas etiquetas dos pods.

    1. O manifesto seguinte 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

      Este manifesto inclui um conjunto de seletores de etiquetas. Estas etiquetas correspondem ao conjunto de etiquetas implementadas no passo anterior. Por conseguinte, este serviço encaminha o tráfego de rede para o pod principal do Redis criado num passo anterior.

      A secção ports do manifesto declara um único mapeamento de portas. O serviço encaminha o tráfego em port: 6379 para o targetPort: 6379 dos contentores que correspondem às etiquetas selector especificadas. O containerPort usado na implementação tem de corresponder ao targetPort para encaminhar o tráfego para a implementaçã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 é semelhante ao seguinte:

      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
      

    Configure seguidores do Redis

    Embora o líder do Redis seja um único pod, pode torná-lo altamente disponível e satisfazer as exigências de tráfego adicionando alguns seguidores ou réplicas do Redis.

    1. O manifesto seguinte descreve uma implementação para os pods 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 seguidoras do Redis estão em execução:

      kubectl get pods
      

      O resultado é semelhante ao seguinte:

      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
      

      A alteração do STATUS de Pending para Running pode demorar vários minutos.

    Crie o serviço seguidor do Redis

    A aplicação Web tem de comunicar com os seguidores do Redis para ler os dados. Para tornar os seguidores do Redis detetáveis, tem de configurar um serviço.

    1. O manifesto seguinte 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

      Este manifesto especifica que o serviço é executado na porta 6379. O campo selector do serviço corresponde aos pods seguidores do Redis criados no passo 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 é semelhante ao seguinte:

      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
      

    Configure a interface Web da aplicação

    Agora que tem armazenamento Redis para a sua aplicação, inicie os servidores Web. Tal como os seguidores do Redis, o front-end é implementado através de uma implementação do Kubernetes.

    A aplicação Web usa um front-end PHP, que está configurado para comunicar com os serviços de seguidor ou líder do Redis, consoante o pedido seja de leitura ou escrita. O front-end expõe uma interface JSON e disponibiliza uma IU baseada em jQuery Ajax.

    1. O manifesto seguinte descreve uma implementação para o servidor 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 ficheiro de manifesto especifica a variável de ambiente GET_HOSTS_FROM=dns. Quando fornece a configuração à aplicação Web de front-end, a aplicação de front-end usa os nomes de anfitrião redis-follower e redis-leader para fazer uma procura de DNS. A pesquisa de DNS encontra os endereços IP dos serviços que criou nos passos anteriores. Este conceito é denominado deteção 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 é semelhante ao seguinte:

      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
      

    Exponha o front-end num endereço IP externo

    Com a configuração atual, os serviços redis-follower e redis-leader que criou nos passos anteriores só estão acessíveis no cluster do GKE, porque o tipo predefinido de um serviço é ClusterIP.

    Um serviço ClusterIP fornece um único endereço IP para o conjunto de pods para o qual o serviço está a apontar. Este endereço IP só está acessível no cluster.

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

    O manifesto seguinte 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 secção ports especifica port: 80 e targetPort não está especificado. Quando omite a propriedade targetPort, esta assume por predefinição o valor do campo port. Neste caso, este serviço encaminha o tráfego externo na porta 80 para a porta 80 dos contentores na implementaçã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. Estes recursos estão sujeitos a faturação.

    Visite o Website da aplicação

    Para aceder ao Website da aplicação, obtenha o endereço IP externo do frontend serviço:

    kubectl get service frontend
    

    O resultado é semelhante ao seguinte:

    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á a ser criado. Pode demorar alguns minutos. Se vir erros como Does not have minimum availability, aguarde alguns minutos. Este 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:

    Aplicação Web em execução no GKE

    Experimente adicionar algumas entradas escrevendo uma mensagem e clicando em Enviar. A mensagem que escreveu aparece no frontend. Esta mensagem indica que os dados foram adicionados com êxito ao Redis através dos serviços que criou.

    Aumente a escala da interface Web

    Suponha que a sua aplicação está em execução há algum tempo e recebe um aumento repentino de publicidade. Decide que seria uma boa ideia adicionar mais servidores Web ao seu frontend. Pode fazê-lo aumentando o número de pods.

    1. Aumente o número de agrupamentos frontend:

      kubectl scale deployment frontend --replicas=5
      

      O resultado é semelhante ao seguinte:

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

      kubectl get pods
      

      O resultado é semelhante ao seguinte:

      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
      

      Pode reduzir o número de frontendpods usando o mesmo comando, substituindo 5 por 1.

    Limpar

    Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste tutorial, elimine o projeto que contém os recursos ou mantenha o projeto e elimine os recursos individuais.

    Elimine o projeto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Elimine os recursos individuais

    Se usou um projeto existente e não o quer eliminar, elimine os recursos individuais.

    1. Elimine o frontend serviço:

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

      gcloud container clusters delete guestbook
      

    O que se segue?