Skip to content

Commit 3a0a0cf

Browse files
authored
Merge pull request #742 from mauriciopoppe/delve-remote-debugging
Enable remote debugging with delve
2 parents bca22e3 + ca3e20f commit 3a0a0cf

File tree

9 files changed

+227
-8
lines changed

9 files changed

+227
-8
lines changed

Diff for: Dockerfile.debug

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2021 The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM golang:1.13.15 as builder
16+
WORKDIR /go/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
17+
ADD . .
18+
19+
RUN CGO_ENABLED=0 go get -ldflags "-s -w -extldflags '-static'" github.com/go-delve/delve/cmd/dlv
20+
RUN GCE_PD_CSI_DEBUG=1 make gce-pd-driver
21+
22+
# MAD HACKS: Build a version first so we can take the scsi_id bin and put it somewhere else in our real build
23+
FROM k8s.gcr.io/build-image/debian-base-amd64:buster-v1.5.0 as mad-hack
24+
RUN clean-install udev
25+
26+
# Start from Kubernetes Debian base
27+
FROM k8s.gcr.io/build-image/debian-base-amd64:buster-v1.5.0
28+
29+
# Copy source code too to correlate the binary and the breakpoints
30+
WORKDIR /go/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
31+
ADD . .
32+
33+
COPY --from=builder /go/bin/dlv /go/bin/dlv
34+
35+
# Install necessary dependencies
36+
RUN clean-install util-linux e2fsprogs mount ca-certificates udev xfsprogs
37+
COPY --from=mad-hack /lib/udev/scsi_id /lib/udev_containerized/scsi_id
38+
39+
# PDCSI driver isn't copied to / because of delve not being able to correlate
40+
# the binary and the source code, instead just run the binary where it was
41+
# compiled, the overlay noauth-dev calls this binary
42+
ENTRYPOINT ["/go/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/bin/gce-pd-csi-driver"]

Diff for: Makefile

+17-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ ifdef GCE_PD_CSI_STAGING_VERSION
2020
else
2121
STAGINGVERSION=${REV}
2222
endif
23+
24+
GCFLAGS=""
25+
ifdef GCE_PD_CSI_DEBUG
26+
GCFLAGS="all=-N -l"
27+
endif
28+
2329
STAGINGIMAGE=${GCE_PD_CSI_STAGING_IMAGE}
2430
DRIVERBINARY=gce-pd-csi-driver
2531
DRIVERWINDOWSBINARY=${DRIVERBINARY}.exe
@@ -38,7 +44,7 @@ WINDOWS_BASE_IMAGES=$(BASE_IMAGE_LTSC2019) $(BASE_IMAGE_1909) $(BASE_IMAGE_2004)
3844
all: gce-pd-driver gce-pd-driver-windows
3945
gce-pd-driver:
4046
mkdir -p bin
41-
go build -mod=vendor -ldflags "-X main.version=$(STAGINGVERSION)" -o bin/${DRIVERBINARY} ./cmd/gce-pd-csi-driver/
47+
go build -mod=vendor -gcflags=$(GCFLAGS) -ldflags "-X main.version=$(STAGINGVERSION)" -o bin/${DRIVERBINARY} ./cmd/gce-pd-csi-driver/
4248

4349
gce-pd-driver-windows:
4450
mkdir -p bin
@@ -76,6 +82,11 @@ build-and-push-multi-arch: build-and-push-container-linux build-and-push-windows
7682
STAGINGIMAGE="$(STAGINGIMAGE)" STAGINGVERSION="$(STAGINGVERSION)" WINDOWS_IMAGE_TAGS="$(WINDOWS_IMAGE_TAGS)" WINDOWS_BASE_IMAGES="$(WINDOWS_BASE_IMAGES)" ./manifest_osversion.sh
7783
$(DOCKER) manifest push -p $(STAGINGIMAGE):$(STAGINGVERSION)
7884

