En este tutorial se muestra cómo crear un servicio Knative serving personalizado que transforma un parámetro de entrada de descripción de un gráfico en un diagrama con el formato de imagen PNG
. Usa Graphviz, que se instala como paquete del sistema en el entorno de contenedor del servicio.
Graphviz se usa a través de utilidades de línea de comandos para atender solicitudes.
Obtener el código de ejemplo
Para obtener el código de muestra que vas a usar, sigue estos pasos:
Clona el repositorio de aplicaciones de muestra en la máquina local:
Node.js
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Python
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Go
git clone https://github.com/GoogleCloudPlatform/golang-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Java
git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
También puedes descargar el ejemplo como un archivo ZIP y extraerlo.
Cambia al directorio que contiene el código de ejemplo de servicio de Knative:
Node.js
cd nodejs-docs-samples/run/system-package/
Python
cd python-docs-samples/run/system-package/
Go
cd golang-samples/run/system_package/
Java
cd java-docs-samples/run/system-package/
Visualizar la arquitectura
La arquitectura básica es la siguiente:

El usuario envía una solicitud HTTP al servicio de Knative Serving, que ejecuta una utilidad de Graphviz para transformar la solicitud en una imagen. Esa imagen se envía al usuario como respuesta HTTP.
Información sobre el código
Definir la configuración del entorno con Dockerfile
Tu Dockerfile
es específico del idioma y del entorno operativo base, como Ubuntu, que usará tu servicio.
Este servicio requiere uno o varios paquetes de sistema adicionales que no están disponibles de forma predeterminada.
Abre el
Dockerfile
en un editor.Busca un extracto de
Dockerfile
RUN
. Esta instrucción permite ejecutar comandos de shell arbitrarios para modificar el entorno. Si elDockerfile
tiene varias fases, identificadas por varias instruccionesFROM
, se encontrará en la última fase.Los paquetes específicos necesarios y el mecanismo para instalarlos varían en función del sistema operativo declarado en el contenedor.
Para obtener instrucciones sobre tu sistema operativo o imagen base, haz clic en la pestaña correspondiente.
Debian/Ubuntu Alpine Alpine requiere un segundo paquete para admitir fuentes.Para determinar el sistema operativo de tu imagen de contenedor, consulta el nombre en la instrucción
FROM
o en un archivo README asociado a tu imagen base. Por ejemplo, si amplías desdenode
, puedes encontrar documentación y el elemento principalDockerfile
en Docker Hub.Para probar la personalización, compila la imagen con
docker build
localmente o con Cloud Build.
Gestionar solicitudes entrantes
El servicio de ejemplo usa parámetros de la solicitud HTTP entrante para invocar una llamada al sistema que ejecuta el comando de utilidad dot
adecuado.
En el controlador HTTP que se muestra a continuación, se extrae un parámetro de entrada de descripción de gráfico de la variable de cadena de consulta dot
.
Las descripciones de los gráficos pueden incluir caracteres que deben codificarse como URL para usarse en una cadena de consulta.
Node.js
Python
Go
Java
Deberás diferenciar entre los errores de servidor internos y las entradas de usuario no válidas. Este servicio de ejemplo devuelve un error de servidor interno para todos los errores de línea de comandos de punto, a menos que el mensaje de error contenga la cadena syntax
, que indica un problema de entrada del usuario.
Generar un diagrama
La lógica principal de la generación de diagramas usa la herramienta de línea de comandos dot para procesar el parámetro de entrada de descripción del gráfico y convertirlo en un diagrama en formato de imagen PNG.
Node.js
Python
Go
Java
Diseñar un servicio seguro
Las vulnerabilidades de la herramienta dot
son vulnerabilidades potenciales del servicio web. Para mitigar este problema, puedes usar versiones actualizadas del paquete graphviz
recompilando la imagen del contenedor de forma periódica.
Si amplías la muestra actual para que acepte datos introducidos por el usuario como parámetros de línea de comandos, debes protegerte contra los ataques de inyección de comandos. Estas son algunas de las formas de evitar los ataques de inyección:
- Asignar entradas a un diccionario de parámetros admitidos
- Validar que las entradas coincidan con un intervalo de valores seguros conocidos, quizás mediante expresiones regulares
- Escapar las entradas para asegurarse de que no se evalúe la sintaxis de shell
Envío del código
Para enviar tu código, compila con Cloud Build, sube el contenido a Container Registry y despliégalo en Knative Serving:
Ejecuta el siguiente comando para compilar el contenedor y publicarlo en Container Registry.
Node.js
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
graphviz
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Container Registry y se puede volver a usar si quieres.
Python
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
graphviz
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Container Registry y se puede volver a usar si quieres.
Go
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz
Donde PROJECT_ID es el ID de tu proyecto Google Cloud y
graphviz
es el nombre que quieres dar a tu servicio.Si la operación se realiza correctamente, verás un mensaje de ÉXITO que contiene el ID, la hora de creación y el nombre de la imagen. La imagen se almacena en Container Registry y se puede volver a usar si quieres.
Java
En este ejemplo se usa Jib para crear imágenes de Docker con herramientas comunes de Java. Jib optimiza las compilaciones de contenedores sin necesidad de usar un Dockerfile ni de tener Docker instalado. Más información sobre cómo crear contenedores Java con JibCon el Dockerfile, configura y compila una imagen base con los paquetes del sistema instalados para anular la imagen base predeterminada de Jib:
gcloud builds submit --tag gcr.io/PROJECT_ID/graphviz-base
Donde PROJECT_ID es el ID de tu proyecto Google Cloud .
Crea el contenedor final con Jib y publícalo en Container Registry:
mvn compile jib:build \ -Dimage=gcr.io/PROJECT_ID/graphviz \ -Djib.from.image=gcr.io/PROJECT_ID/graphviz-base
Donde PROJECT_ID es el ID de tu proyecto Google Cloud .
Implementa con el siguiente comando:
gcloud run deploy graphviz-web --create-if-missing --image gcr.io/PROJECT_ID/graphviz
Donde PROJECT_ID es el ID de tu proyecto, Google Cloud es el nombre del contenedor de arriba y
graphviz
es el nombre del servicio.graphviz-web
Espera a que se complete el despliegue, que puede tardar aproximadamente medio minuto.
Si quieres implementar una actualización de código en el servicio, repite los pasos anteriores. Cada despliegue en un servicio crea una nueva revisión y empieza a servir tráfico automáticamente cuando está listo.
Pruébalo
Prueba tu servicio enviando solicitudes HTTP POST
con descripciones de sintaxis DOT en la carga útil de la solicitud.
Envía una solicitud HTTP a tu servicio.
Puedes insertar el diagrama en una página web:
-
Para obtener la IP externa del balanceador de carga, ejecuta el siguiente comando:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
Sustituye ASM-INGRESS-NAMESPACE por el espacio de nombres en el que se encuentra tu entrada de Cloud Service Mesh. Especifica
istio-system
si has instalado Cloud Service Mesh con su configuración predeterminada.La salida resultante tiene un aspecto similar al siguiente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingressgateway LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
donde el valor EXTERNAL-IP es la dirección IP externa del balanceador de carga.
Ejecuta un comando curl con esta dirección
EXTERNAL-IP
en la URL. No incluyas el protocolo (por ejemplo,http://
) enSERVICE_DOMAIN
.curl -G -H "Host: SERVICE_DOMAIN" http://EXTERNAL-IP/diagram.png \ --data-urlencode "dot=digraph Run { rankdir=LR Code -> Build -> Deploy -> Run }" \ > diagram.png
-
Abre el archivo
diagram.png
resultante en cualquier aplicación que admita archivosPNG
, como Chrome.Debería tener este aspecto:
Fuente: Descripción de DoT
Puedes consultar una pequeña colección de descripciones de diagramas prediseñadas.
- Copia el contenido del archivo
.dot
seleccionado. Pégalo en un comando
curl
:curl -G -H "Host: SERVICE_DOMAIN" http://EXTERNAL-IP/diagram.png \ --data-urlencode "dot=digraph Run { rankdir=LR Code -> Build -> Deploy -> Run }" \ > diagram.png