Configure o encaminhamento de serviços


Esta página mostra como configurar o encaminhamento de serviços para os seus pods.

Para compreender como funciona o encaminhamento de serviços, consulte o artigo Como funciona o encaminhamento de serviços.

Requisitos

  • Versão 1.30 ou posterior do GKE.

Limitações

  • Um ServiceFunctionChain pode ter, no máximo, uma função de serviço.
  • Recomendamos um máximo de 100 nós, mais 10 pares ServiceFunctionChain e TrafficSelector.
  • A gestão de serviços do GKE só está disponível com nós que executam a imagem do nó do SO otimizado para contentores.
  • A gestão de serviços do GKE só suporta endereços IP de saída e de destino.
  • O encaminhamento de serviços não processa conflitos que surgem quando são aplicados vários seletores de tráfego com comprimentos de prefixos idênticos ao mesmo assunto. Para evitar conflitos, crie proativamente os seletores de tráfego com intervalos de endereços IP não sobrepostos e critérios de seleção claramente definidos.

Implemente o encaminhamento de serviços

A gestão de serviços do GKE permite-lhe personalizar e controlar o fluxo de tráfego de rede num cluster. Esta secção demonstra como implementar o encaminhamento de serviços através de um exemplo de gateway Web.

Considere um exemplo de utilização em que quer criar um gateway Web que proteja o tráfego de dispositivos cliente de utilizadores finais para a Internet. Um terminador de VPN extrai tráfego para o gateway gerido através de um canal seguro. O tráfego do utilizador final é redirecionado para a firewall e, em seguida, para o proxy. O proxy executa a tradução de endereços de rede de origem (SNAT) no tráfego, oculta o endereço de origem original e envia-o para a Internet.

Para implementar o encaminhamento de serviços do GKE, faça o seguinte:

  1. Crie uma VPC com MTU de 8896.
  2. Crie um cluster do GKE.
  3. Crie os pods de função de serviço e o serviço.
  4. Crie o ServiceFunctionChain.
  5. Crie o recurso TrafficSelector que faz referência ao ServiceFunctionChain.

Antes de começar

Antes de começar, certifique-se de que realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ative a API Google Kubernetes Engine
  • Se quiser usar a CLI gcloud para esta tarefa, instale-a e, em seguida, inicialize-a. Se instalou anteriormente a CLI gcloud, execute gcloud components update para obter a versão mais recente.

Prepare uma VPC

Prepare uma VPC. A Direção de serviços usa a encapsulagem para redirecionar o tráfego para as funções de serviço adequadas. A encapsulagem envolve a adição de cabeçalhos adicionais a cada pacote, o que aumenta o tamanho do pacote. O encaminhamento de serviços não requer uma configuração especial nas VPCs. Ao preparar a VPC, recomendamos que, ao decidir o tamanho da MTU, tenha em conta a sobrecarga de encapsulamento. Para mais informações, consulte o artigo Rede VPC com um MTU especificado.

O comando seguinte define o tamanho da MTU na sua VPC:

gcloud compute networks create VPC_NETWORK_NAME --mtu=8896

Substitua VPC_NETWORK_NAME pelo nome da rede VPC que contém a sub-rede.

Crie um cluster do GKE

Para ativar as capacidades avançadas de encaminhamento de rede e gestão de endereços IP necessárias para implementar a gestão de serviços no GKE, crie um cluster do GKE com o plano de dados V2 do GKE ativado da seguinte forma:

gcloud container clusters create CLUSTER_NAME \
    --network VPC_NAME \
    --release-channel RELEASE_CHANNEL \
    --cluster-version CLUSTER_VERSION \
    --enable-dataplane-v2 \
    --enable-ip-alias

Substitua o seguinte:

  • CLUSTER_NAME: o nome do cluster.
  • VPC_NAME: o nome da VPC com a qual quer associar o cluster.
  • RELEASE_CHANNEL: o nome do canal de lançamento.
  • VERSION: a versão do GKE, que tem de ser 1.30 ou posterior. Também pode usar a flag --release-channel para selecionar um canal de lançamento. O canal de lançamento tem de ter uma versão predefinida de 1.30 ou posterior.

Crie ServiceFunction pods

Para estabelecer a sua cadeia de serviços, implemente o pod terminador de VPN e os pods de função de serviço necessários no seu cluster. Os pods encapsulam as aplicações contentorizadas que executam as funções de rede.

O pod terminador de VPN é frequentemente a primeira função de serviço na cadeia, que termina o tráfego que entra no cluster através da VPN. Em seguida, direciona as outras funções de serviço, como firewalls e balanceamento de carga, para processamento adicional antes de chegar ao destino final.

O ficheiro de configuração de exemplo seguinte define os três componentes seguintes essenciais para a gestão do tráfego de rede num cluster:

  • VPN Pod: estabelece um ponto final de rede privada virtual (VPN) no seu cluster, o que permite uma comunicação segura e encriptada entre o seu cluster e redes externas.
  • Implementação de firewall: implementa várias réplicas de um pod de firewall, que oferecem segurança e equilíbrio de carga.
  • Proxy DaemonSet: implementa um pod de proxy em todos os nós do cluster, garantindo que o tráfego de rede pode ser processado localmente antes de ser encaminhado para outros serviços, como a firewall.

