Ejecuta el proxy de servicio extensible localmente o en otra plataforma

En esta página, se explica cómo configurar y ejecutar una instancia del proxy de servicio extensible (ESP) en una máquina local, en otro proveedor de servicios en la nube, como Amazon Web Services (AWS), o en un clúster de Kubernetes que no se ejecuta en Google Cloud.

Puedes ejecutar el ESP en una computadora Linux o macOS o en una máquina virtual (VM). Microsoft Windows no es compatible. Puedes implementar tu aplicación y el ESP en el mismo host o en hosts diferentes. Alojar una instancia local del ESP te permite hacer lo siguiente:

  • Probar el ESP antes de implementarlo en una plataforma de producción
  • Verificar que la configuración de seguridad esté configurada y funcione de forma correcta, además de que las métricas y los registros aparezcan en la página Endpoints > Servicios como se esperaba.

Requisitos previos

Como punto de partida, esta página supone lo siguiente:

Si necesitas una API para realizar pruebas con el ESP, puedes implementar y configurar el código de muestra en la sección Opcional: usa una API de muestra. Si ya implementaste y configuraste tu API, ve a Crea una cuenta de servicio.

Opcional: usa una API de muestra

En esta sección, aprenderás a configurar y, también, implementar la versión de Python de la muestra getting-started para Endpoints de forma local. Sigue los pasos de esta sección solo si no tienes una API para realizar pruebas con el ESP.

La muestra getting-started de Cloud Endpoints está disponible en otros lenguajes. Consulta la página Muestras si quieres conocer la ubicación del GitHub para la muestra getting-started en el lenguaje que prefieras. Sigue las instrucciones del archivo README.md de la muestra para realizar la ejecución local. Luego, sigue las instrucciones de esta sección a fin de configurar Endpoints y, además, implementar la configuración.

Cómo obtener el software necesario

Si aún no configuraste un entorno de desarrollo de Python, consulta Cómo configurar un entorno de desarrollo de Python para obtener asesoramiento. Asegúrate de tener instalado lo siguiente:

Obtenga el código de muestra

  1. Clona el repositorio de la aplicación de muestra en tu máquina local con el siguiente comando:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples
    
  2. Ve al directorio que contiene el código de muestra:

    cd python-docs-samples/endpoints/getting-started
    

Configura Endpoints

  1. En el directorio de código de muestra, abre el archivo de configuración openapi.yaml.

    swagger: "2.0"
    info:
      description: "A simple Google Cloud Endpoints API example."
      title: "Endpoints Example"
      version: "1.0.0"
    host: "echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog"
  2. En el campo host, reemplaza YOUR-PROJECT-ID con tu propio ID del proyecto de Google Cloud.

  3. Guarda el archivo openapi.yaml.

Implemente la configuración de Endpoints

Para implementar la configuración de Endpoints, usa el comando gcloud endpoints services deploy. Este comando usa Service Management a fin de crear un servicio administrado.

  1. Actualiza la CLI de gcloud:

    gcloud components update
    
  2. Asegúrate de que la CLI de gcloud (gcloud) esté autorizada para acceder a tus datos y servicios en Google Cloud:

    gcloud auth login
    

    En la pestaña del navegador nueva que se abre, selecciona una cuenta.

  3. Configura el proyecto predeterminado como el ID del proyecto de la manera siguiente:

    gcloud config set project YOUR-PROJECT-ID
    

    Reemplaza YOUR-PROJECT-ID con el ID del proyecto de Google Cloud que especificaste en el archivo openapi.yaml.

  4. Implementa tu configuración:

    gcloud endpoints services deploy openapi.yaml
    

Service Management usa el texto que especificaste en el campo host del archivo openapi.yaml para crear un servicio de Endpoints nuevo con el nombre echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog (si no existe) y, luego, configura el servicio según tu archivo de configuración de OpenAPI.

