Como configurar o Google Cloud Armor

Nesta página, você aprenderá a usar um recurso personalizado de BackendConfig para configurar o Google Cloud Armor 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 Ingress do GKE (em inglês), que recebe informações de configuração de um objeto Ingress do Kubernetes. Ingress está associado a um ou mais objetos Service. Cada objeto Service contém informações de roteamento que são usadas para direcionar 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 outras configurações para o balanceador de carga. Para isso, basta associar uma porta de Service a um recurso personalizado (em inglês) 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 Ingress e Service do Kubernetes não oferecem uma maneira de configurar recursos específicos do provedor, como o Google Cloud Armor. No entanto, o BackendConfig fornece uma maneira de fazer essa configuração.

Aqui está a ideia geral de como configurar um BackendConfig neste exercício:

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

Antes de começar

Execute as etapas a seguir para se preparar para a tarefa:

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

Como criar um namespace

Crie um namespace do Kubernetes para os objetos deste guia:

kubectl create namespace cloud-armor-how-to

Como criar uma implantação

Este manifesto de implantação declara que você quer executar duas réplicas do aplicativo da Web hello-app:

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: cloud-armor-how-to
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: hello-app
  replicas: 2
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app-container
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080

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

kubectl apply -f my-deployment.yaml

Como criar uma regra e uma política de segurança do Google Cloud Armor

Crie uma política de segurança do Google Cloud Armor:

gcloud beta compute security-policies create ca-how-to-security-policy \
    --description "policy for Google Cloud Armor how-to topic"

Crie uma regra para sua política de segurança:

gcloud beta compute security-policies rules create 1000 \
    --security-policy ca-how-to-security-policy \
    --description "Deny traffic from 192.0.2.0/24." \
    --src-ip-ranges "192.0.2.0/24" \
    --action "deny-404"

Veja a política de segurança:

gcloud beta compute security-policies describe ca-how-to-security-policy

Saída:

...
kind: compute#securityPolicy
name: ca-how-to-security-policy
rules:
- action: deny(404)
  description: Deny traffic from 192.0.2.0/24.
  kind: compute#securityPolicyRule
  match:
    config:
      srcIpRanges:
      - 192.0.2.0/24
    versionedExpr: SRC_IPS_V1
  preview: false
  priority: 1000
  ...

Como criar um BackendConfig

Aqui está um manifesto para um BackendConfig. O manifesto especifica uma política de segurança:

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backend-config
spec:
  securityPolicy:
    name: "ca-how-to-security-policy"

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 --namespace cloud-armor-how-to --output yaml

A saída mostra a política de segurança especificada:

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: my-backend-config
  namespace: cloud-armor-how-to
  ...
spec:
  securityPolicy:
    name: ca-how-to-security-policy

Como criar um serviço

Veja o manifesto de um Service:

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

Salve o manifesto em um arquivo chamado my-service.yaml e crie o Service:

kubectl apply -f my-service.yaml

Veja o Service:

kubectl get service my-service --namespace cloud-armor-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:
    app: hello-app
  name: my-service
  namespace: cloud-armor-how-to
  ...
spec:
  clusterIP: 10.19.249.137
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 32629
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello-app
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

Para os fins deste exercício, estes são os pontos mais importantes a serem observados sobre seu Service:

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

  • O Service tem o tipo NodePort. Esse é o tipo necessário para os Services que serão associados a um Ingress.

  • Qualquer pod que tenha o rótulo app: hello-app é um membro do Service. O campo selector especifica isso.

  • O tráfego direcionado ao Service 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 cloud-armor-how-to-address --global

Veja o endereço IP externo estático:

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

Saída:

NAME                        REGION  ADDRESS        STATUS
cloud-armor-how-to-address          203.0.113.2    RESERVED

Como criar uma Entrada

Veja aqui um manifesto de um Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: cloud-armor-how-to
  name: my-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "cloud-armor-how-to-address"
spec:
  backend:
    serviceName: my-service
    servicePort: 80

Copie o manifesto para um arquivo chamado my-ingress.yaml e crie o Ingress:

kubectl create -f my-ingress.yaml

Aguarde alguns minutos para que o controlador Ingress do Kubernetes configure um balanceador de carga do Cloud e visualize Ingress:

kubectl get ingress my-ingress --output yaml --namespace cloud-armor-how-to

Saída:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: cloud-armor-how-to
  ...
spec:
  backend:
    serviceName: my-service
    servicePort: 80
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.2

Para os fins deste exercício, estes são os pontos mais importantes a serem observados sobre Ingress:

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

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

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

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

  • 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

Aguarde alguns minutos. Em seguida, no seu navegador, digite o endereço IP externo estático.

A página exibe a resposta do aplicativo da Web hello-app que está sendo executado em um dos pods da sua implantação:

Hello, world!
Version: 1.0.0
Hostname: my-deployment-574ddbdf88-f9fbj

Use curl para visualizar o aplicativo da Web:

curl -v [STATIC_ADDRESS]

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

A saída é a resposta de hello-app:

Hello, world!
Version: 1.0.0
Hostname: my-deployment-574ddbdf88-zpb94

Como separar a política de segurança

Para separar a política de segurança de uma Entrada, defina o nome da política de segurança como vazia no BackendConfig. Aqui está um exemplo de separação da política de segurança:

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backend-config
spec:
  securityPolicy:
    name: ""

Limitações

Limite de cota

Há um limite absoluto no número de regras do Google Cloud Armor que podem ser escritos enquanto esse recurso está na versão Beta. Esse limite será removido quando o recurso estiver com disponibilidade geral.

Somente listas de permissões e proibições de IP

O Google Cloud Armor é compatível apenas com listas de permissões e proibições de IP.

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

Política de segurança não encontrada

Depois que o objeto de Entrada for criado, se a política de segurança não estiver adequadamente associada ao serviço de balanceador de carga, avalie o evento do Kubernetes para ver se há um erro de configuração. Especificamente, se o BackendConfig indicar uma política inexistente, um evento de aviso será emitido periodicamente. Para corrigir esse problema, especifique a política de segurança correta, por nome, no BackendConfig.

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

MESSAGE
Error during sync: The given security policy "my-policy" does not exist.

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 cloud-armor-how-to
kubectl delete service my-service --namespace cloud-armor-how-to
kubectl delete backendconfig my-backend-config --namespace cloud-armor-how-to
kubectl delete deployment my-deployment --namespace cloud-armor-how-to
kubectl delete namespace cloud-armor-how-to

Exclua o endereço IP externo estático:

gcloud compute addresses delete cloud-armor-how-to-address --global

Exclua a política de segurança:

gcloud beta compute security-policies delete ca-how-to-security-policy

A seguir

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

Enviar comentários sobre…

Documentação do Kubernetes Engine