Guarde o seguinte manifesto de exemplo como service_function.yaml:

apiVersion: v1
kind: Pod
  name: vpn
  namespace: vpn
  labels:
    app: vpn
spec:
  containers:
  -   name: vpn
    image: openvpn
    ports:
    -   containerPort: 51820
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: firewall
  namespace: firewall
spec:
  replicas: 3
  selector:
    matchLabels:
      app: firewall
  template:
    metadata:
      labels:
        app: firewall
    spec:
      containers:
      -   name: firewall
        image: firewall
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: proxy
  namespace: proxy
spec:
  selector:
    matchLabels:
      app: proxy
  template:
    metadata:
      labels:
        app: proxy
    spec:
      containers:
      -   name: proxy
        image: proxy

Aplique o manifesto:

kubectl apply -f service_function.yaml

Criar ServiceFunctionChains

Para definir uma sequência de funções de rede para o tráfego atravessar, crie um pipeline onde cada função, como firewall, proxy e equilibrador de carga, executa a sua tarefa específica antes de passar o tráfego para a seguinte.

Guarde o seguinte manifesto de exemplo como ServiceFunctionChain.yaml:

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  sessionAffinity:
    clientIpNoDestination:
      timeoutSeconds: 3600 # 1hr
  serviceFunctions:
  -   name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewall
---
apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: proxy
spec:
  sessionAffinity:
    clientIpNoDestination: {}
  serviceFunctions:
  -   name: proxy
    namespace: proxy
    podSelector:
      matchLabels:
        app: proxy

Aplique o manifesto:

kubectl apply -f ServiceFunctionChain.yaml

As funções de serviço são definidas inline no elemento ServiceFunctionChain através do campo serviceFunctions. Uma função de serviço é um seletor de pontos finais.

Crie o recurso TrafficSelector

Para definir onde e que tráfego é selecionado para o encaminhamento de serviços, crie o recurso TrafficSelector que faz referência ao ServiceFunctionChains a aplicar ao tráfego escolhido.

Guarde o seguinte manifesto de exemplo como TrafficSelector.yaml:

apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: vpn-to-firewall
spec:
  serviceFunctionChain: firewall
  subject:
    pods:
      namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: vpn
      podSelector:
        matchLabels:
          app: vpn
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP
---
apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: firewall-to-proxy
spec:
  serviceFunctionChain: proxy
  subject:
    pods:
      namespaceSelector:
        kubernetes.io/metadata.name: firewall
      podSelector:
        app: firewall
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP

Aplique o manifesto:

kubectl apply -f TrafficSelector.yaml

Resolva problemas de encaminhamento de serviços

Esta secção mostra-lhe como resolver problemas relacionados com o encaminhamento de serviços do GKE.

O tráfego de rede não está a fluir

Pode realizar as seguintes ações para depurar o problema:

Passo 1: verifique se a opção servicePathId está definida em ServiceFunctionChain

Verifique se servicePathId está definido em ServiceFunctionChain. A cada objeto ServiceFunctionChain é atribuído um servicePathId exclusivo, conforme mostrado no exemplo seguinte:

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  serviceFunctions:
  - name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewal
status:
  servicePathId: 1

Passo 2: verifique se é criado um serviço Kubernetes por função de serviço

É criado automaticamente um serviço ClusterIP para cada função de serviço. Pode ver a lista de serviços através de kubectl:

kubectl get svc -A -l networking.gke.io/managed-by=service-steering-controller.gke.io

Passo 3: verifique se, para cada função de serviço, é criada uma entrada de mapa bpf em cada nó para armazenar o endereço IP do serviço

Para cada função de serviço, é criada uma entrada de mapa bpf em cada nó para armazenar o endereço IP do serviço.

Obtenha o nome do anetd Pod:

kubectl get pods -n kube-system -o wide -l k8s-app=cilium

Registe o nome do Pod semelhante a anetd.

Execute o seguinte comando:

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcpath list

Substitua ANETD-POD-NAME pelo nome do Pod anetd.

O resultado é semelhante ao seguinte:

PATH     SERVICE FUNCTION ADDRESS
(1, 1)   10.4.10.124

Passo 4: verifique se as entradas do mapa BPF são criadas no mapa sfcselect

Num nó, se existirem pods selecionados por um TrafficSelector, são criadas entradas de mapa bpf no mapa sfcselect. O exemplo seguinte mostra que o tráfego TCP/UDP de qualquer porta do ponto final (Pod) 3783 para o endereço IP de destino 10.0.2.12 é encaminhado para um ServiceFunctionChain.

Execute o seguinte comando:

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcselect list

Substitua ANETD-POD-NAME pelo nome real do pod anetd no seu cluster.

O resultado é semelhante ao seguinte:

SELECTOR                            PATH
3783, egress, 0/TCP, 10.0.2.12/32   /32 (1, 1)
3783, egress, 0/UDP, 10.0.2.12/32   /32 (1, 1)

Passo 5: use o tcpdump na porta 7081 para capturar e analisar o tráfego de rede

A gestão de serviços faz a encapsulagem Geneve na porta UDP 7081. Pode usar o tcpdump nos nós relevantes para analisar o fluxo de tráfego e identificar onde o problema pode estar a ocorrer.

O que se segue?