Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: enhance debugging docs #945

Merged
merged 24 commits into from
Jul 17, 2024
Merged
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0373e02
chore: docs
cmwylie19 Jul 9, 2024
d5ef09f
chore: add resources
cmwylie19 Jul 9, 2024
d8d2920
Update docs/060_best-practices/README.md
cmwylie19 Jul 9, 2024
81cb26e
Update docs/060_best-practices/README.md
cmwylie19 Jul 9, 2024
b8ed70e
Update docs/060_best-practices/README.md
cmwylie19 Jul 9, 2024
9632e91
Update docs/060_best-practices/README.md
cmwylie19 Jul 9, 2024
d384a82
chore: fix error
cmwylie19 Jul 9, 2024
664175f
chore: updates
cmwylie19 Jul 9, 2024
04c08a8
chore: debugging-856
cmwylie19 Jul 10, 2024
9c731aa
Merge branch 'main' into debugging-856
cmwylie19 Jul 10, 2024
7f8efc0
Merge branch 'main' into debugging-856
cmwylie19 Jul 15, 2024
89a0824
chore:fix json
cmwylie19 Jul 15, 2024
c41ab6c
Merge branch 'main' into debugging-856
cmwylie19 Jul 15, 2024
0ef4bad
chore: address comments
cmwylie19 Jul 16, 2024
99f2440
Merge branch 'main' into debugging-856
cmwylie19 Jul 16, 2024
502f4de
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
96de325
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
19b7c42
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
11f4d66
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
815a639
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
a0e289e
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
10f6afa
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
5ed0452
Update docs/060_best-practices/README.md
cmwylie19 Jul 17, 2024
891e784
Merge branch 'main' into debugging-856
cmwylie19 Jul 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 137 additions & 1 deletion docs/060_best-practices/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,143 @@ The workflow for developing features in Pepr is:

## Debugging