85+
build-and-push-multi-arch-debug: build-and-push-container-linux-debug build-and-push-windows-container-ltsc2019
86+
$(DOCKER) manifest create --amend $(STAGINGIMAGE):$(STAGINGVERSION) $(STAGINGIMAGE):$(STAGINGVERSION)_linux $(STAGINGIMAGE):$(STAGINGVERSION)_ltsc2019
87+
STAGINGIMAGE="$(STAGINGIMAGE)" STAGINGVERSION="$(STAGINGVERSION)" WINDOWS_IMAGE_TAGS="ltsc2019" WINDOWS_BASE_IMAGES="$(BASE_IMAGE_LTSC2019)" ./manifest_osversion.sh
88+
$(DOCKER) manifest push -p $(STAGINGIMAGE):$(STAGINGVERSION)
89+
7990
push-container: build-container
8091
gcloud docker -- push $(STAGINGIMAGE):$(STAGINGVERSION)
8192

@@ -84,6 +95,11 @@ build-and-push-container-linux: require-GCE_PD_CSI_STAGING_IMAGE init-buildx
8495
-t $(STAGINGIMAGE):$(STAGINGVERSION)_linux \
8596
--build-arg TAG=$(STAGINGVERSION) --push .
8697

98+
build-and-push-container-linux-debug: require-GCE_PD_CSI_STAGING_IMAGE init-buildx
99+
$(DOCKER) buildx build --file=Dockerfile.debug --platform=linux \
100+
-t $(STAGINGIMAGE):$(STAGINGVERSION)_linux \
101+
--build-arg TAG=$(STAGINGVERSION) --push .
102+
87103
test-sanity: gce-pd-driver
88104
go test -mod=vendor --v -timeout 30s sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/test/sanity -run ^TestSanity$
89105

Diff for: deploy/kubernetes/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ The current structure for kustomization is as follows. Note that Windows support
1616
* `overlays`: It has the k8s minor version-specific driver manifest bundle.
1717
* `stable-master`: Contains deployment specs of a stable driver for k8s master.
1818
* `stable-{k8s-minor}`: Contains deployment specs of a stable driver for given k8s minor version release.
19-
* `alpha`: Contains deployment specs for features in development. Both Linux and Windows are supported.
19+
* `alpha`: Contains deployment specs for features in development. Both Linux and Windows are supported.
2020
* `dev`: Based on alpha, and also contains the developer's specs for use in driver development.
21+
* `noauth-debug`: Based on alpha, used for debugging purposes only, see docs/kubernetes/development.md.
2122
* `prow-gke-release-staging-rc-master`: Used for prow tests. Contains deployment specs of a driver for latest k8s master.
2223
* `prow-gke-release-staging-rc-{k8s-minor}`: Used for prow tests. Contains deployment specs of a driver for given k8s minor version release.
2324
* `prow-gke-release-staging-rc-head`: Used for prow tests. Contains deployment specs of a driver with latest sidecar images, for latest k8s master.

Diff for: deploy/kubernetes/deploy-driver.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# which are in Kubernetes version 1.10.5+
99

1010
# Args:
11-
# GCE_PD_SA_DIR: Directory the service account key has been saved in (generated
11+
# GCE_PD_SA_DIR: Directory the service account key has been saved in (generated
1212
# by setup-project.sh). Ignored if GCE_PD_DRIVER_VERSION == noauth.
1313
# GCE_PD_DRIVER_VERSION: The kustomize overlay (located in
1414
# deploy/kubernetes/overlays) to deploy. Can be one of {stable, dev}
@@ -44,7 +44,7 @@ while [ -n "${1-}" ]; do
4444
esac
4545
done
4646

47-
if [ "${DEPLOY_VERSION}" != noauth ]; then
47+
if [[ ! "${DEPLOY_VERSION}" == *noauth* ]]; then
4848
ensure_var GCE_PD_SA_DIR
4949
fi
5050

@@ -74,7 +74,7 @@ function check_service_account()
7474

7575
ensure_kustomize
7676

77-
if [ "$skip_sa_check" != true -a "${DEPLOY_VERSION}" != noauth ]; then
77+
if [[ "$skip_sa_check" != true ]] && [[ ! "${DEPLOY_VERSION}" == *noauth* ]]; then
7878
check_service_account
7979
fi
8080

