Cloud CDN

Nesta página, mostramos como usar um recurso personalizado do BackendConfig para configurar o Cloud CDN (Cloud CDN) no Google Kubernetes Engine.

Visão geral

Em um cluster do GKE, o tráfego de entrada é processado pelo balanceamento de carga HTTP(S), que é um componente do Cloud Load Balancing. Normalmente, o balanceador de carga HTTP(S) é configurado pelo controlador de entrada do GKE, que recebe informações de configuração de um objeto de entrada do Kubernetes. A entrada está associada a um ou mais objetos de serviço. Cada serviço contém informações de encaminhamento que são usadas para encaminhar uma solicitação de entrada para um determinado pod e porta.

A partir da versão 1.10.5-gke.3 do Kubernetes, é possível fornecer configuração extra para o balanceador de carga. Basta associar uma porta de serviço a um recurso personalizado denominado BackendConfig.

O controlador do GKE Ingress lê as informações de configuração do BackendConfig e configura o balanceador de carga da forma adequada. Um BackendConfig contém informações de configuração específicas do Cloud Load Balancing. Os recursos de entrada e serviço do Kubernetes não oferecem uma maneira de configurar recursos específicos do provedor, como o Cloud CDN. O BackendConfig fornece uma maneira de você fazer essa configuração.

Aqui está a ideia geral de como você configura um BackendConfig neste exercício:

  1. Crie um BackendConfig.
  2. Crie um serviço e associe uma das respectivas portas ao BackendConfig.
  3. Crie uma entrada e associe-a ao par (serviço, porta).

Antes de começar

Prepare-se para a tarefa tomando as seguintes medidas:

  • Verifique se você ativou a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Verifique se o SDK do Cloud está instalado.
  • Defina o código padrão do projeto:
    gcloud config set project [PROJECT_ID]
  • Se você estiver trabalhando com clusters zonais, defina a zona de computação padrão:
    gcloud config set compute/zone [COMPUTE_ZONE]
  • Se você estiver trabalhando com clusters regionais, defina a região de computação padrão:
    gcloud config set compute/region [COMPUTE_REGION]
  • Atualize o gcloud para a versão mais recente:
    gcloud components update
  • Leia a [Visão geral do Cloud CDN].

  • Leia sobre o [armazenamento em cache do Cloud CDN].

  • Leia sobre os recursos de entrada e serviço do Kubernetes.

  • Familiarize-se com o recurso personalizado BackendConfig.

Como criar um namespace

Crie um namespace do Kubernetes para os objetos deste guia:

kubectl create namespace cdn-how-to

Como criar uma implantação

Este manifesto de implantação declara que você quer executar duas réplicas do aplicativo da Web ingress-gce-echo-amd64:

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: cdn-how-to
  name: my-deployment
spec:
  selector:
    matchLabels:
      purpose: demonstrate-cdn
  replicas: 2
  template:
    metadata:
      labels:
        purpose: demonstrate-cdn
    spec:
      containers:
      - name: echo-amd64
        image: gcr.io/google-samples/hello-app-cdn:1.0

Copie o manifesto para um arquivo denominado my-deployment.yaml e crie a implantação:

kubectl apply -f my-deployment.yaml

Como criar um BackendConfig

Veja aqui um manifesto de um BackendConfig. No manifesto, fica especificada uma política de cache do Cloud CDN e declarado que o Cloud CDN precisa estar ativado:

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  namespace: cdn-how-to
  name: my-backend-config
spec:
  cdn:
    enabled: true
    cachePolicy:
      includeHost: true
      includeProtocol: true
      includeQueryString: false

Copie o manifesto para um arquivo denominado my-backend-config.yaml e crie o BackendConfig:

kubectl apply -f my-backend-config.yaml

Veja o BackendConfig:

kubectl get backendconfig my-backend-config --output yaml --namespace cdn-how-to

Veja a política de cache do Cloud CDN na saída:

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: my-backend-config
  namespace: cdn-how-to
  ...
spec:
  cdn:
    cachePolicy:
      includeHost: true
      includeProtocol: true
      includeQueryString: false
    enabled: true

Como criar um serviço

Veja aqui um manifesto de um serviço:

apiVersion: v1
kind: Service
metadata:
  namespace: cdn-how-to
  name: my-service
  labels:
    purpose: demonstrate-cdn
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
spec:
  type: NodePort
  selector:
    purpose: demonstrate-cdn
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080

Salve o manifesto em um arquivo denominado my-service.yaml e crie o serviço:

kubectl apply -f my-service.yaml

Veja o serviço:

kubectl get service my-service --namespace cdn-how-to --output yaml

A saída é semelhante a esta:

apiVersion: v1
kind: Service
metadata:
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
    ...
  labels:
    purpose: demonstrate-cdn
  name: my-service
  namespace: cdn-how-to
  ...
spec:
  clusterIP: 10.51.255.39
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 31484
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    purpose: demonstrate-cdn
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

Para os fins deste exercício, estas são as coisas importantes a serem observadas sobre o serviço:

  • A porta 80 do serviço está associada a um BackendConfig denominado my-backend-config. A anotação beta.cloud.google.com/backend-config especifica isso.

  • O serviço tem o tipo NodePort. Ele é típico para os serviços que serão associados a uma Entrada.

  • Qualquer pod que tenha o rótulo purpose: demonstrate-cdn é um membro do serviço. O campo selector especifica isso.

  • O tráfego direcionado ao serviço na porta TCP 80 é encaminhado para a porta TCP 8080 em um dos pods membros. Os campos port e targetPort especificam isso.