A medida que se crea y configura el servicio, Service Management envía información a la terminal. Puedes ignorar las advertencias sin problemas sobre las rutas de acceso en el archivo openapi.yaml que no requieren una clave de API. Cuando completas la tarea con éxito, una línea similar a la siguiente muestra el ID de configuración del servicio y el nombre del servicio entre corchetes:

Service Configuration [2017-02-13r0] uploaded for service [echo-api.endpoints.example-project-12345.cloud.goog]

En el ejemplo anterior, 2017-02-13r0 es el ID de configuración del servicio y echo-api.endpoints.example-project-12345.cloud.goog es el nombre del servicio.

Inicia tu servidor local

  1. Crea un virtualenv, actívalo y, luego, instala las dependencias de la aplicación.

    virtualenv env
    source env/bin/activate
    pip install -r requirements.txt
    
  2. Inicia el servidor. Para esto, sigue los pasos siguientes:

    python main.py
    
  3. Abre otra ventana de la terminal y usa curl para enviar una solicitud de la manera siguiente:

    curl --request POST \
        --header "content-type:application/json" \
        --data '{"message":"hello world"}' \
        http://localhost:8080/echo
    

    La API repite el mensaje que le enviaste y responde lo siguiente:

    {
      "message": "hello world"
    }
    

Crea una cuenta de servicio

A fin de proporcionar administración a tu API, el ESP y el ESPv2 requieren los servicios de la infraestructura del servicio. Para llamar a estos servicios, el ESP y el ESPv2 deben usar tokens de acceso. Cuando implementas el ESP o el ESPv2 Beta en entornos de Google Cloud, como GKE o Compute Engine, el ESP y el ESPv2 obtienen tokens de acceso mediante el servicio de metadatos de Google Cloud.

Cuando implementas el ESP o el ESPv2 en un entorno que no es de Google Cloud, como tu computadora de escritorio local, un clúster de Kubernetes local o cualquier otro proveedor de servicios en la nube, tienes que proporcionar un archivo JSON de la cuenta de servicio que contenga una clave privada. El ESP y el ESPv2 usan la cuenta de servicio con el objetivo de generar tokens de acceso que le permitan llamar a los servicios que necesitan para administrar tu API.

Puedes usar Cloud Console o la CLI de Google Cloud para crear la cuenta de servicio y el archivo de claves privadas:

Console

  1. En Cloud Console, abre la página Cuentas de servicio.

    Ir a la página Cuentas de servicio

  2. Haz clic en Seleccionar un proyecto.
  3. Selecciona el proyecto en el que creaste tu API y haz clic en Abrir.
  4. Haz clic en + Crear cuenta de servicio.
  5. En el campo Nombre de la cuenta de servicio, ingresa el nombre de tu cuenta de servicio.
  6. Haga clic en Crear.
  7. Haz clic en Continuar.
  8. Haga clic en Listo.
  9. Haz clic en la dirección de correo electrónico de la cuenta de servicio recién creada.
  10. Haga clic en Claves.
  11. Haz clic en Agregar clave, luego haz clic en Crear clave nueva.
  12. Haga clic en Crear. Se descargará un archivo de claves JSON en tu computadora.

    Asegúrate de almacenar el archivo de claves de forma segura, ya que se puede usar para autenticarse como tu cuenta de servicio. Puedes mover y cambiar el nombre de este archivo como desees.

  13. Haga clic en Cerrar.

