Configurar o direcionamento de serviço


Nesta página, mostramos como configurar o direcionamento de serviço para seus pods.

Para entender como o direcionamento de serviço funciona, consulte este artigo.

Requisitos

  • GKE versão 1.30 ou posterior

Limitações

  • Um ServiceFunctionChain pode ter no máximo uma função de serviço.
  • Recomendamos no máximo 100 nós mais 10 ServiceFunctionChain e TrafficSelector.
  • O direcionamento de serviço do GKE só está disponível em nós que executam a imagem de nó do Container-Optimized OS.
  • O direcionamento de serviço do GKE oferece suporte apenas a IPs de saída e de endereços IP de destino.
  • O direcionamento de serviço não lida com conflitos que surgem quando vários seletores de tráfego com comprimentos de prefixo idênticos são aplicados ao mesmo assunto. Para evitar conflitos, crie seus seletores de tráfego com intervalos de endereços IP não sobrepostos e critérios de seleção claramente definidos.

Implementar o direcionamento de serviço

O direcionamento de serviço do GKE permite personalizar e controlar o fluxo do tráfego de rede em um cluster. Esta seção demonstra como implementar o direcionamento de serviço usando um exemplo de gateway da Web.

Considere um caso de uso em que você quer criar um gateway da Web que proteja o tráfego de dispositivos clientes do usuário final para a Internet. Um terminador de VPN direciona tráfego ao gateway gerenciado usando um túnel seguro. O tráfego do usuário final é redirecionado ao firewall e, em seguida, ao proxy. O proxy realiza a conversão de endereços de rede de origem (SNAT) no tráfego, mascara o endereço de origem e o envia para a Internet.

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

  1. Crie uma VPC com MTU 8896.
  2. Crie um cluster do GKE.
  3. Crie os pods e o serviço da função de serviço.
  4. Crie o ServiceFunctionChain.
  5. Crie o recurso TrafficSelector que referencia a ServiceFunctionChain.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ativar a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a Google Cloud CLI para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando gcloud components update.

Preços

Os seguintes recursos do Otimizador de funções de rede (NFO) são compatíveis apenas com clusters que estão em projetos ativados com o GKE Enterprise:

Para entender as cobranças que se aplicam à ativação da edição Enterprise do Google Kubernetes Engine (GKE), consulte Preços do GKE Enterprise.

Preparar uma VPC

Prepare uma VPC. O direcionamento de serviço usa encapsulamento para redirecionar o tráfego para as funções de serviço apropriadas. O encapsulamento envolve a adição de cabeçalhos extras a cada pacote, o que aumenta o tamanho do pacote. O direcionamento de serviço não requer configurações especiais em VPCs. Ao preparar a VPC, recomendamos que, ao decidir o tamanho da MTU, você considere a sobrecarga de encapsulamento. Para mais informações, consulte Rede VPC com uma MTU especificada.

O comando a seguir 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 os recursos avançados de roteamento de rede e gerenciamento de endereços IP necessários para implementar o direcionamento de serviço no GKE, crie um cluster do GKE ativado pelo GKE Dataplane V2 da seguinte maneira:

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

Substitua:

  • CLUSTER_NAME: o nome do cluster.
  • VPC_NAME: o nome da VPC a que você quer associar o cluster.
  • RELEASE_CHANNEL: o nome do canal de lançamento.
  • VERSION: a versão do GKE, que precisa ser 1.30 ou posterior. Também é possível usar a sinalização --release-channel para selecionar um canal de lançamento. O canal de lançamento precisa ter a versão padrão 1.30 ou posterior.
.

Criar ServiceFunction pods

Para estabelecer sua cadeia de serviços, implante o pod do terminador de VPN e os pods de função de serviço necessários no cluster. Os pods encapsulam os aplicativos conteinerizados que executam suas funções de rede.

O pod do terminador de VPN geralmente é a primeira função de serviço na cadeia, que encerra o tráfego que entra no cluster pela VPN. Em seguida, ele direciona outras funções de serviço, como firewalls e balanceamento de carga, processamento adicional antes de chegar ao destino final.

O arquivo de configuração de exemplo abaixo define os três componentes a seguir, essenciais para o gerenciamento de tráfego de rede em um cluster:

  • Pod de VPN: estabelece um endpoint de rede privada virtual (VPN) no cluster, o que permite uma comunicação segura e criptografada entre os cluster e redes externas.
  • Implantação de firewall: implanta várias réplicas de um pod de firewall, que para fornecer segurança e balanceamento de carga.
  • DaemonSet de proxy: implanta um pod de proxy em cada nó do cluster, garantindo que o tráfego de rede possa ser processado localmente antes de ser encaminhado para outros serviços, como firewall.

Salve o seguinte manifesto de amostra 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 a serem transferidas pelo tráfego, crie um pipeline, em que cada função, como firewall, proxy e balanceador de carga, executam a tarefa específica antes de passar o tráfego para a próxima.

Salve o seguinte manifesto de amostra 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 in-line no ServiceFunctionChain usando o campo serviceFunctions. Uma função de serviço é um seletor de endpoint.

Criar o recurso TrafficSelector

Para definir onde e qual tráfego é selecionado para o direcionamento de serviço, crie o recurso TrafficSelector que referencia a ServiceFunctionChains a ser aplicada ao tráfego escolhido.

Salve o seguinte manifesto de amostra 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

Resolver problemas do direcionamento de serviço

Nesta seção, mostramos como resolver problemas relacionados ao direcionamento de serviço do GKE.

O tráfego de rede não está fluindo

Realize as seguintes ações para depurar o problema:

Etapa 1: verificar se servicePathId está definido em ServiceFunctionChain

Verifique se servicePathId está definido em ServiceFunctionChain. Todo objeto ServiceFunctionChain recebe um servicePathId exclusivo, conforme mostrado no exemplo a seguir:

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

Etapa 2: verificar se um serviço do Kubernetes foi criado por função de serviço

Um serviço ClusterIP é criado automaticamente para cada função de serviço. Você pode visualizar a lista de serviços usando kubectl:

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

Etapa 3: verificar se uma entrada de mapa bpf foi criada em cada nó para armazenar o endereço IP de cada função de serviço

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

Consiga o nome do pod anetd:

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

Registre o nome do pod semelhante a anetd.

Execute este 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 será assim:

PATH     SERVICE FUNCTION ADDRESS
(1, 1)   10.4.10.124

Etapa 4: verificar se as entradas do mapa bpf foram criadas no mapa sfcselect

Em um nó, se houver pods selecionados por um TrafficSelector, entradas de mapa bpf são criadas no mapa sfcselect. O exemplo a seguir mostra que o tráfego TCP/UDP de qualquer porta do endpoint (Pod) 3783 para o endereço IP de destino 10.0.2.12 é direcionado ServiceFunctionChain:

Execute este comando:

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

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

O resultado será assim:

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)

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

O direcionamento de serviço encapsulamento Geneve na porta UDP 7081. Você pode usar o tcpdump nos nós relevantes para analisar o fluxo de tráfego e identificar onde o problema pode estar ocorrendo.

A seguir