Nightingale
Tiny binary for gRPC services for docker HEALTHCHECK command which calls the gRPC recommended health check protocol
Install / Use
/learn @zakhenry/NightingaleREADME
Tiny binary for gRPC services for HEALTHCHECK docker command which calls the gRPC recommended health check service
Features
- Self contained binary
- will work in
FROM scratchimages - same binary will work in most <sup>all?</sup> linux x86_64 based images
- will work in
- Small -
2.3mbstatically linked binary - Quick installation using docker multi-build pattern
Prerequisites
Your gRPC server must have a service which implements the gRPC health checking protocol
<details> <summary>View .proto file:</summary> <!-- embedme proto/health_check.proto#L3-L24 -->syntax = "proto3";
package grpc.health.v1;
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
service Health {
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}
</details>
Your Health service only needs to implement the unary Check rpc, as nightingale
does not use the streaming endpoint.
Feel free to throw 12: Unimplemented in the Watch endpoint.
Installation
In your Dockerfile add the following lines (this is using the multi stage build strategy)
COPY --from=xiphiaz/nightingale:latest /nightingale /nightingale
HEALTHCHECK CMD /nightingale
Nightingale Options
Note that options like --interval and --timeout should be passed to HEALTCHECK, NOT nightingale
USAGE:
nightingale [OPTIONS] --host <host> --port <port>
FLAGS:
--help Prints help information
-V, --version Prints version information
OPTIONS:
-h, --host <host> Set host to use [default: [::1]]
-p, --port <port> Set port to use [default: 50051]
-s, --service <service> Which gRPC service request healthcheck for [default: ]
Comprehensive install:
COPY --from=xiphiaz/nightingale:latest /nightingale /nightingale
HEALTHCHECK --interval=5s --timeout=3s --start-period=10s --retries=5 CMD /nightingale --host 0.0.0.0 --port 50051 --service example.ExampleService
Usage
When your docker container starts, nightingale will be run every --interval (default 30s)
which will in turn call the Check rpc endpoint of your Health service.
- If this returns
SERVING,nightingalewill exit0and the container is considered"healthy". - If this returns
NOT_SERVINGorUNKNOWNnightingalewill exit1and the container is considered"unhealthy". - If this doesn't return at all, after
--timeout(Default 30s), docker will cancelnightingaleand consider the container"unhealthy".
You can verify the behavior and configuration is correct by running your container locally, and running the following command to view the docker-determined health status:
docker inspect --format='{{json .State.Health}}' $(docker ps -q --filter ancestor=your-image-name) | jq
Note the interval configuration - you need to wait some time before seeing the docker log of health.
Future tasks
- Handle multiple service checks
- Clean up text output as docker inspect is very limiting in output format
- Unit tests over the input validation
Contributing
- Install rust https://www.rust-lang.org/tools/install
- Build & run
rustup install beta rustup component add rustfmt --toolchain beta cargo +beta run --bin nightingale - Builder docker image
docker build -t nightingale:latest .