gcloud

  1. Ingresa lo siguiente para mostrar los ID de tus proyectos de Google Cloud:

    gcloud projects list
  2. Reemplaza PROJECT_ID en el comando siguiente para definir el proyecto predeterminado donde está tu API:

    gcloud config set project PROJECT_ID

  3. Asegúrate de que la CLI de Google Cloud (gcloud) esté autorizada para acceder a los datos y servicios en Google Cloud:

    gcloud auth login

    Si tienes más de una cuenta, asegúrate de elegir la que está en el proyecto de Google Cloud en el que se encuentra la API. Si ejecutas gcloud auth list, la cuenta que seleccionaste se muestra como la cuenta activa para el proyecto.

  4. Para crear una cuenta de servicio, ejecuta el comando siguiente y reemplaza SERVICE_ACCOUNT_NAME y My Service Account por el nombre y el nombre comercial que quieres usar:

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME 
    --display-name "My Service Account"

    Con el comando, se asigna una dirección de correo electrónico para la cuenta de servicio en este formato:

    SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

    Esta dirección de correo electrónico se requiere en los comandos posteriores.

  5. Crea un archivo de claves de la cuenta de servicio:

    gcloud iam service-accounts keys create ~/service-account-creds.json \
          --iam-account SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

Agrega las funciones requeridas de IAM:

En esta sección, se describen los recursos de IAM que usan el ESP y el ESPv2 y las funciones de IAM necesarias para que la cuenta de servicio conectada acceda a estos recursos.

Configuración del servicio de extremo

El ESP y el ESPv2 llaman al Control de servicios que usa la configuración del servicio de extremo. La configuración del servicio de extremo es un recurso de IAM, por lo que el ESP y el ESPv2 necesitan la función de Controlador de servicio para acceder a él.

La función de IAM se encuentra en la configuración del servicio de extremo, no en el proyecto. Un proyecto puede tener múltiples opciones de configuración de servicio de extremo.

Usa el siguiente comando de gcloud a fin de agregar la función a la cuenta de servicio conectada para la configuración del servicio de extremo.

gcloud endpoints services add-iam-policy-binding SERVICE_NAME \
                --member serviceAccount:SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com \
                --role roles/servicemanagement.serviceController

En el ejemplo anterior
* SERVICE_NAME es el nombre del servicio de extremo
* SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com es la cuenta de servicio conectada

Cloud Trace

El ESP y el ESPv2 llaman al servicio de Cloud Trace para exportar Trace a un proyecto. Este proyecto se llama proyecto de seguimiento. En el ESP, el proyecto de seguimiento y el proyecto que posee la configuración del servicio de extremo son los mismos. En el ESPv2, el proyecto de seguimiento se puede especificar con la marca --tracing_project_id y, de forma predeterminada, se establece el proyecto de implementación.

El ESP y el ESPv2 requieren la función Agente de Cloud Trace para habilitar Cloud Trace.

Usa el siguiente comando de gcloud para agregar la función a la cuenta de servicio conectada:

gcloud projects add-iam-policy-binding TRACING_PROJECT_ID \
                --member serviceAccount:SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com \
                --role roles/cloudtrace.agent

En el ejemplo anterior
* TRACING_PROJECT_ID es el ID del proyecto de seguimiento
* SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com es la cuenta de servicio conectada Para obtener más información, consulta ¿Qué son las funciones y los permisos?

Consulta gcloud iam service-accounts para obtener más información sobre los comandos.

Ejecuta ESP en un contenedor

En esta sección, se describe cómo implementar el contenedor del ESP. El procedimiento que uses dependerá de las opciones siguientes para implementar el contenedor del ESP:

En los siguientes ejemplos, la opción del ESP --http_port solo funciona si el servicio gRPC tiene configurada la transcodificación HTTP/JSON. Para obtener más información, consulta Transcodificar HTTP/JSON a gRPC.

Ejecuta el ESP en un contenedor de Docker de forma local o en otra plataforma

  1. Renombra el archivo JSON que contiene la clave privada para la cuenta de servicio a service-account-creds.json y cópialo en $HOME/Downloads/, si se descargó en un directorio diferente. De esta forma, el nombre completo de la ruta de acceso coincide con el valor para --service_account_key en el comando de docker run siguiente.

  2. En el comando siguiente de docker run, reemplaza YOUR_SERVICE_NAME por el nombre de tu servicio.

Linux