@@ -83,7 +83,7 @@ then
8383
${KUBECTL} create namespace "${NAMESPACE}" -v="${VERBOSITY}"
8484
fi
8585

86-
if [ "${DEPLOY_VERSION}" != noauth ]; then
86+
if [[ ! "${DEPLOY_VERSION}" == *noauth* ]]; then
8787
if ! ${KUBECTL} get secret cloud-sa -v="${VERBOSITY}" -n "${NAMESPACE}";
8888
then
8989
${KUBECTL} create secret generic cloud-sa -v="${VERBOSITY}" --from-file="${GCE_PD_SA_DIR}/cloud-sa.json" -n "${NAMESPACE}"

Diff for: deploy/kubernetes/install-kustomize.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ elif [[ "$OSTYPE" == darwin* ]]; then
4848
fi
4949

5050
# As github has a limit on what stored in releases/, and kustomize has many different package
51-
# versions, we just point directly at the version we want. See
51+
# versions, we just point directly at the version we want. See
5252
# github.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh.
5353

5454
version=v3.9.4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
kind: Deployment
2+
apiVersion: apps/v1
3+
metadata:
4+
name: csi-gce-pd-controller
5+
annotations:
6+
# https://kubernetes.io/docs/tutorials/clusters/apparmor/
7+
container.apparmor.security.beta.kubernetes.io/gce-pd-driver: unconfined
8+
spec:
9+
template:
10+
spec:
11+
containers:
12+
- name: gce-pd-driver
13+
imagePullPolicy: Always
14+
command: ["/go/bin/dlv"]
15+
args:
16+
- "--listen=:2345"
17+
- "--headless=true"
18+
- "--api-version=2"
19+
# https://github.com/go-delve/delve/blob/master/Documentation/usage/dlv_exec.md#options
20+
- "--accept-multiclient"
21+
- "--continue"
22+
- "--log"
23+
- "exec"
24+
- "/go/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/bin/gce-pd-csi-driver"
25+
- "--"
26+
- "--v=5"
27+
- "--endpoint=unix:/csi/csi.sock"
28+
ports:
29+
- containerPort: 2345
30+
securityContext:
31+
capabilities:
32+
add:
33+
- SYS_PTRACE
34+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: kustomize.config.k8s.io/v1beta1
2+
kind: Kustomization
3+
resources:
4+
- ../../base/
5+
# Here noauth overlay is using the same image as alpha
6+
transformers:
7+
- ../../images/alpha
8+
patchesStrategicMerge:
9+
- noauth.yaml
10+
- controller-overlay.yaml
11+
namespace: gce-pd-csi-driver
12+
# To change the dev image, add something like the following.
13+
# images:
14+
# - name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
15+
# newName: gcr.io/mauriciopoppe-gke-dev/gcp-compute-persistent-disk-csi-driver
16+
# newTag: latest

Diff for: deploy/kubernetes/overlays/noauth-debug/noauth.yaml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
kind: Deployment
2+
apiVersion: apps/v1
3+
metadata:
4+
name: csi-gce-pd-controller
5+
spec:
6+
template:
7+
spec:
8+
containers:
9+
- name: gce-pd-driver
10+
env:
11+
- $patch: delete
12+
name: GOOGLE_APPLICATION_CREDENTIALS
13+
value: "/etc/cloud-sa/cloud-sa.json"
14+
volumeMounts:
15+
- $patch: delete
16+
name: cloud-sa-volume
17+
readOnly: true
18+
mountPath: "/etc/cloud-sa"
19+
volumes:
20+
- $patch: delete
21+
name: cloud-sa-volume
22+
secret:
23+
secretName: cloud-sa
24+
25+

Diff for: docs/kubernetes/development.md

+86-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Manual
44

55
To build and install a development version of the driver:
6+
67
```
78
$ GCE_PD_CSI_STAGING_IMAGE=gcr.io/path/to/driver/image:dev # Location to push dev image to
89
$ make push-container
@@ -13,9 +14,93 @@ $ ./deploy/kubernetes/deploy-driver.sh
1314
```
1415

