Tailscale client metrics service discovery to Prometheus
I couldn’t summarize this in a title (even with an LLM’s help):
I wanted to:
- Run a Tailscale service discovery agent
- On a Tailscale node outside of the Kubernetes cluster
- Using Podman Quadlet
- Accessing it from the Kubernetes Cluster using the Tailscale’s egress proxy
- Accessing the proxy with a
kube-prometheusScrapeConfig - In order that Prometheus would scrape the container for Tailscale client metrics
Long-winded? Yes but I had an underlying need in running the Tailscale Service Discoovery remotely and this configuration helped me achieve that.
Prometheus MCP Server
I was unable to find a Model Context Protocol (MCP) server implementation for Prometheus. I had a quiet weekend and so I’ve been writing one: prometheus-mcp-server.
I used the code from the MCP for gRPC Health Checking protocol that I wrote about previously as a guide.
I wrote a series of stdin and HTTP tests to have confidence that the service is working correctly but I had no MCP host.
I discovered that Visual Studio Code through its GitHub Copilot extension functions has a preview to use MCP servers i.e. function as an MCP host and access MCP servers.
MCP for gRPC Health Checking protocol
Model Context Protocol (MCP) is “all the rage” these days.
I stumbled upon protoc-gen-go-mcp and think it’s an elegant application of two technologies: programmatically generating an MCP server from a gRPC protobuf.
I’m considering building an MCP server for Ackal but, thought I’d start with something simple: gRPC Health Checking protocol.
I was surprised to learn as I was doing this that there’s a new List (Add List method to gRPC Health service #143) added to grpc.health.v1.Health. My (Ackal) healthcheck server does not yet implement it (see later).
Configuring Envoy to proxy Google Cloud Run v2
I’m building an emulator for Cloud Run. As I considered the solution, I assumed (more later) that I could implement Google’s gRPC interface for Cloud Run and use Envoy to proxy HTTP/REST requests to the gRPC service using Envoy’s gRPC-JSON transcoder.
Google calls this process Transcoding HTTP/JSON to gRPC which I think it a better description.
Google’s Cloud Run v2 (v1 is no longer published to the googleapis repo) service.proto includes the following Services definition for CreateService:
Migrating Prometheus Exporters to Kubernetes
I have built Prometheus Exporters for multiple cloud platforms to track resources deployed across clouds:
- Prometheus Exporter for Azure
- Prometheus Exporter for crt.sh
- Prometheus Exporter for Fly.io
- Prometheus Exporter for GoatCounter
- Prometheus Exporter for Google Analytics
- Prometheus Exporter for Google Cloud
- Prometheus Exporter for Koyeb
- Prometheus Exporter for Linode
- Prometheus Exporter for PorkBun
- Prometheus Exporter for updown.io
- Prometheus Exporter for Vultr
Additionally, I’ve written two status service exporters:
These exporters are all derived from an exemplar DigitalOcean Exporter written by metalmatze for which I maintain a fork.
Prometheus Exporter for USGS Water Data service
I’m a little obsessed with creating Prometheus Exporters:
- Prometheus Exporter for Azure
- Prometheus Exporter for crt.sh
- Prometheus Exporter for Fly.io
- Prometheus Exporter for GoatCounter
- Prometheus Exporter for Google Cloud
- Prometheus Exporter for Koyeb
- Prometheus Exporter for Linode
- Prometheus Exporter for PorkBun
- Prometheus Exporter for updown.io
- Prometheus Exporter for Vultr
All of these were written to scratch an itch.
In the case of the cloud platform exporters (Azure, Fly, Google, Linode, Vultr etc.), it’s an overriding anxiety that I’ll leave resources deployed on these platforms and, running an exporter that ships alerts to Pushover and Gmail, provides me a support mechanism for me.
gRPC Firestore `Listen` in Rust
Obsessing on gRPC Firestore Listen somewhat but it’s also a good learning opportunity for me to write stuff in Rust. This doesn’t work against Google’s public endpoint (possibly for the same reason that gRPCurl doesn’t work either) but this does work against the Go server described in the other post.
I’m also documenting here because I always encounter challenges using TLS with Rust (and this documents 2 working ways to do this with gRPC) as well as references two interesting (rust) examples that use Google services.
gRPC Firestore `Listen`
A question on Stack overflow Firestore gRPC Listen does not send deletions piqued by interest but created a second problem for me: I’m unable to get its Listen method to work using gRPCurl.
For what follows, you will need:
- a Google Project with Firestore enabled and a database (default:
(default)) containing a Collection (e.g.Dogs) with at least one Document (e.g.freddie) googleapiscloned locally in order to access Protobufs
Summary
| client | server | R | See |
|---|---|---|---|
gRPCurl |
firestore.googleapis.com:443 |
✅ | link |
| Go client | firestore.googleapis.com:443 |
✅ | link |
gRPCurl |
Go server | ✅ | link |
| Go client | Go server | ✅ | link |
I subsequently tried this using Postman and it also works (✅).
gRPC-Web w/ FauxRPC and Rust
After recently discovering FauxRPC, I was sufficiently impressed that I decided to use it to test Ackal’s gRPC services using rust.
FauxRPC provides multi-protocol support and so, after successfully implementing the faux gRPC client tests, I was compelled to try gRPC-Web too. For no immediate benefit other than, it’s there, it’s free and it’s interesting. As an aside, the faux REST client tests worked without issue using Reqwest.
Unfortunately, my optimism hit a wall with gRPC-Web and what follows is a summary of my unresolved issue.
FauxRPC using gRPCurl, Golang and rust
Read FauxRPC + Testcontainers on Hacker News and was intrigued. I spent a little more time “evaluating” this than I’d planned because I’m forcing myself to use rust as much as possible and my ignorance (see below) caused me some challenges.
The technology is interesting and works well. The experience helped me explore Testcontainers too which I’d heard about but not explored until this week.
For my future self:
| What | What? |
|---|---|
| FauxRPC | A general-purpose tool (built using Buf’s Connect) that includes registry and stub (gRPC) services that can be (programmatically) configured (using a Protobuf descriptor) and stubs (example method responses) to help test gRPC implementations. |
| Testcontainers | Write code (e.g. rust) to create and interact (test)services (running in [Docker] containers). |
| Connect | (More than a) gRPC implementation used by FauxRPC |
| gRPCurl | A command-line gRPC tool. |
I started following along with FauxRPC’s Testcontainers example but, being unfamiliar with Connect, I wasn’t familiar with its Eliza service. The service is available on demo.connectrpc.com:443 and is described using eliza.proto as part of examples-go. Had I realized this sooner, I would have used this example rather than the Health Checking protocol.