sudo docker run \
    --detach \
    --name="esp" \
    --net="host" \
    --volume=$HOME/Downloads:/esp \
    --publish=8082 \
    gcr.io/endpoints-release/endpoints-runtime:1 \
    --service=YOUR_SERVICE_NAME \
    --rollout_strategy=managed \
    --http_port=8082 \
    --http2_port=8083 \
    --backend=grpc://localhost:8080 \
    --service_account_key=/esp/service-account-creds.json
  

mac OS

La opción --net="host" de Docker no funciona en macOS. En su lugar, debes realizar una asignación de puertos explícita del host al contenedor, en la que reemplaces --net="host" por --publish 8082:8082. También debes reemplazar localhost por el nombre de DNS especial docker.for.mac.localhost solo para macOS. Consulta la sección sobre casos prácticos y soluciones alternativas en la documentación de Docker para obtener más información.

sudo docker run \
    --detach \
    --name="esp" \
    --publish=8082:8082 \
    --volume=$HOME/Downloads:/esp \
    gcr.io/endpoints-release/endpoints-runtime:1 \
    --service=YOUR_SERVICE_NAME \
    --rollout_strategy=managed \
    --http_port=8082 \
    --http2_port=8083 \
    --backend=grpc://docker.for.mac.localhost:8080 \
    --service_account_key=/esp/service-account-creds.json
  

Otra plataforma

sudo docker run \
    --detach \
    --name="esp" \
    --net="host" \
    --volume=$HOME/Downloads:/esp \
    --publish=8082 \
    gcr.io/endpoints-release/endpoints-runtime:1 \
    --service=YOUR_SERVICE_NAME \
    --rollout_strategy=managed \
    --http_port=8082 \
    --http2_port=8083 \
    --backend=grpc://IP_Address:PORT \
    --service_account_key=/esp/service-account-creds.json
  

En la siguiente tabla, se describen las opciones de Docker utilizadas en los comandos anteriores. Para obtener más información sobre las opciones del ESP que se usaron en el ejemplo, consulta Opciones de inicio del ESP.

Opción Descripción
--detach Esta opción de Docker inicia al contenedor en modo separado, así que se ejecuta en segundo plano.
--name="esp" Esta opción de Docker brinda al contenedor un nombre de fácil acceso. Por ejemplo, para ver los registros del contenedor, puedes ejecutar docker logs esp.
--net="host" Esta opción indica que el contenedor de Docker usa la misma configuración de red que la máquina host, lo que le permite realizar llamadas al host local en la máquina host. Esta opción no funciona para ejecutar el ESP de manera local en macOS.
--publish=8082:8082 En macOS, cuando quieras ejecutar el ESP de manera local, usa esta opción de Docker, en lugar de --net="host", para hacer una asignación explícita de puertos desde el host hasta el contenedor.
--volume=
$HOME/Downloads:/esp
Con esta opción de Docker, se asigna tu directorio local $HOME/Downloads al directorio /esp en el contenedor. La opción del ESP --service_account_key usa esta asignación.

Ejecuta el ESP en un contenedor dentro de un clúster de Kubernetes

En esta sección, se describe cómo implementar el ESP en un clúster de Kubernetes que no está en Google Cloud.

