How to Setup Kubernetes Health Checking for gRPC with NodeJs And Bazel? (grpc-health-probe) How to Setup Kubernetes Health Checking for gRPC with NodeJs And Bazel? (grpc-health-probe) kubernetes kubernetes

How to Setup Kubernetes Health Checking for gRPC with NodeJs And Bazel? (grpc-health-probe)


1. Add the grpc-health-probe binary to Bazel

In your WORKSPACE file add

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")http_file(    name = "grpc_health_check_bin",    downloaded_file_path = "grpc_health_probe",    urls = ["https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/v0.3.2/grpc_health_probe-linux-amd64"],)

to download the executable binary.

2. Implement Service

Option 1: Use the grpc-health-check npm module

  • just read the docs :)

Option 2 Implement the Health service yourself

  1. Go to this page and copy the health-checking.proto file, which currently looks like this:
    syntax = "proto3";package grpc.health.v1;message HealthCheckRequest {  string service = 1;}message HealthCheckResponse {  enum ServingStatus {    UNKNOWN = 0;    SERVING = 1;    NOT_SERVING = 2;    SERVICE_UNKNOWN = 3;  // Used only by the Watch method.  }  ServingStatus status = 1;}service Health {  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);  rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);}
  2. In your BUILD.bazel file create a filegroup with the proto file, such that we can later add it to the NodeJs image
    filegroup(    name = "health_checking_proto",    srcs = ["health-checking.proto"],)
  3. Implement the Health service
    import * as protoLoader from '@grpc/proto-loader'import * as grpc from '@grpc/grpc-js'async function main() {  const packageDefinition = await protoLoader.load('health-checking.proto')  const grpcObject = grpc.loadPackageDefinition(packageDefinition)  const {service} = (grpcObject.grpc as any).health.v1.Health  const server = new grpc.Server()  const implementation = {    // status can be on of UNKNOWN, SERVING, NOT_SERVING    Check: (_call: any, callback: any) => callback(null, {status: 'SERVING'}),  }  server.addService(service, implementation)  server.bindAsync('0.0.0.0:9090', grpc.ServerCredentials.createInsecure(), () => server.start())}main()

3. Build and Deploy the NodeJs image with Bazel

The final BUILD file might look like this:

load("@npm//@bazel/typescript:index.bzl", "ts_library")load("@k8s_deploy//:defaults.bzl", "k8s_deploy")load("@io_bazel_rules_docker//nodejs:image.bzl", "nodejs_image")package(default_visibility = ["//visibility:public"])ts_library(    name = "lib",    srcs = glob(include = ["**/*.ts"]),    deps = [        "@npm//@grpc/grpc-js",        "@npm//@grpc/proto-loader",        "@npm//@types/node",    ],)filegroup(    name = "health_checking_proto",    srcs = ["health-checking.proto"],)nodejs_image(    name = "image",    data = [        # nodejs application        ":lib",        # health-checking.proto file        ":health_checking_proto",        # grpc-health-probe executable binary        "@grpc_health_check_bin//file",    ],    entry_point = ":index.ts",)k8s_deploy(    name = "k8s",    images = {"k8s:placeholder_name": ":image"},    template = ":k8s.yaml",)

4. Add Liveness and Readiness Probes to Kubernetes

spec:  containers:  - name: server    image: "[YOUR-DOCKER-IMAGE]"    ports:    - containerPort: 9090    readinessProbe:      exec:        command: ["/app/<path to dir with BUILD file>/image.binary.runfiles/grpc_health_check_bin/file/grpc_health_probe", "-addr=:9090"]      initialDelaySeconds: 5    livenessProbe:      exec:        command: ["/app/<path to dir with BUILD file>/image.binary.runfiles/grpc_health_check_bin/file/grpc_health_probe", "-addr=:9090"]      initialDelaySeconds: 10