Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 88bb9fb

Browse files
committed
Add process logging documentation for workspaces
Include instructions for enabling and configuring workspace process logging on Kubernetes to help users monitor system-level processes.
1 parent f709b8e commit 88bb9fb

File tree

2 files changed

+321
-0
lines changed

2 files changed

+321
-0
lines changed
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
# Workspace Process Logging
2+
3+
The workspace process logging feature allows you to log all system-level
4+
processes executing in the workspace.
5+
6+
> **Note:** This feature is only available on Linux in Kubernetes. There are
7+
> additional requirements outlined further in this document.
8+
9+
Workspace process logging adds a sidecar container to workspace pods that will
10+
log all processes started in the workspace container (e.g., commands executed in
11+
the terminal or processes created in the background by other processes).
12+
Processes launched inside containers or nested containers within the workspace
13+
are also logged. You can view the output from the sidecar or send it to a
14+
monitoring stack, such as CloudWatch, for further analysis or long-term storage.
15+
16+
Please note that these logs are not recorded or captured by the Coder
17+
organization in any way, shape, or form.
18+
19+
> This is an [Premium or Enterprise](https://coder.com/pricing) feature. To
20+
> learn more about Coder Enterprise, please
21+
> [contact sales](https://coder.com/contact).
22+
23+
## How this works
24+
25+
Coder uses [eBPF](https://ebpf.io/) (which we chose for its minimal performance
26+
impact) to perform in-kernel logging and filtering of all exec system calls
27+
originating from the workspace container.
28+
29+
The core of this feature is also open source and can be found in the
30+
[exectrace](https://github.com/coder/exectrace) GitHub repo. The enterprise
31+
component (in the `enterprise/` directory of the repo) is responsible for
32+
starting the eBPF program with the correct filtering options for the specific
33+
workspace.
34+
35+
## Requirements
36+
37+
The host machine must be running a Linux kernel >= 5.8 with the kernel config
38+
`CONFIG_DEBUG_INFO_BTF=y` enabled.
39+
40+
To check your kernel version, run:
41+
42+
```shell
43+
uname -r
44+
```
45+
46+
To validate the required kernel config is enabled, run either of the following
47+
commands on your nodes directly (_not_ from a workspace terminal):
48+
49+
```shell
50+
cat /proc/config.gz | gunzip | grep CONFIG_DEBUG_INFO_BTF
51+
```
52+
53+
```shell
54+
cat "/boot/config-$(uname -r)" | grep CONFIG_DEBUG_INFO_BTF
55+
```
56+
57+
If these requirements are not met, workspaces will fail to start for security
58+
reasons.
59+
60+
Your template must be a Kubernetes template. Workspace process logging is not
61+
compatible with the `sysbox-runc` runtime due to technical limitations, but it
62+
is compatible with our `envbox` template family.
63+
64+
## Example templates
65+
66+
We provide working example templates for Kubernetes, and Kubernetes with
67+
`envbox` (for [Docker support in workspaces](./docker-in-workspaces.md)). You
68+
can view these templates in the
69+
[exectrace repo](https://github.com/coder/exectrace/tree/main/enterprise/templates).
70+
71+
## Configuring custom templates to use workspace process logging
72+
73+
If you have an existing Kubernetes or Kubernetes with `envbox` template that you
74+
would like to add workspace process logging to, follow these steps:
75+
76+
1. Ensure the image used in your template has `curl` installed.
77+
78+
1. Add the following section to your template's `main.tf` file:
79+
80+
<!--
81+
If you are updating this section, please also update the example templates
82+
in the exectrace repo.
83+
-->
84+
85+
```hcl
86+
locals {
87+
# This is the init script for the main workspace container that runs before the
88+
# agent starts to configure workspace process logging.
89+
exectrace_init_script = <<EOT
90+
set -eu
91+
pidns_inum=$(readlink /proc/self/ns/pid | sed 's/[^0-9]//g')
92+
if [ -z "$pidns_inum" ]; then
93+
echo "Could not determine process ID namespace inum"
94+
exit 1
95+
fi
96+
97+
# Before we start the script, does curl exist?
98+
if ! command -v curl >/dev/null 2>&1; then
99+
echo "curl is required to download the Coder binary"
100+
echo "Please install curl to your image and try again"
101+
# 127 is command not found.
102+
exit 127
103+
fi
104+
105+
echo "Sending process ID namespace inum to exectrace sidecar"
106+
rc=0
107+
max_retry=5
108+
counter=0
109+
until [ $counter -ge $max_retry ]; do
110+
set +e
111+
curl \
112+
--fail \
113+
--silent \
114+
--connect-timeout 5 \
115+
-X POST \
116+
-H "Content-Type: text/plain" \
117+
--data "$pidns_inum" \
118+
http://127.0.0.1:56123
119+
rc=$?
120+
set -e
121+
if [ $rc -eq 0 ]; then
122+
break
123+
fi
124+
125+
counter=$((counter+1))
126+
echo "Curl failed with exit code $${rc}, attempt $${counter}/$${max_retry}; Retrying in 3 seconds..."
127+
sleep 3
128+
done
129+
if [ $rc -ne 0 ]; then
130+
echo "Failed to send process ID namespace inum to exectrace sidecar"
131+
exit $rc
132+
fi
133+
134+
EOT
135+
}
136+
```
137+
138+
1. Update the `command` of your workspace container like the following:
139+
140+
<!--
141+
If you are updating this section, please also update the example templates
142+
in the exectrace repo.
143+
-->
144+
145+
```hcl
146+
resource "kubernetes_pod" "main" {
147+
...
148+
spec {
149+
...
150+
container {
151+
...
152+
// NOTE: this command is changed compared to the upstream kubernetes
153+
// template
154+
command = [
155+
"sh",
156+
"-c",
157+
"${local.exectrace_init_script}\n\n${coder_agent.main.init_script}",
158+
]
159+
...
160+
}
161+
...
162+
}
163+
...
164+
}
165+
```
166+
167+
> **Note:** If you are using the `envbox` template, you will need to update
168+
> the third argument to be
169+
> `"${local.exectrace_init_script}\n\nexec /envbox docker"` instead.
170+
171+
1. Add the following container to your workspace pod spec.
172+
173+
<!--
174+
If you are updating this section, please also update the example templates
175+
in the exectrace repo.
176+
-->
177+
178+
```hcl
179+
resource "kubernetes_pod" "main" {
180+
...
181+
spec {
182+
...
183+
// NOTE: this container is added compared to the upstream kubernetes
184+
// template
185+
container {
186+
name = "exectrace"
187+
image = "ghcr.io/coder/exectrace:latest"
188+
image_pull_policy = "Always"
189+
command = [
190+
"/opt/exectrace",
191+
"--init-address", "127.0.0.1:56123",
192+
"--label", "workspace_id=${data.coder_workspace.me.id}",
193+
"--label", "workspace_name=${data.coder_workspace.me.name}",
194+
"--label", "user_id=${data.coder_workspace_owner.me.id}",
195+
"--label", "username=${data.coder_workspace_owner.me.name}",
196+
"--label", "user_email=${data.coder_workspace_owner.me.email}",
197+
]
198+
security_context {
199+
// exectrace must be started as root so it can attach probes into the
200+
// kernel to record process events with high throughput.
201+
run_as_user = "0"
202+
run_as_group = "0"
203+
// exectrace requires a privileged container so it can control mounts
204+
// and perform privileged syscalls against the host kernel to attach
205+
// probes.
206+
privileged = true
207+
}
208+
}
209+
...
210+
}
211+
...
212+
}
213+
```
214+
215+
> **Note:** `exectrace` requires root privileges and a privileged container
216+
> to attach probes to the kernel. This is a requirement of eBPF.
217+
218+
1. Add the following environment variable to your workspace pod:
219+
220+
<!--
221+
If you are updating this section, please also update the example templates
222+
in the exectrace repo.
223+
-->
224+
225+
```hcl
226+
resource "kubernetes_pod" "main" {
227+
...
228+
spec {
229+
...
230+
env {
231+
name = "CODER_AGENT_SUBSYSTEM"
232+
value = "exectrace"
233+
}
234+
...
235+
}
236+
...
237+
}
238+
```
239+
240+
Once you have made these changes, you can push a new version of your template
241+
and workspace process logging will be enabled for all workspaces once they are
242+
restarted.
243+
244+
## Viewing workspace process logs
245+
246+
To view the process logs for a specific workspace you can use `kubectl` to print
247+
the logs:
248+
249+
```bash
250+
kubectl logs pod-name --container exectrace
251+
```
252+
253+
The raw logs will look something like this:
254+
255+
```json
256+
{
257+
"ts": "2022-02-28T20:29:38.038452202Z",
258+
"level": "INFO",
259+
"msg": "exec",
260+
"fields": {
261+
"labels": {
262+
"user_email": "[email protected]",
263+
"user_id": "5e876e9a-121663f01ebd1522060d5270",
264+
"username": "jessie",
265+
"workspace_id": "621d2e52-a6987ef6c56210058ee2593c",
266+
"workspace_name": "main"
267+
},
268+
"cmdline": "uname -a",
269+
"event": {
270+
"filename": "/usr/bin/uname",
271+
"argv": ["uname", "-a"],
272+
"truncated": false,
273+
"pid": 920684,
274+
"uid": 101000,
275+
"gid": 101000,
276+
"comm": "bash"
277+
}
278+
}
279+
}
280+
```
281+
282+
### View logs in AWS EKS
283+
284+
If you're using AWS' Elastic Kubernetes Service, you can
285+
[configure your cluster](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-EKS-logs.html)
286+
to send logs to CloudWatch. This allows you to view the logs for a specific user
287+
or workspace.
288+
289+
To view your logs, go to the CloudWatch dashboard (which is available on the
290+
**Log Insights** tab) and run a query similar to the following:
291+
292+
```text
293+
fields @timestamp, log_processed.fields.cmdline
294+
| sort @timestamp asc
295+
| filter kubernetes.container_name="exectrace"
296+
| filter log_processed.fields.labels.username="zac"
297+
| filter log_processed.fields.labels.workspace_name="code"
298+
```
299+
300+
## Usage considerations
301+
302+
- The sidecar attached to each workspace is a privileged container, so you may
303+
need to review your organization's security policies before enabling this
304+
feature. Enabling workspace process logging does _not_ grant extra privileges
305+
to the workspace container itself, however.
306+
- `exectrace` will log processes from nested Docker containers (including deeply
307+
nested containers) correctly, but Coder does not distinguish between processes
308+
started in the workspace and processes started in a child container in the
309+
logs.
310+
- With `envbox` workspaces, this feature will detect and log startup processes
311+
begun in the outer container (including container initialization processes).
312+
- Because this feature logs **all** processes in the workspace, high levels of
313+
usage (e.g., during a `make` run) will result in an abundance of output in the
314+
sidecar container. Depending on how your Kubernetes cluster is configured, you
315+
may incur extra charges from your cloud provider to store the additional logs.

docs/manifest.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,12 @@
351351
"title": "Provider Authentication",
352352
"description": "Authenticate with provider APIs to provision workspaces",
353353
"path": "./admin/templates/extending-templates/provider-authentication.md"
354+
},
355+
{
356+
"title": "Process Logging",
357+
"description": "Log workspace processes",
358+
"path": "./admin/templates/extending-templates/process-logging.md",
359+
"state": ["enterprise", "premium"]
354360
}
355361
]
356362
},

0 commit comments

Comments
 (0)