Como reservar um endereço IP externo estático

Reserve um endereço IP externo estático:

gcloud compute addresses create cdn-how-to-address --global

Visualize seu endereço IP externo estático:

gcloud compute addresses list --filter "name=cdn-how-to-address"

A saída mostra o nome e o valor do endereço:

NAME                ...     ADDRESS        STATUS
cdn-how-to-address          203.0.113.1    RESERVED

Como criar uma entrada

Veja aqui um manifesto de uma entrada:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: cdn-how-to
  name: my-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "cdn-how-to-address"
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-service
          servicePort: 80

Copie o manifesto para um arquivo denominado my-ingress.yaml e crie a Entrada:

kubectl apply -f my-ingress.yaml

Aguarde dez minutos para que o controlador de Entrada do Kubernetes configure um balanceador de carga do Cloud e visualize a Entrada:

kubectl get ingress my-ingress --output yaml --namespace cdn-how-to

A saída é semelhante a esta:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  ...
  name: my-ingress
  namespace: cdn-how-to
  ...
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: my-service
          servicePort: 80
        path: /*
status:
  loadBalancer:
    ingress:
    - ip: 201.0.113.1

Para o propósito deste exercício, aqui estão as coisas importantes a serem observadas sobre a entrada:

  • O endereço IP para o tráfego de entrada é listado em loadBalancer:ingress:.

  • A Entrada tem uma regra que se aplica a solicitações HTTP de entrada de qualquer host. Isso ocorre porque não há nenhum campo host na regra. Portanto, por padrão, a regra se aplica a todos os hosts.

  • Todas as solicitações recebidas são tratadas da mesma forma, independentemente do caminho do URL. Isso é especificado pelo valor /* de path.

  • As solicitações recebidas são encaminhadas para um pod que é membro de my-service. Neste exercício, os pods membros têm o rótulo purpose: demonstrate-cdn.

  • As solicitações são encaminhadas para o pod na porta de destino especificada em my-service. Neste exercício, a porta de destino do pod é 8080.

Como visualizar o aplicativo da Web

Digite este comando curl duas vezes:

curl -v [STATIC_ADDRESS]/?cache=true

em que [STATIC_ADDRESS] é seu endereço IP externo estático.

A saída mostra os cabeçalhos e o corpo de resposta. Nos cabeçalhos, é possível ver que o conteúdo foi armazenado em cache. O cabeçalho Age informa quantos segundos o conteúdo foi armazenado em cache:

...
< HTTP/1.1 200 OK
< Date: Fri, 25 Jan 2019 02:34:08 GMT
< Content-Length: 70
< Content-Type: text/plain; charset=utf-8
< Via: 1.1 google
< Cache-Control: max-age=86400,public
< Age: 2716
<
Hello, world!
Version: 1.0.0
Hostname: my-deployment-7f589cc5bc-l8kr8

Como visualizar registros de balanceamento de carga

Verifique se o conteúdo foi armazenado em cache visualizando os registros do Stackdriver para o balanceamento de carga HTTP. Antes disso, certifique-se de que solicitou uma resposta do aplicativo pelo menos duas vezes.

Console

No Console do GCP, acesse a página Registros no menu Registros.

Acessar a página "Registros"

No primeiro menu suspenso, selecione balanceador de carga de HTTP do Cloud.

Expanda a entrada de registro mais recente e o campo httpRequest.

No campo httpRequest, é possível ver que cacheHit é true.

httpRequest: {
cacheHit:  true
cacheLookup:  true
...

gcloud

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/requests"' \
    --limit 2

em que [PROJECT_ID] é o código do projeto.

A saída mostra que houve uma ocorrência em cache:

httpRequest:
cacheHit: true
cacheLookup: true

Limitações

O Cloud CDN e o Cloud Identity-Aware Proxy não podem ser ativados para o mesmo serviço de back-end de balanceamento de carga HTTP(S).

Solução de problemas

BackendConfig não encontrado

Este erro ocorre quando um BackendConfig para uma porta de serviço é especificado na anotação do serviço, mas o recurso BackendConfig real não é encontrado. Isso pode ocorrer se você não criou o recurso BackendConfig, criou-o no namespace incorreto ou digitou incorretamente a referência na anotação do serviço.

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service “default/my-service”:
no BackendConfig for service port exists

Cloud CDN e Cloud IAP ativados

Este erro ocorre quando você ativa o Cloud IAP e o Cloud CDN em um BackendConfig.

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: BackendConfig default/config-default is not valid:
iap and cdn cannot be enabled at the same time.

O conteúdo não está sendo armazenado em cache

Se você achar que seu conteúdo não está sendo armazenado em cache, verifique se seu aplicativo está configurado corretamente para ativar o armazenamento em cache do conteúdo. Para mais informações, consulte Capacidade de armazenamento em cache.

Como fazer a limpeza

Depois de concluir os exercícios nesta página, siga estas etapas para remover os recursos e evitar cobranças indesejadas na conta:

Exclua os objetos do Kubernetes que você criou para este exercício:

kubectl delete ingress my-ingress --namespace cdn-how-to
kubectl delete service my-service --namespace cdn-how-to
kubectl delete backendconfig my-backend-config --namespace cdn-how-to
kubectl delete deployment my-deployment --namespace cdn-how-to
kubectl delete namespace cdn-how-to

Exclua seu endereço IP externo estático:

gcloud compute addresses delete cdn-how-to-address --global

A seguir

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

Enviar comentários sobre…

Documentação do Kubernetes Engine