From 0b14722be40760a6754905efc938bf1420efe96d Mon Sep 17 00:00:00 2001 From: Travis Groth Date: Tue, 13 Oct 2020 16:54:21 -0400 Subject: [PATCH] deplyoment: add debug build / container / docs (#1513) --- .github/workflows/docker-master.yaml | 20 ++++- .vscode/launch.json | 14 +++- DEBUG.MD | 118 +++++++++++++++++++++++++++ Dockerfile.debug | 28 +++++++ Makefile | 7 ++ scripts/debug-entrypoint.sh | 5 ++ 6 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 DEBUG.MD create mode 100644 Dockerfile.debug create mode 100755 scripts/debug-entrypoint.sh diff --git a/.github/workflows/docker-master.yaml b/.github/workflows/docker-master.yaml index 42f283e81..87f1d87da 100644 --- a/.github/workflows/docker-master.yaml +++ b/.github/workflows/docker-master.yaml @@ -1,4 +1,4 @@ -name: Docker Tag - Master +name: Docker Master on: push: branches: @@ -10,6 +10,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 + - name: Docker Publish - Master uses: zenato/docker-action@master with: @@ -17,3 +18,20 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} repository: pomerium/pomerium tag: master + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Docker Publish - Debug + uses: docker/build-push-action@v2 + with: + context: . + file: ./Dockerfile.debug + push: true + tags: pomerium/pomerium:debug diff --git a/.vscode/launch.json b/.vscode/launch.json index 7584ef5f4..b520e2b45 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,19 @@ "request": "launch", "mode": "debug", "program": "${workspaceRoot}/cmd/pomerium", - "args": ["-config", "${workspaceRoot}/.config.yaml"] + "args": [ + "-config", + "${workspaceRoot}/.config.yaml" + ] + }, + { + "name": "Connect to server", + "type": "go", + "request": "attach", + "mode": "remote", + "remotePath": "/go/src/github.com/pomerium/pomerium/", + "port": 9999, + "host": "127.0.0.1", } ] } diff --git a/DEBUG.MD b/DEBUG.MD new file mode 100644 index 000000000..31de11bef --- /dev/null +++ b/DEBUG.MD @@ -0,0 +1,118 @@ +Instructions for remotely debugging pomerium. Especially useful in container deployments. + +- [Building](#building) + - [Binary](#binary) + - [Container](#container) +- [Running](#running) + - [Kubernetes](#kubernetes) + - [Docker Compose](#docker-compose) +- [Debugging](#debugging) + - [VSCode](#vscode) + +# Building + +## Binary + +If you are building a binary to run outside of a container: + +``` +make build-debug +``` + +## Container + +The published `pomerium/pomerium:debug` image contains an entrypoint and environment appropriate for debugging purposes. It can be run in docker by itself, or in kubernetes. It will not run the debugger by default - set the entrypoint to `/debug-entrypoint.sh`. + +It can be rebuilt via: + +`docker build -t pomerium/pomerium:debug -f Dockerfile.debug .` + +# Running + +To run the container in debug mode you must: + +- Set your entrypoint to `/debug-entrypoint.sh` +- Add the `SYS_PTRACE` capability +- Attach your debugger to the `dlv` port (9999 by default) + +Override `DEBUG_PORT` or `DEBUG_ADDRESS` env vars to change listening ports and addresses. + +## Kubernetes + +Patch your deployment as follows: + +patch.yaml +```yaml +spec: + replicas: 1 + template: + spec: + containers: + - name: pomerium + # this can be changed in helm chart or use a custom/local build + image: pomerium/pomerium:debug + securityContext: + capabilities: + add: + - SYS_PTRACE + command: + - /debug-entrypoint.sh + # Disable health checks + livenessProbe: null + readinessProbe: null +``` + +Patch the deployment: + +```bash +kubectl patch deployments.apps pomerium-authorize --patch "$(cat patch.yaml)" +``` + +Port forward to the service: + +```bash +DEPLOYMENT=pomerium-authorize +kubectl port-forward $(kubectl get pods -l app.kubernetes.io/name=${DEPLOYMENT} -o jsonpath="{.items[0].metadata.name}") 9999 +``` + +## Docker Compose + +Set/override the following parameters in your compose file: + +```yaml +services: + pomerium: + entrypoint: /debug-entrypoint.sh + cap_add: + - SYS_PTRACE + ports: + - "9999:9999" + +``` + +# Debugging + +## VSCode + +Use remote debugging support. Set up a launch configuration as follows: + + +**NOTE** The remotePath must precisely match the directory the code was built in. See references: [1] [2]. The directory does not need to actually exist in the running container. + +```json + { + "name": "Connect to server", + "type": "go", + "request": "attach", + "mode": "remote", + "remotePath": "/go/src/github.com/pomerium/pomerium/", + "port": 9999, + "host": "127.0.0.1", + } +``` + +Running the launch configuration should attach to the running process. + + +[1]: https://github.com/microsoft/vscode-go/issues/941 +[2]: https://github.com/microsoft/vscode-go/issues/2010 diff --git a/Dockerfile.debug b/Dockerfile.debug new file mode 100644 index 000000000..677231068 --- /dev/null +++ b/Dockerfile.debug @@ -0,0 +1,28 @@ +FROM golang:latest as build +WORKDIR /go/src/github.com/pomerium/pomerium + +RUN apt-get update \ + && apt-get -y install zip + +# cache depedency downloads +COPY go.mod go.sum ./ +RUN go mod download +COPY . . + +# build +RUN make build-deps +RUN make build-debug NAME=pomerium +RUN make build-debug NAME=pomerium-cli +RUN touch /config.yaml +RUN go get github.com/go-delve/delve/cmd/dlv + +FROM alpine:latest +ENV AUTOCERT_DIR /data/autocert +WORKDIR /pomerium +RUN apk add --no-cache ca-certificates +COPY --from=build /go/src/github.com/pomerium/pomerium/bin/* /bin/ +COPY --from=build /config.yaml /pomerium/config.yaml +COPY --from=build /go/bin/dlv /bin +COPY scripts/debug-entrypoint.sh / +ENTRYPOINT [ "/bin/pomerium" ] +CMD ["-config","/pomerium/config.yaml"] diff --git a/Makefile b/Makefile index a52d0f16d..f3f74b880 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,13 @@ build: ## Builds dynamic executables and/or packages. @CGO_ENABLED=0 GO111MODULE=on $(GO) build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} -o $(BINDIR)/$(NAME) ./cmd/"$(NAME)" ./scripts/embed-envoy.bash $(BINDIR)/$(NAME) +.PHONY: build-debug +build-debug: ## Builds binaries appropriate for debugging + @echo "==> $@" + @CGO_ENABLED=0 GO111MODULE=on $(GO) build -gcflags="all=-N -l" -o $(BINDIR)/$(NAME) ./cmd/"$(NAME)" + ./scripts/embed-envoy.bash $(BINDIR)/$(NAME) + + .PHONY: lint lint: ## Verifies `golint` passes. @echo "==> $@" diff --git a/scripts/debug-entrypoint.sh b/scripts/debug-entrypoint.sh new file mode 100755 index 000000000..af39770e6 --- /dev/null +++ b/scripts/debug-entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +DEBUG_PORT="${DEBUG_PORT:-9999}" +DEBUG_ADDRESS="${DEBUG_ADDRESS:-127.0.0.1}" +/bin/dlv exec /bin/pomerium --api-version=2 --headless --listen="${DEBUG_ADDRESS}:${DEBUG_PORT}" --log --accept-multiclient -- "$@"