Cómo configurar la dirección de servicio


En esta página, se muestra cómo configurar la dirección de servicio para tus Pods.

Para comprender cómo funciona la dirección de servicio, consulta Cómo funciona la dirección de servicio.

Requisitos

  • GKE versión 1.30 o posterior.

Limitaciones

  • Un ServiceFunctionChain puede tener como máximo una función de servicio.
  • Recomendamos un máximo de 100 nodos más 10 pares ServiceFunctionChain y TrafficSelector.
  • La dirección de servicio de GKE solo está disponible con nodos que ejecutan la imagen de nodo de Container-Optimized OS.
  • La dirección de servicio de GKE solo admite direcciones IP de salida y destino.
  • La dirección de servicio no controla los conflictos que surgen cuando se aplican varios selectores de tráfico con longitudes de prefijo idénticas al mismo sujeto. Para evitar conflictos, diseña de forma proactiva tus selectores de tráfico con rangos de direcciones IP que no se superpongan y con criterios de selección definidos con claridad.

Implementa la dirección de servicio

La dirección de servicio de GKE te permite personalizar y controlar el flujo de tráfico de red dentro de un clúster. En esta sección, se muestra cómo implementar la dirección de servicio con un ejemplo de puerta de enlace web.

Considera un caso de uso en el que deseas crear una puerta de enlace web que proteja el tráfico desde los dispositivos cliente del usuario final hacia Internet. Un terminador de VPN dirige el tráfico a la puerta de enlace administrada mediante un túnel seguro. El tráfico del usuario final se redirecciona al firewall y, luego, al proxy. El proxy realiza la traducción de la dirección de red de origen (SNAT) en el tráfico, enmascara la dirección de origen original y la envía a Internet.

Para implementar la dirección de servicio de GKE, haz lo siguiente:

  1. Crea una VPC con MTU de 8,896.
  2. Crea un clúster de GKE.
  3. Crea los Pods y el Service de la función de servicio.
  4. Crea el ServiceFunctionChain:
  5. Crea el recurso TrafficSelector que hace referencia a ServiceFunctionChain.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.

Prepara una VPC

Preparar una VPC. La dirección de servicio usa el encapsulamiento para redireccionar el tráfico a las funciones de servicio adecuadas. El encapsulamiento implica agregar encabezados adicionales a cada paquete, lo que aumenta el tamaño del paquete. La dirección de servicio no requiere una configuración especial en las VPC. Cuando preparas la VPC, te recomendamos que, cuando decidas el tamaño de la MTU, tengas en cuenta la sobrecarga de encapsulamiento. Para obtener más información, consulta Red de VPC con una MTU especificada.

El siguiente comando establece el tamaño de mtu en tu VPC:

gcloud compute networks create VPC_NETWORK_NAME --mtu=8896

Reemplaza VPC_NETWORK_NAME por el nombre de la red de VPC que contiene la subred.

Cree un clúster de GKE

A fin de habilitar las capacidades avanzadas de enrutamiento de red y administración de direcciones IP necesarias para implementar la dirección de servicio en GKE, crea un clúster de GKE habilitado para GKE Dataplane V2 de la siguiente manera:

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

Reemplaza lo siguiente:

  • CLUSTER_NAME: el nombre del clúster
  • VPC_NAME: Es el nombre de la VPC con la que deseas asociar el clúster.
  • RELEASE_CHANNEL: Es el nombre del canal de versiones.
  • VERSION: la versión de GKE, que debe ser 1.30 o posterior. También puedes usar la marca --release-channel para seleccionar un canal de versiones. El canal de versiones debe tener una versión predeterminada 1.30 o posterior.

Crea Pods ServiceFunction

Para establecer tu cadena de servicio, implementa el Pod del terminador de VPN y los Pods de la función de servicio necesarios dentro de tu clúster. Los Pods encapsulan las aplicaciones en contenedores que realizan las funciones de red.

El Pod del terminador de VPN suele ser la primera función de servicio de la cadena, que finaliza el tráfico que ingresa al clúster a través de la VPN. Luego, dirige las otras funciones del servicio, como firewalls y balanceo de cargas, para su posterior procesamiento antes de llegar al destino final.

