Skip to content

Commit

Permalink
entrypoint: add liveness probe endpoint to the sidecar
Browse files Browse the repository at this point in the history
This change uses the liveness probes as a way to guarantee a regular
period of uninterrupted CPU for the sidecar to complete its prometheus
scrapes and flushes to GMP.

Change-Id: Ic6f0ed38ade237d6179dea12268cd2575d221146
  • Loading branch information
ridwanmsharif committed May 23, 2024
1 parent 18777a5 commit b48c63a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 40 deletions.
21 changes: 21 additions & 0 deletions entrypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/signal"
"path/filepath"
Expand All @@ -34,6 +35,9 @@ var userConfigFile = "/etc/rungmp/config.yaml"
var otelConfigFile = "/run/rungmp/otel.yaml"
var configRefreshInterval = 20 * time.Second
var selfMetricsPort = 0
var livenessProbePort = 13133
var livenessProbePath = "/liveness"
var delayLivenessProbe = 5 * time.Second

func getRawUserConfig(userConfigFile string) (string, error) {
_, err := os.Stat(userConfigFile)
Expand Down Expand Up @@ -84,6 +88,16 @@ func generateOtelConfig(ctx context.Context, userConfigFile string) error {
return nil
}

// The container is allocated CPU for the duration of the healthcheck. Delaying
// the response to this probe allows the container to complete telemetry flushes
// that may have been throttled.
//
// TODO(b/342463831): Use a more reliable way of checking if telemetry is being
// flushed instead of using a static sleep.
func healthcheckHandler(w http.ResponseWriter, r *http.Request) {
time.Sleep(delayLivenessProbe)
}

func main() {
// SIGINT handles Ctrl+C locally.
// SIGTERM handles Cloud Run termination signal.
Expand All @@ -101,6 +115,13 @@ func main() {
log.Fatal(err)
}

entrypointMux := http.NewServeMux()
entrypointMux.HandleFunc(livenessProbePath, healthcheckHandler)

go func() {
http.ListenAndServe(fmt.Sprintf(":%d", livenessProbePort), entrypointMux)
}()

// Spin up new-subprocess that runs the OTel collector and store the PID.
// This OTel collector should use the generated config.
var procAttr os.ProcAttr
Expand Down
31 changes: 16 additions & 15 deletions run-service-simple.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,22 @@ spec:
metadata:
annotations:
run.googleapis.com/execution-environment: gen2
run.googleapis.com/cpu-throttling: 'false'
run.googleapis.com/cpu-throttling: "false"
run.googleapis.com/container-dependencies: '{"collector":["app"]}'
spec:
containers:
- image: "%SAMPLE_APP_IMAGE%"
name: app
startupProbe:
httpGet:
path: /startup
port: 8000
livenessProbe:
httpGet:
path: /liveness
port: 8000
ports:
- containerPort: 8000
- image: us-docker.pkg.dev/cloud-ops-agents-artifacts/cloud-run-gmp-sidecar/cloud-run-gmp-sidecar:1.1.1
name: collector
- image: "%SAMPLE_APP_IMAGE%"
name: app
startupProbe:
httpGet:
path: /startup
port: 8000
livenessProbe:
httpGet:
path: /liveness
port: 8000
ports:
- containerPort: 8000
- image: us-docker.pkg.dev/cloud-ops-agents-artifacts/cloud-run-gmp-sidecar/cloud-run-gmp-sidecar:1.1.1
name: collector
# TODO(b/342463134): Post release 1.2.0, update the collector container to use the healthcheck endpoint
55 changes: 30 additions & 25 deletions run-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,37 @@ spec:
metadata:
annotations:
run.googleapis.com/execution-environment: gen2
run.googleapis.com/cpu-throttling: 'false'
run.googleapis.com/container-dependencies: '{"collector":["app"]}'
run.googleapis.com/secrets: '%SECRET%:projects/%PROJECT%/secrets/%SECRET%'
run.googleapis.com/secrets: "%SECRET%:projects/%PROJECT%/secrets/%SECRET%"
spec:
containers:
- image: "%SAMPLE_APP_IMAGE%"
name: app
startupProbe:
httpGet:
path: /startup
port: 8000
livenessProbe:
httpGet:
path: /liveness
port: 8000
ports:
- containerPort: 8000
- image: "%OTELCOL_IMAGE%"
name: collector
volumeMounts:
- mountPath: /etc/rungmp/
name: config
- image: "%SAMPLE_APP_IMAGE%"
name: app
startupProbe:
httpGet:
path: /startup
port: 8000
livenessProbe:
httpGet:
path: /liveness
port: 8000
ports:
- containerPort: 8000
- image: "%OTELCOL_IMAGE%"
name: collector
livenessProbe:
httpGet:
path: /liveness
port: 13133
timeoutSeconds: 30
periodSeconds: 30
volumeMounts:
- mountPath: /etc/rungmp/
name: config
volumes:
- name: config
secret:
items:
- key: latest
path: config.yaml
secretName: '%SECRET%'
- name: config
secret:
items:
- key: latest
path: config.yaml
secretName: "%SECRET%"

0 comments on commit b48c63a

Please sign in to comment.