Update documentation with websockets.

This commit is contained in:
2023-10-24 00:22:28 +01:00
parent 4255f87efd
commit 8fc5782d29
2 changed files with 170 additions and 3 deletions
+49 -3
View File
@@ -6,10 +6,10 @@ This project is in active use by [telegram-bot.app](https://telegram-bot.app), a
![Example of monitoring dashboard](static/monitoring-at-glance.png?raw=true)
You can find the example of the Kubernetes manifest in the [example deployment](static/kubernetes-deployment.yaml) file.
- [graphql monitoring proxy](#graphql-monitoring-proxy)
- [Why this project exists](#why-this-project-exists)
- [How to deploy](#how-to-deploy)
- [Note on websocket support](#note-on-websocket-support)
- [Endpoints](#endpoints)
- [Features](#features)
- [Configuration](#configuration)
@@ -26,11 +26,55 @@ You can find the example of the Kubernetes manifest in the [example deployment](
- [Healthcheck](#healthcheck)
- [Monitoring endpoint](#monitoring-endpoint)
### Why this project exists
I wanted to monitor the queries and responses of our graphql endpoint. Still, we didn't want to pay the price of the graphql server itself ( and I will not point fingers at a particular well-known project), as monitoring and basic security features should be a standard, free functionality.
### How to deploy
You can find the example of the Kubernetes manifest in the [example standalone deployment](static/kubernetes-deployment.yaml) or [example combined deployment](static/kubernetes-single-deployment.yaml) files. Observed advantage of multideployment is that it allows the network requests to travel via localhost, without leaving the deployment which brings quite significant network performance boost.
#### Note on websocket support
Proxy in its current version 0.5.30 does not support websockets. If you need to proxy the websocket requests - you can use following trick whilst setting up the proxy. As I'm a big fan of Traefik - there's an example which works with the mentioned above combined deployment.
<details>
<summary>Click to show working Traefik Ingress Route example.</summary>
```yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: hasura-internal
spec:
entryPoints:
- websecure
routes:
# NON WEBSOCKET CONNECTION
- kind: Rule
match: Host(`example.com`) && PathPrefix(`/v1/graphql`) && !HeadersRegexp(`Upgrade`, `websocket`)
services:
- name: hasura-w-proxy-internal
port: proxy
middlewares:
- name: compression
namespace: default
# WEBSOCKET CONNECTION
- kind: Rule
match: Host(`example.com`) && PathPrefix(`/v1/graphql`) && HeadersRegexp(`Upgrade`, `websocket`)
services:
- name: hasura-w-proxy-internal
port: hasura
middlewares:
- name: compression
namespace: default
```
In this case, both proxy and websockets will be available under the `/v1/graphql` path, and the websocket connection will be proxied directly to the hasura service, bypassing the proxy.
</details>
### Endpoints
* `:8080/*` - the graphql passthrough endpoint
@@ -89,6 +133,8 @@ You can then start using the cache by setting the `ENABLE_GLOBAL_CACHE` environm
In the case of the `@cached` you can add additional parameters to the directive which will set the cache for specific queries to the provided time.
For example, `query MyCachedQuery @cached(ttl: 90) ....` will set the cache for the query to 90 seconds.
Since version `0.5.30` the cache is gzipped in the memory, which should optimise the memory usage quite significantly.
### Security
#### Role-based rate limiting
+121
View File
@@ -0,0 +1,121 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: hasura-w-proxy-internal
labels:
app: hasura-w-proxy-internal
type: support
spec:
replicas: 2
selector:
matchLabels:
app: hasura-w-proxy-internal
type: support
template:
metadata:
labels:
app: hasura-w-proxy-internal
type: support
spec:
securityContext:
runAsUser: 65534 # nobody
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/worker
operator: Exists
containers:
- name: hasura
image: hasura/graphql-engine:v2.33.1-ce
ports:
- name: hasura-internal
containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
resources:
limits:
cpu: "1"
memory: "640Mi"
requests:
cpu: "0.75"
memory: "512Mi"
env:
- name: HASURA_GRAPHQL_DATABASE_URL
value: postgres://postgres:xxx@yyy:5432/postgres
- name: HASURA_GRAPHQL_ENABLE_CONSOLE
value: "true"
- name: HASURA_GRAPHQL_DEV_MODE
value: "true"
- name: HASURA_GRAPHQL_ENABLE_TELEMETRY
value: "false"
- name: HASURA_GRAPHQL_EXPERIMENTAL_FEATURES
value: "inherited_roles"
- name: HASURA_GRAPHQL_PG_CONNECTIONS
value: "20"
- name: HASURA_GRAPHQL_LOG_LEVEL
value: "error"
- name: graphql-proxy
image: ghcr.io/lukaszraczylo/graphql-monitoring-proxy:latest
imagePullPolicy: Always
resources:
limits:
cpu: "1"
memory: "640Mi"
requests:
cpu: "0.75"
memory: "128Mi"
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 5
ports:
- name: web
containerPort: 8181
- name: monitoring
containerPort: 9393
env:
- name: PORT_GRAPHQL
value: "8181"
- name: MONITORING_PORT
value: "9393"
- name: HOST_GRAPHQL
value: http://localhost:8080/
- name: ENABLE_GLOBAL_CACHE
value: "true"
- name: CACHE_TTL
value: "10"
---
apiVersion: v1
kind: Service
metadata:
name: hasura-w-proxy-internal
labels:
app: hasura-w-proxy-internal
type: support
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9393"
prometheus.io/path: "/metrics"
spec:
ports:
- name: hasura
port: 8080
targetPort: 8080
- name: proxy
port: 8181
targetPort: 8181
- name: monitoring
port: 9393
targetPort: 9393
selector:
app: hasura-w-proxy-internal
type: support
type: ClusterIP