Don't use debug base; Add pprof handlers

Add pprof web handlers mostly for testing, not because it is needed.
Dockerfile: Use the non-debug base image. Use user nobody since
    that is a bit more standard than user "nonroot"
pprofweb-deploy.yaml: Example Kubernetes configuration
This commit is contained in:
Evan Jones 2020-01-20 10:55:01 -05:00 committed by GitHub
parent 87b634aecb
commit e29f0a2d66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 3 deletions

View File

@ -13,15 +13,14 @@ RUN cd /tmp && \
for deb in *.deb; do dpkg --extract $deb /dpkg || exit 10; done
FROM gcr.io/distroless/base-debian10:debug AS run
FROM gcr.io/distroless/base-debian10:latest AS run
COPY --from=builder /go/src/pprofweb/pprofweb /pprofweb
COPY --from=deb_extractor /dpkg /
# Configure dot plugins
RUN ["dot", "-c"]
# Use a non-root user: slightly more secure (defense in depth)
USER nonroot
USER nobody
WORKDIR /
EXPOSE 8080
ENTRYPOINT ["/pprofweb"]

60
pprofweb-deploy.yaml Normal file
View File

@ -0,0 +1,60 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: pprofweb
labels:
app: pprofweb
spec:
replicas: 1
selector:
matchLabels:
app: pprofweb
template:
metadata:
labels:
app: pprofweb
annotations:
# allow scale down even though this uses an emptyDir for tmp
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
spec:
containers:
- name: pprofweb
image: us.gcr.io/gosignin-demo/pprofweb:20200120-1
resources:
requests:
memory: 64Mi
#ephemeral-storage: 256Mi
limits:
memory: 128Mi
#ephemeral-storage: 256Mi
volumeMounts:
- mountPath: /tmp
name: tmp
# defense in depth: read-only FS; run as nobody/nogroup
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65534
runAsGroup: 65534
volumes:
- name: tmp
emptyDir:
# TODO: replace with resource request/limit?
sizeLimit: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: pprofweb
spec:
selector:
app: pprofweb
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080

View File

@ -5,6 +5,7 @@ import (
"io"
"log"
"net/http"
"net/http/pprof"
"os"
"path"
"strings"
@ -128,6 +129,13 @@ func main() {
mux.HandleFunc(uploadPath, s.uploadHandlerErrHandler)
mux.HandleFunc(pprofWebPath, s.servePprof)
// copied from net/http/pprof to avoid relying on the global http.DefaultServeMux
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
port := os.Getenv(portEnvVar)
if port == "" {
port = defaultPort