El siguiente archivo de configuración de ejemplo define los siguientes tres componentes esenciales para la administración del tráfico de red dentro de un clúster:

  • Pod de VPN: Establece un extremo de red privada virtual (VPN) dentro de tu clúster, que permite una comunicación segura y encriptada entre el clúster y las redes externas.
  • Implementación de firewall: Implementa varias réplicas de un Pod de firewall, que proporcionan seguridad y balanceo de cargas.
  • DaemonSet del proxy: Implementa un Pod del proxy en cada nodo del clúster, lo que garantiza que el tráfico de red se pueda procesar de forma local antes de reenviarlo a otros servicios, como un firewall.

Guarda el siguiente manifiesto de muestra 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

Aplica el manifiesto

kubectl apply -f service_function.yaml

Crear ServiceFunctionChains

Para definir una secuencia de funciones de red para que el tráfico recorra, crea una canalización en la que cada función, como firewall, proxy y balanceador de cargas, realice su tarea específica antes de pasar el tráfico a la siguiente.

Guarda el siguiente manifiesto de muestra 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

Aplica el manifiesto

kubectl apply -f ServiceFunctionChain.yaml

Las funciones de servicio se definen intercaladas en ServiceFunctionChain mediante el campo serviceFunctions. Una función de servicio es un selector de extremos.

Crea el recurso TrafficSelector

A fin de definir dónde y qué tráfico se selecciona para la dirección de servicio, crea el recurso TrafficSelector que haga referencia a ServiceFunctionChains a fin de aplicarlo al tráfico elegido.

Guarda el siguiente manifiesto de muestra 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

Aplica el manifiesto

kubectl apply -f TrafficSelector.yaml

Solución de problemas de la dirección de servicio

En esta sección, se muestra cómo resolver problemas relacionados con la dirección de servicio de GKE.

El tráfico de red no fluye

Puedes realizar las siguientes acciones para depurar el problema:

Paso 1: Verifica que servicePathId esté configurado en ServiceFunctionChain

Verifica que servicePathId esté configurado en ServiceFunctionChain. A cada objeto ServiceFunctionChain se le asigna un servicePathId único, como se muestra en el siguiente ejemplo:

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

Paso 2: Verifica que se cree un servicio de Kubernetes por cada función de servicio

Se crea un servicio ClusterIP para cada función de servicio de forma automática. Puedes ver la lista de servicios mediante kubectl:

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

Paso 3: Verifica que, para cada función de servicio, se cree una entrada de mapa bpf en cada nodo a fin de almacenar la dirección IP del servicio

Para cada función de servicio, se crea una entrada de mapa bpf en cada nodo a fin de almacenar la dirección IP del Service.

Obtén el nombre del Pod anetd:

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

Registra el nombre del Pod, similar a anetd.

Ejecuta el siguiente comando:

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

Reemplaza ANETD-POD-NAME con el nombre del pod anetd.

El resultado es similar a este:

PATH     SERVICE FUNCTION ADDRESS
(1, 1)   10.4.10.124

Paso 4: Verifica que las entradas del mapa bpf se creen en el mapa sfcselect

En un nodo, si hay Pods seleccionados por un TrafficSelector, se crean entradas de mapa bpf en el mapa sfcselect. En el siguiente ejemplo, se muestra que el tráfico de TCP/UDP desde cualquier puerto del extremo (Pod) 3783 a la dirección IP de destino 10.0.2.12 se dirige a un ServiceFunctionChain.

Ejecuta el siguiente comando:

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

Reemplaza ANETD-POD-NAME por el nombre real del Pod anetd en tu clúster.

El resultado es similar a este:

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)

Paso 5: Usa tcpdump en el puerto 7081 para capturar y analizar el tráfico de red

La dirección de servicio realiza el encapsulamiento de Geneve en el puerto UDP 7081. Puedes usar tcpdump en los nodos relevantes para analizar el flujo de tráfico y detectar dónde podría estar ocurriendo el problema.

¿Qué sigue?