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, faz 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:

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. Mude 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 principal 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 estado 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 estado 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 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 de 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ó sã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 de frontend Web 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 à sua interface. Pode fazê-lo aumentando o número de pods.

  1. Aumente o número de agrupamentos de 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.