grpc_health_proxy is a webserver proxy for gRPC Health Checking Protocol.
This utility starts up an HTTP/S server which responds back after making an RPC
call to an upstream server’s gRPC healthcheck endpoint (/grpc.health.v1.Health/Check).
If the healthcheck passes, response back to the original http client will be 200. If the
gRPC HealthCheck failed, a 503 is returned. If the service is not registered, a 404 is returned
Basically, this is an http proxy for the grpc healthcheck protocol.
client--->http-->grpc_heatlh_proxy-->gRPC HealthCheck-->gRPC Server
This utility uses similar flags, cancellation and timing snippets for the grpc call from grpc-health-probe. Use that tool as a specific Liveness and Readiness Probes for Kubernetes. This utility can be used in the same cli mode but also as a generic HTTP interface (eg, as httpHealthCheck probe). For more information on the CLI mode without http listener, see the section at the end.
This is not an official Google project and is unsupported by Google
You can find the source here
EXAMPLES
Check the status of an upstream gRPC serviceName echo.EchoService listening on :50051:
For any mode, enable verbose logging with glog levels: append --logtostderr=1 -v 10
grpc_health_probe will listen on :8080 for HTTP healthcheck requests at path /healthz.
$ grpc_health_proxy --http-listen-addr localhost:8080 \
--http-listen-path /healthz \
--grpcaddr localhost:50051 \
--service-name echo.EchoServer --logtostderr=1 -v 1
curl http://localhost:8080/healthz
(also via &serverName=echo.EchoServer query parameter)
grpc_health_probe will listen on :8080 for HTTPS healthcheck requests at path /healthz.
HTTPS listener will use keypairs [http_crt.pem, http_key.pem]
$ grpc_health_proxy --http-listen-addr localhost:8080 \
--http-listen-path /heatlhz \
--grpcaddr localhost:50051 \
--https-listen-cert http_crt.pem \
--https-listen-key http_key.pem \
--grpc-service-name echo.EchoServer --logtostderr=1 -v 1
curl \
--cacert CA_crt.pem \
--resolve 'http.domain.com:8080:127.0.0.1' \
https://host.domain.com:8080/healthz
grpc_health_probe will listen on :8080 for HTTPS with mTLS healthcheck requests at path /healthz.
HTTPS listener will use keypairs [http_crt.pem, http_crt.pem] and verify client certificates issued by CA_crt.pem
$ grpc_health_proxy --http-listen-addr localhost:8080 \
--http-listen-path /healthz \
--grpcaddr localhost:50051 \
--https-listen-cert http_crt.pem \
--https-listen-key http_key.pem \
--grpc-service-name echo.EchoServer \
--https-listen-verify \
--https-listen-ca=CA_crt.pem --logtostderr=1 -v 1
curl \
--cacert CA_crt.pem \
--key client_key.pem \
--cert client_crt.pem \
--resolve 'http.domain.com:8080:127.0.0.1'
https://host.domain.com:8080/healthz
Options to establish mTLS from the http proxy to gRPC server
client->http->grpc_health_proxy->mTLS->gRPC serverin the example below, grpc_client_crt.pem and grpc_client_key.pem are the TLS client credentials to present to the gRPC server
$ grpc_health_proxy --http-listen-addr localhost:8080 \
--http-listen-path=/healthz \
--grpcaddr localhost:50051 \
--grpctls \
--service-name echo.EchoServer \
--grpc-ca-cert=CA_crt.pem \
--grpc-client-cert=grpc_client_crt.pem \
--grpc-client-key=grpc_client_key.pem \
--grpc-sni-server-name=server.domain.com --logtostderr=1 -v 1
Run this application stand alone or within a Docker image with TLS certificates mounted appropriately.
The Dockerfile provided here for the proxy but you are strongly encouraged to deploy your own docker image of the same:
docker.io/salrashid123/grpc_health_proxy
NOTE: the default docker image listens on containerPort :8080Note, the application an healthcheck docker image now is on
docker.io. Please generate and host your own images as necessary:
gcr.io/cloud-solutions-images/grpc_health_proxy =-> docker.io/salrashid123/grpc_health_proxyTo compile the proxy directly, run
go build -o grpc_health_proxy main.go
or download a binary from the Release page.
The proxy version also correspond to docker image tags.
docker.io/salrashid123/grpc_health_proxy:1.0.0 sha256:bba655892eedd2a59a0197f0949faad24f49546a6e548489be545c56776abbf9)| Option | Description |
|---|---|
-http-listen-addr |
host:port for the http(s) listener |
-grpcaddr |
upstream gRPC host:port the proxy will connect to |
-service-name |
gRPC service name to check |
gRPC server must implement the gRPC Health Checking Protocol v1. This means you must to register the
Health service and implement the rpc Check that returns a SERVING status.
The sample gRPC server provided below for golang implements it at:
func (s *Server) Check(ctx context.Context, in *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error)
TLS options for the connection from grpc_health_proxy to the upstream gRPC server
| Option | Description |
|---|---|
-grpctls |
use TLS to access gRPC Server (default: false) |
-grpc-ca-cert |
path to file containing CA certificates (to override system root CAs) |
-grpc-client-cert |
client certificate for authenticating to the server |
-grpc-client-key |
private key for for authenticating to the server |
-grpc-no-verify |
use TLS, but do not verify the certificate presented by the server (INSECURE) (default: false) |
-grpc-sni-server-name |
override the hostname used to verify the server certificate |
TLS options for the connection from an http client to grpc_health_proxy.
Configuration options for HTTTP(s) listener supports TLS and mTLS
| Option | Description |
|---|---|
-http-listen-addr |
host:port for the http(s) listener |
-http-listen-path |
path for http healthcheck requests (defaut / |
-https-listen-cert |
server public certificate for https listner |
-https-listen-key |
server private key for https listner |
-https-listen-verify |
option to enable mTLS for HTTPS requests |
-https-listen-ca |
trust CA for mTLS |
The example/ folder contains certificates and sample gRPC server application to test with.
Sample TLS certificates for use with this sample under example/certs folder:
CA_crt.pem: Root CAgrpc_server_crt.pem: TLS certificate for gRPC serverhttp_server_crt.pem: TLS certificate for http listner for grpc_health_proxyclient_crt.pem: Client certificate to use while connecting via mTLS to grpc_health_proxyTo use, first prepare the gRPC server and then run grpc_health_proxy. Use the curl command to invoke the http listener. Copy the certificates file at example/certs to the folder where the grpc_health_proxy, the grpc Server and curl are run from.
client->http->grpc_health_proxy->gRPC Server
cd example/
grpc_health_proxy \
--http-listen-addr localhost:8080 \
--http-listen-path=/healthz \
--grpcaddr localhost:50051 \
--service-name echo.EchoServer \
--logtostderr=1 -v 10
go run src/grpc_server.go \
--grpcport 0.0.0.0:50051 \
--insecure
curl -v \
--resolve 'http.domain.com:8080:127.0.0.1' \
http://http.domain.com:8080/healthz
client->https->grpc_health_proxy->gRPC Server
cd example/
grpc_health_proxy \
--http-listen-addr localhost:8080 \
--http-listen-path=/healthz \
--grpcaddr localhost:50051 \
--https-listen-cert=certs/http_server_crt.pem \
--https-listen-key=certs/http_server_key.pem \
--service-name echo.EchoServer \
--logtostderr=1 -v 10
go run src/grpc_server.go --grpcport 0.0.0.0:50051 --insecure
curl -v \
--cacert certs/CA_crt.pem \
--resolve 'http.domain.com:8080:127.0.0.1' \
https://http.domain.com:8080/healthz
client->https->grpc_health_proxy->mTLS->gRPC Server
Note that for convenience, we are reusing the same client and CA certificate during various stages here:
cd example/
grpc_health_proxy \
--http-listen-addr localhost:8080 \
--http-listen-path=/healthz \
--grpcaddr localhost:50051 \
--https-listen-cert=certs/http_server_crt.pem \
--https-listen-key=certs/http_server_key.pem \
--service-name echo.EchoServer \
--https-listen-verify \
--https-listen-ca=certs/CA_crt.pem \
--grpctls \
--grpc-client-cert=certs/client_crt.pem \
--grpc-client-key=certs/client_key.pem \
--grpc-ca-cert=certs/CA_crt.pem \
--grpc-sni-server-name=grpc.domain.com \
--logtostderr=1 -v 10
go run src/grpc_server.go \
--grpcport 0.0.0.0:50051 \
--tlsCert=certs/grpc_server_crt.pem \
--tlsKey=certs/grpc_server_key.pem
curl -v \
--resolve 'http.domain.com:8080:127.0.0.1' \
--cacert certs/CA_crt.pem \
--key certs/client_key.pem \
--cert certs/client_crt.pem \
https://http.domain.com:8080/healthz
Or as a docker container from the repo root to mount certs:
docker run -v `pwd`/certs:/certs/ \
-p 8080:8080 \
--net=host \
-t docker.io/salrashid123/grpc_health_proxy \
--http-listen-addr localhost:8080 \
--http-listen-path=/healthz \
--grpcaddr localhost:50051 \
--https-listen-cert=/certs/http_server_crt.pem \
--https-listen-key=/certs/http_server_key.pem \
--service-name echo.EchoServer \
--https-listen-verify \
--https-listen-ca=/certs/CA_crt.pem \
--grpctls \
--grpc-client-cert=/certs/client_crt.pem \
--grpc-client-key=/certs/client_key.pem \
--grpc-ca-cert=/certs/CA_crt.pem \
--grpc-sni-server-name=grpc.domain.com \
--logtostderr=1 -v 10
You can use this utility as a proxy for service healthchecks.
This is useful for external services that utilize HTTP but need to verify a gRPC services health status.
In the kubernetes deployment below, an http request to the healthcheck serving port (:8080) will reflect
the status of the gRPC service listening on port :50051
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
type: myapp-deployment-label
spec:
replicas: 1
selector:
matchLabels:
type: myapp
template:
metadata:
labels:
type: myapp
spec:
containers:
- name: hc-proxy
image: docker.io/salrashid123/grpc_health_proxy
args: [
"--http-listen-addr=0.0.0.0:8080",
"--grpcaddr=localhost:50051",
"--service-name=echo.EchoServer",
"--logtostderr=1",
"-v=1"
]
ports:
- containerPort: 8080
- name: grpc-app
image: docker.io/salrashid123/grpc_only_backend
args: [
"/grpc_server",
"--grpcport=0.0.0.0:50051",
"--insecure"
]
ports:
- containerPort: 50051
The docker image used for the gRPC Server is taken from eample/ folder in the same repo
You can run tis utiity is cli mode directly similar to the grpc_health_probe cited above. In this cli mode, you can a grpc healthcheck service without resorting to curl, etc.
There are several exit codes this utility returns
$ ./grpc_health_proxy \
--runcli \
--grpcaddr localhost:50051 \
--service-name echo.EchoServer \
--logtostderr=1
echo.EchoServer SERVING
$ echo $?
0
$ ./grpc_health_proxy \
--runcli \
--grpcaddr localhost:50051 \
--service-name echo.EchoServer \
--logtostderr=1
echo.EchoServer UNHEALTHY
$ echo $?
5
$ ./grpc_health_proxy \
--runcli \
--grpcaddr localhost:50051 \
--service-name echo.EchoServer \
--logtostderr=1
timeout: failed to connect service localhost:50051 within 1s
HealtCheck Probe Error: StatusConnectionFailure
$ echo $?
1
$ ./grpc_health_proxy \
--runcli \
--grpcaddr localhost:50051 \
--service-name foo \
--logtostderr=1
error Service Not Found rpc error: code = NotFound desc = unknown service
HealtCheck Probe Error: StatusServiceNotFound
$ echo $?
3
This site supports webmentions. Send me a mention via this form.