Pepr can be broken down into two parts: Admission and Watches. If the focus of the debug is on a Mutation or Validation, then only pay attention to pods with labels `pepr.dev/controller: admission`, else, you can focus on `pepr.dev/controller: watch`.
- [Debugging During Module Development](https://docs.pepr.dev/main/best-practices/#debugging-during-module-development)
- [Logging](https://docs.pepr.dev/main/best-practices/#logging)
- [Internal Error Occurred](https://docs.pepr.dev/main/best-practices/#internal-error-occurred)
- [Pepr Store](https://docs.pepr.dev/main/best-practices/#pepr-store)


Welcome to the the debugging section! 🐛

Pepr is composed of `Modules` (ie, what happens when you issue `npx pepr init`), [Capabilities](https://docs.pepr.dev/main/user-guide/capabilities/) like `hello-pepr.ts`, and [Actions](https://docs.pepr.dev/main/user-guide/actions/) (ie, the blocks of code containing filters and `Mutate`, `Validate`, `Watch`, `Reconcile`, `OnSchedule`). You can have as many Capabilities as you would like in a Module.

Pepr is a webhook-based system, meaning it is event-driven. When a resource is created, updated, or deleted, Pepr is called to perform the actions you have defined in your Capabilities. It's common for multiple webhooks to exist in a cluster, not just Pepr. When there are multiple webhooks, the order in which they are called is not guaranteed. The only garuantee is that all of the `MutatingWebhooks` will be called before all of the `ValidatingWebhooks`. After the admission webhooks are called, the `Watch` and `Reconcile` are called. The `Reconcile` and `Watch` create a watch on the resources specified in the `When` block and are watched for changes after admission. The difference between reconcile and watch is that `Reconcile` processes events in a queue to guarantee that the events are processed in order where as watch does not.
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved

Considering that many webhooks may be modifying the same resource, it is best practice to validate the resource after mutations are made to ensure that the resource is in a valid state if it has been changed since the last mutation.


**_It is always a best practice to add a `Validate` to your `Mutate` to ensure that the object is in a valid state before making changes._**
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved

```typescript
When(a.Pod)
.IsCreated()
.InNamespace("my-app")
.WithName("database")
.Mutate(pod => {
pod.metadata.labels["pepr"] = "true";
return pod;
})
// another mutating webhook could removed labels
.Validate(pod => {
if (pod.metadata.labels["pepr"] !== "true") {
return ["Label 'pepr' must be 'true'"];
}
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved
});
```

_If you think your Webhook is not being called for a given resource, check the `*WebhookConfiguration`._
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved


### Debugging During Module Development

Pepr supports breakpoints in the VSCode editor. To use breakpoints, run `npx pepr dev` in the root of a Pepr module using a JavaScript Debug Terminal. This command starts the Pepr development server running at `localhost:3000` with the `*WebhookConfiguration` configured to send `AdmissionRequest` objects to the local address.

This allows you to set breakpoints in `Mutate()`, `Validate()`, `Reconcile()`, `Watch()` or `OnSchedule()` and step through module code.

Note that you will need a cluster running:

```bash
k3d cluster create pepr-dev --k3s-arg '--debug@server:0' --wait
```

```typescript
When(a.Pod)
.IsCreated()
.InNamespace("my-app")
.WithName("database")
.Mutate(pod => {
// Set a breakpoint here
pod.metadata.labels["pepr"] = "true";
return pod;
})
.Validate(pod => {
// Set a breakpoint here
if (pod.metadata.labels["pepr"] !== "true") {
return ["Label 'pepr' must be 'true'"];
}
});
```

### Logging

Pepr can deploy two controllers: Admission and Watch. The controllers deployed are dictated by the [actions](https://docs.pepr.dev/main/user-guide/actions/) used in the capabilities (Pepr only deploys what is necessary). The default log level is `info`, but it can be changed to `debug` by setting the environment variable `LOG_LEVEL` to `debug`.
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved

Pepr logs for all pods:
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved

```bash
kubectl logs -l app.kubernetes.io/controller
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it'll pull logs for all controllers... which is pretty broad, no? Is there really no way to scope the label to Pepr controllers (of both types) only? I could swear I remember some label with "pepr.dev" in it but... maybe I'm misremembering.

kubectl logs -l 'pepr.dev/controller in (admission, watch)' maybe? Maybe the -n pepr-system flag would be helpful here too / otherwise (like the examples below)?

cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved
```

#### Admission Controller

If the focus of the debug is on a `Mutate()` or `Validate()`, the relevenat logs will be from pods with label `pepr.dev/controller: admission`.

```bash
kubectl logs -l pepr.dev/controller=admission -n pepr-system
```

More refined admission logs -- which can be optionally filtered by the module UUID -- can be obtained with [`npx pepr monitor`](https://docs.pepr.dev/main/best-practices/#monitoring)

```bash
npx pepr monitor
```

#### Watch Controller

If the focus of the debug is a `Watch()`, `Reconcile()`, or `OnSchedule()`, look for logs from pods containing label `pepr.dev/controller: watch`.
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved

```bash
kubectl logs -l pepr.dev/controller=watch -n pepr-system
cmwylie19 marked this conversation as resolved.
Show resolved Hide resolved
```

### Internal Error Occurred

```bash
Error from server (InternalError): Internal error occurred: failed calling webhook "<pepr_module>pepr.dev": failed to call webhook: Post ...
```

When an internal error occurs, check the deployed `*WebhookConfiguration` resources' timeout and failurePolicy configurations. If the failurePolicy is set to `Fail`, and a request cannot be processed within the timeout, that request will be rejected. If the failurePolicy is set to `Ignore`, given the same timeout conditions, the request will (perhaps surprisingly) be allowed to continue.

If you have a validating webhook, the recommended is to set the failurePolicy to `Fail` to ensure that the request is rejected if the webhook fails.

```yaml
failurePolicy: Fail
matchPolicy: Equivalent
timeoutSeconds: 3
```

The failurePolicy and timeouts can be set in the Module's `package.json` file, under the `pepr` configuration key. If changed, the settings will be reflected in the `*WebhookConfiguration` after the next build:

```json
"pepr": {
"uuid": "static-test",
"onError": "ignore",
"webhookTimeout": 10,
}
```

Read more on customization [here](https://docs.pepr.dev/main/user-guide/customization/).


### Pepr Store

If you need to read all store keys, or you think the PeprStore is malfunctioning, you can check the PeprStore CR:

```bash
kubectl get peprstore -n pepr-system -o yaml
```

You should run in `npx pepr dev` mode to debug the issue, see the [Debugging During Module Development](https://docs.pepr.dev/main/best-practices/#debugging-during-module-development) section for more information.

## Deployment

Expand Down
Loading