Ejecutar el proxy de servicios extensible localmente o en otra plataforma

En esta página se explica cómo configurar y ejecutar una instancia de Extensible Service Proxy (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 esté en Google Cloud.

Puedes ejecutar ESP en un ordenador o una máquina virtual (VM) Linux o macOS. No se admite Microsoft Windows. Puedes implementar tu aplicación y ESP en el mismo host o en hosts diferentes. Alojar una instancia local de ESP te permite:

  • Prueba ESP antes de implementarlo en una plataforma de producción.
  • Verifica que los ajustes de seguridad estén configurados y funcionen correctamente, y que las métricas y los registros aparezcan en la página Endpoints > Services (Endpoints > Servicios) como se espera.

Requisitos previos

Para empezar, en esta página se presupone lo siguiente:

  • Has instalado Docker si vas a desplegar el contenedor de ESP de forma local o en una VM. Consulta Instalar Docker para obtener más información.

  • Has implementado una API de forma local o en un host al que puede acceder el host en el que ejecutas ESP.

  • Has configurado Cloud Endpoints y desplegado la configuración para crear un servicio gestionado para tu API.

Si necesitas una API para hacer pruebas con ESP, puedes configurar e implementar el código de ejemplo de la sección Opcional: usar una API de ejemplo. Si ya has configurado e implementado tu API, ve a la sección Crear una cuenta de servicio.

Opcional: Usar una API de ejemplo

En esta sección se explica cómo configurar y desplegar la versión de Python del ejemplo de getting-started para Endpoints de forma local. Sigue los pasos de esta sección solo si no tienes una API para probar con ESP.

La muestra de Cloud Endpoints getting-started está disponible en otros idiomas. Consulta la página Ejemplos para ver la ubicación en GitHub del ejemplo de getting-started en el idioma que prefieras. Sigue las instrucciones del archivo README.md de ejemplo para ejecutarlo de forma local y, a continuación, las instrucciones de esta sección para configurar Endpoints y desplegar la configuración de Endpoints.

Obtener el software necesario

Si aún no has configurado un entorno de desarrollo de Python, consulta la guía Configurar un entorno de desarrollo de Python. Asegúrate de que tienes instalados los siguientes elementos:

Obtén el código de ejemplo

  1. Clona el repositorio de aplicaciones de muestra en la máquina local:

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

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

Configurar Endpoints

  1. En el directorio de código de ejemplo, 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, sustituye YOUR-PROJECT-ID por el ID de tu proyecto Google Cloud .

  3. Guarda el archivo openapi.yaml.

Desplegar la configuración de Endpoints

Para desplegar la configuración de Endpoints, usa el comando gcloud endpoints services deploy. Este comando usa Gestión de servicios para crear un servicio gestionado.

  1. Actualiza gcloud CLI:

    gcloud components update
  2. Comprueba que la CLI de gcloud (gcloud) tenga autorización para acceder a tus datos y servicios en Google Cloud:

    gcloud auth login

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

  3. Define el proyecto predeterminado con el ID de tu proyecto:

    gcloud config set project YOUR-PROJECT-ID
    

    Sustituye YOUR-PROJECT-ID por el ID del proyectoGoogle Cloud que has especificado en el archivo openapi.yaml.

  4. Despliega la configuración:

    gcloud endpoints services deploy openapi.yaml

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

Mientras crea y configura el servicio, Gestión de servicios muestra información en la terminal. Puedes ignorar las advertencias sobre las rutas del archivo openapi.yaml que no requieren una clave de API. Si se completa correctamente, se mostrará una línea similar a la siguiente con 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.

Iniciar el servidor local

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

    virtualenv env
    source env/bin/activate
    pip install -r requirements.txt
  2. Inicia el servidor:

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

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

    La API devuelve el mensaje que le envías y responde con lo siguiente:

    {
    "message": "hello world"
    }

Creando una cuenta de servicio

Para gestionar tu API, tanto ESP como ESPv2 requieren los servicios de Infraestructura de servicios. Para llamar a estos servicios, ESP y ESPv2 deben usar tokens de acceso. Cuando despliegas ESP o ESPv2 en entornos como GKE o Compute Engine, ESP y ESPv2 obtienen tokens de acceso a través del servicio de metadatos. Google Cloud Google Cloud

Cuando implementas ESP o ESPv2 en un entorno que no es deGoogle Cloud , como tu ordenador local, un clúster de Kubernetes local u otro proveedor de servicios en la nube, debes proporcionar un archivo JSON de cuenta de servicio que contenga una clave privada. ESP y ESPv2 usan la cuenta de servicio para generar tokens de acceso con los que llamar a los servicios que necesita para gestionar tu API.

Puedes usar la Google Cloud consola o la CLI de Google Cloud para crear la cuenta de servicio y el archivo de clave privada:

Consola

  1. En la Google Cloud consola, 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 se creó la API y haz clic en Abrir.
  4. Haz clic en + Crear cuenta de servicio.
  5. En el campo Nombre de cuenta de servicio, introduce el nombre de tu cuenta de servicio.
  6. Haz clic en Crear.
  7. Haz clic en Continuar.
  8. Haz clic en Listo.
  9. Haz clic en la dirección de correo de la cuenta de servicio que acabas de crear.
  10. Haz clic en Teclas.
  11. Haz clic en Añadir clave y, a continuación, en Crear clave.
  12. Haz clic en Crear. Se descargará un archivo de clave JSON en tu ordenador.

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

  13. Haz clic en Cerrar.

gcloud

  1. Introduce lo siguiente para mostrar los IDs de tus Google Cloud proyectos:

    gcloud projects list
  2. Sustituye PROJECT_ID en el siguiente comando para definir el proyecto predeterminado como aquel en el que se encuentra tu API:

    gcloud config set project PROJECT_ID
  3. Asegúrate de que la CLI de Google Cloud (gcloud) tenga autorización para acceder a tus datos y servicios en Google Cloud:

    gcloud auth login

    Si tienes más de una cuenta, asegúrate de elegir la cuenta que esté en el Google Cloud proyecto en el que se encuentra la API. Si ejecutas gcloud auth list, la cuenta que hayas seleccionado se mostrará como la cuenta activa del proyecto.

  4. Para crear una cuenta de servicio, ejecuta el siguiente comando y sustituye SERVICE_ACCOUNT_NAME y My Service Account por el nombre y el nombre visible que quieras usar:

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

    El comando asigna una dirección de correo a la cuenta de servicio con el siguiente formato:

    SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

    Esta dirección de correo es obligatoria en los comandos posteriores.

  5. Crea un archivo de clave de cuenta de servicio:

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

Añade los roles de gestión de identidades y accesos necesarios:

En esta sección se describen los recursos de gestión de identidades y accesos que usan ESP y ESPv2, así como los roles de gestión de identidades y accesos que necesita la cuenta de servicio asociada para acceder a estos recursos.

Configuración del servicio de endpoint

ESP y ESPv2 llaman a Service Control, que usa la configuración del servicio de endpoint. La configuración del servicio de endpoint es un recurso de gestión de identidades y accesos, y ESP y ESPv2 necesitan el rol Service Controller para acceder a él.

El rol de IAM está en la configuración del servicio de endpoint, no en el proyecto. Un proyecto puede tener varias configuraciones de servicio de endpoint.

Usa el siguiente comando de gcloud para añadir el rol a la cuenta de servicio adjunta en la configuración del servicio de endpoint.

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

Donde
* SERVICE_NAME es el nombre del servicio de endpoint
* SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com es la cuenta de servicio asociada.

Cloud Trace

ESP y ESPv2 llaman al servicio Cloud Trace para exportar el seguimiento a un proyecto. Este proyecto se llama proyecto de seguimiento. En ESP, el proyecto de seguimiento y el proyecto propietario de la configuración del servicio de endpoint son el mismo. En ESPv2, el proyecto de seguimiento se puede especificar mediante la marca --tracing_project_id y, de forma predeterminada, se usa el proyecto de implementación.

ESP y ESPv2 requieren el rol Agente de Cloud Trace para habilitar Cloud Trace.

Usa el siguiente comando de gcloud para añadir el rol a la cuenta de servicio adjunta:

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

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

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

Ejecutar ESP en un contenedor

En esta sección se describe cómo implementar el contenedor de ESP. El procedimiento que sigas dependerá de dónde implementes el contenedor de ESP:

En los siguientes ejemplos, la opción --http_port del ESP 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.

Ejecutar ESP en un contenedor Docker localmente o en otra plataforma

  1. Cambia el nombre del archivo JSON que contiene la clave privada de la cuenta de servicio a service-account-creds.json y cópialo en $HOME/Downloads/ si se ha descargado en otro directorio. De esta forma, la ruta completa coincide con el valor de --service_account_key en el siguiente comando docker run.

  2. En el siguiente comando docker run, sustituye 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 de Docker --net="host" no funciona en macOS. En su lugar, debes asignar puertos explícitamente del host al contenedor. Para ello, sustituye --net="host" por --publish 8082:8082. También debes sustituir localhost por el nombre de DNS especial exclusivo para macOS docker.for.mac.localhost. Consulta 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 que se usan en los comandos anteriores. Para obtener información sobre las opciones de ESP que se usan en el ejemplo, consulta Opciones de inicio del ESP.

Opción Descripción
--detach Esta opción de Docker inicia el contenedor en modo independiente, por lo que se ejecuta en segundo plano.
--name="esp" Esta opción de Docker proporciona un nombre de fácil acceso para el contenedor. Por ejemplo, para ver los registros del contenedor, puedes ejecutar docker logs esp
--net="host" Esta opción de Docker indica que el contenedor Docker usa la misma configuración de red que el equipo host, lo que le permite hacer llamadas a localhost en el equipo host. Esta opción no funciona para ejecutar ESP de forma local en macOS.
--publish=8082:8082 En macOS, si quieres ejecutar ESP de forma local, usa esta opción de Docker en lugar de --net="host" para asignar puertos explícitamente del host al contenedor.
--volume=
$HOME/Downloads:/esp
Esta opción de Docker asigna tu directorio $HOME/Downloads local al directorio /esp del contenedor. Esta asignación se usa con la opción --service_account_key ESP.

Ejecutar ESP en un contenedor en un clúster de Kubernetes

En esta sección se describe cómo desplegar ESP en un clúster de Kubernetes que no esté en Google Cloud.

Para que Endpoints gestione tu API, despliega el contenedor de ESP en el mismo pod de Kubernetes que el contenedor de tu API. El conjunto de pods que ejecutan 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 al puerto del proxy.

  1. Cambia el nombre del archivo JSON que contiene la clave privada de la cuenta de servicio a service-account-creds.json y cópialo en $HOME/Downloads/ si se ha descargado en otro directorio. De esta forma, la ruta completa coincide con el comando del paso siguiente.

  2. Ejecuta el siguiente comando para crear un secreto de Kubernetes y montar el secreto como un volumen de Kubernetes.

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

    Si la operación se realiza correctamente, se muestra el siguiente mensaje: secret "service-account-creds" created

  3. En tu archivo de configuración de Kubernetes, añade lo siguiente y sustituye 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 información sobre las opciones de ESP que se usan en el ejemplo, consulta Opciones de inicio del ESP.

  4. Despliega ESP en Kubernetes. Sustituye YOUR_CONFIGURATION_FILE por el nombre de tu archivo de configuración de Kubernetes.

    kubectl apply -f YOUR_CONFIGURATION_FILE

Enviar solicitudes

Para confirmar que el archivo de cuenta de servicio es correcto y que los puertos se han asignado correctamente, envía algunas solicitudes a tu API y asegúrate de que se envían a través de ESP. Para ver los registros de ESP, ejecuta el siguiente comando:

sudo docker logs esp

En los siguientes ejemplos se envían solicitudes a la API de ejemplo. Si no usas la API de ejemplo, te recomendamos que hagas pruebas similares.

Ha configurado el contenedor ESP para que reciba solicitudes en el puerto 8082. Si envía una solicitud directamente al servidor en http://localhost:8080, la solicitud omite el ESP. Por ejemplo:

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 un ESP y no envías una clave de API, el ESP rechaza la solicitud. Por ejemplo:

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, sigue estos pasos:

  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, a continuación, selecciona Clave de API.

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

    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

    Si ves una respuesta correcta:

    {
      "message": "hello world"
    }

Eliminar los recursos utilizados

Cierra y elimina el contenedor Docker esp con la herramienta docker:

    sudo docker stop esp
    sudo docker rm esp
Si quieres limpiar la configuración del servicio implementado, consulta la sección sobre cómo eliminar una API y sus instancias.

Siguientes pasos