Para que Endpoints administre tu API, debes implementar el contenedor del ESP en el mismo pod de Kubernetes que el del contenedor de tu API. El conjunto de pods que ejecutan el ESP y tu API se agrupan en un servicio de Kubernetes mediante un selector de etiquetas, como app: my-api. El servicio de Kubernetes especifica la política de acceso para balancear la carga de las solicitudes del cliente en el puerto del proxy.

  1. Renombra el archivo JSON que contiene la clave privada para la cuenta de servicio a service-account-creds.json y cópialo en $HOME/Downloads/, si se descargó en un directorio diferente. De este modo, el nombre completo de la ruta de acceso al directorio coincidirá con el comando en el paso siguiente.

  2. Ejecuta el comando siguiente para crear un secreto de Kubernetes y actívalo como un volumen de Kubernetes.

    kubectl create secret generic service-account-creds \
    --from-file=$HOME/Downloads/service-account-creds.json
    

    Cuando el proceso finaliza con éxito, se muestra el mensaje siguiente: secret "service-account-creds" created

  3. En tu archivo de configuración de Kubernetes, agrega lo siguiente y reemplaza YOUR_APP_NAME por el nombre de tu API y YOUR_SERVICE_NAME por el nombre de tu servicio.

    spec:
    replicas: 1
    template:
      metadata:
        labels:
          app: "YOUR_APP_NAME"
      spec:
        volumes:
          - name: service-account-creds
            secret:
              secretName: service-account-creds
              containers:
          - name: esp
            image: gcr.io/endpoints-release/endpoints-runtime:1
            args: [
              "--http_port=8082",
              "--http2_port=8083",
              "--backend=grpc://127.0.0.1:8081",
              "--service=YOUR_SERVICE_NAME",
              "--rollout_strategy=managed",
              "--service_account_key=/etc/nginx/creds/service-account-creds.json"
            ]
            ports:
              - containerPort: 8080
            volumeMounts:
              - mountPath: /etc/nginx/creds
                name: service-account-creds
                readOnly: true
    

    Para obtener más información sobre las opciones del ESP que se usaron en el ejemplo, consulta Opciones de inicio del ESP.

  4. Implementa el ESP en Kubernetes. Reemplaza YOUR_CONFIGURATION_FILE por el nombre de tu archivo de configuración de Kubernetes.

    kubectl apply -f YOUR_CONFIGURATION_FILE
    

Envía solicitudes

Para confirmar que el archivo de la cuenta de servicio sea correcto y que los puertos estén bien asignados, envía algunas solicitudes a tu API y asegúrate de que pasen por el ESP. Puedes ver los registros del ESP si ejecutas el comando siguiente:

sudo docker logs esp

Los ejemplos siguientes envían solicitudes a la API de muestra. Si no usas la API de muestra, te recomendamos que ejecutes pruebas similares.

Configuraste el contenedor del ESP para recibir solicitudes en el puerto 8082. Si envías una solicitud directo al servidor en http://localhost:8080, la solicitud omite el ESP. Por ejemplo:

Solicitud:

    curl --request POST \
      --header "content-type:application/json" \
      --data '{"message":"hello world"}' \
      http://localhost:8080/echo

Respuesta:

    {
      "message": "hello world"
    }

Cuando envías una solicitud a http://localhost:8082, que pasa por el ESP, y no envías una clave de API, el ESP rechaza la solicitud. Por ejemplo:

Solicitud:

    curl --request POST \
      --header "content-type:application/json" \
      --data '{"message":"hello world"}' \
      http://localhost:8082/echo

Respuesta:

    {
     "code": 16,
     "message": "Method doesn't allow unregistered callers (callers without
      established identity). Please use API Key or other form of API consumer
      identity to call this API.",
     "details": [
      {
       "@type": "type.googleapis.com/google.rpc.DebugInfo",
       "stackEntries": [],
       "detail": "service_control"
      }
     ]
    }

Para probar la API con una clave de API, haz lo siguiente:

  1. Crea una clave de API en la página Credenciales de API.

    Ir a la página Credenciales

  2. Haz clic en Crear credenciales y, luego, selecciona Clave de API.

  3. Copia la clave y pégala en la declaración de variable de entorno siguiente:

    export KEY=AIza...
    
  4. Envía una solicitud con la clave:

    curl --request POST \
      --header "content-type:application/json" \
      --data '{"message":"hello world"}' \
      http://localhost:8082/echo?key=$KEY
    

    Verás la respuesta siguiente que indica que el proceso se completó de forma correcta:

    {
      "message": "hello world"
    }
    

Realiza una limpieza

Apaga y quita el contenedor de Docker esp con la herramienta de docker de la manera siguiente:

sudo docker stop esp
sudo docker rm esp

Si quieres limpiar la configuración del servicio implementado, consulta Borra una API y las instancias relacionadas.

¿Qué sigue?