1516
To bring down driver:
17+
1618
```
1719
$ ./deploy/kubernetes/delete-driver.sh
1820
```
1921

20-
## TODO Testing
22+
## Debugging
23+
24+
We use https://github.com/go-delve/delve and its feature for remote debugging. This feature
25+
is only available in the PD CSI Controller (which runs in a linux node).
26+
27+
Requirements:
28+
29+
- https://github.com/go-delve/delve
30+
31+
Steps:
32+
33+
- Build the PD CSI driver with additional compiler flags.
34+
35+
```
36+
export GCE_PD_CSI_STAGING_VERSION=latest
37+
export GCE_PD_CSI_STAGING_IMAGE=image/repo/gcp-compute-persistent-disk-csi-driver
38+
make build-and-push-multi-arch-debug
39+
```
40+
41+
- Update `deploy/kubernetes/overlays/noauth-debug/kustomization.yaml` to match the repo you wrote above e.g.
42+
43+
```yaml
44+
images:
45+
- name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
46+
newName: image/repo/gcp-compute-persistent-disk-csi-driver
47+
newTag: latest
48+
```
49+
50+
- Delete and deploy the driver with this overlay
51+
52+
```sh
53+
./deploy/kubernetes/delete-driver.sh && \
54+
GCE_PD_DRIVER_VERSION=noauth-debug ./deploy/kubernetes/deploy-driver.sh
55+
```
56+
57+
At this point you could verify that delve is running in the controller logs:
58+
59+
```text
60+
API server listening at: [::]:2345
61+
2021-04-15T18:28:51Z info layer=debugger launching process with args: [/go/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/bin/gce-pd-csi-driver --v=5 --endpoint=unix:/csi/csi.sock]
62+
2021-04-15T18:28:53Z debug layer=debugger continuing
63+
```
64+
65+
- Enable port forwading of the PD CSI controller of port 2345
66+
67+
```sh
68+
kubectl -n gce-pd-csi-driver get pods | grep controller | awk '{print $1}' | xargs -I % kubectl -n gce-pd-csi-driver port-forward % 2345:2345
69+
```
70+
71+
- Connect to the headless server and issue commands
72+
73+
```sh
74+
dlv connect localhost:2345
75+
Type 'help' for list of commands.
76+
(dlv) clearall
77+
(dlv) break pkg/gce-pd-csi-driver/controller.go:509
78+
Breakpoint 1 set at 0x159ba32 for sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-pd-csi-driver.(*GCEControllerServer).ListVolumes() ./pkg/gce-pd-csi-driver/controller.go:509
79+
(dlv) c
80+
> sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-pd-csi-driver.(*GCEControllerServer).ListVolumes() ./pkg/gce-pd-csi-driver/controller.go:509 (hits goroutine(69):1 total:1) (PC: 0x159ba32)
81+
Warning: debugging optimized function
82+
504: }
83+
505: }
84+
506:
85+
507: func (gceCS *GCEControllerServer) ListVolumes(ctx context.Context, req *csi.ListVolumesRequest) (*csi.ListVolumesResponse, error) {
86+
508: // https//cloud.google.com/compute/docs/reference/beta/disks/list
87+
=> 509: if req.MaxEntries < 0 {
88+
510: return nil, status.Error(codes.InvalidArgument, fmt.Sprintf(
89+
511: "ListVolumes got max entries request %v. GCE only supports values between 0-500", req.MaxEntries))
90+
512: }
91+
513: var maxEntries int64 = int64(req.MaxEntries)
92+
514: if maxEntries > 500 {
93+
(dlv) req
94+
Command failed: command not available
95+
(dlv) p req
96+
*github.com/container-storage-interface/spec/lib/go/csi.ListVolumesRequest {
97+
MaxEntries: 0,
98+
StartingToken: "",
99+
XXX_NoUnkeyedLiteral: struct {} {},
100+
XXX_unrecognized: []uint8 len: 0, cap: 0, nil,
101+
XXX_sizecache: 0,}
102+
(dlv)
103+
```
104+
105+
See https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/pull/742 for the implementation details
21106

0 commit comments

Comments
 (0)