Skip to content

Commit 6929792

Browse files
matifaliericpaulsenbpmct
authored
docs: add coder-logstream-kube docs and update k8s example template (#8675)
* docs: add kubestream docs and update example template * make fmt * add to template's README * add the seperate page * make fmt * make fmt * add namespace to deployment resource * fmt * add screenshots * link docs in template * Add remaining examples * enable deployments requirement * Update deployment-logs.md * rewording * fix spelling * how? * cleanup * Update docs/platforms/kubernetes/deployment-logs.md Co-authored-by: Ben Potter <ben@coder.com> * suggestions * use online link * refine --------- Co-authored-by: Eric <ericpaulsen@coder.com> Co-authored-by: Ben Potter <ben@coder.com>
1 parent b7ced94 commit 6929792

8 files changed

+171
-62
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Kubernetes event logs
2+
3+
To stream Kubernetes events into your workspace startup logs, you can use Coder's [`coder-logstream-kube`](https://github.com/coder/coder-logstream-kube) tool. `coder-logstream-kube` provides useful information about the workspace pod or deployment, such as:
4+
5+
- Causes of pod provisioning failures, or why a pod is stuck in a pending state.
6+
- Visibility into when pods are OOMKilled, or when they are evicted.
7+
8+
## Prerequisites
9+
10+
`coder-logstream-kube` works best with the [`kubernetes_deployment`](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) Terraform resource, which requires the `coder` service account to have permission to create deployments. For example, if you use [Helm](https://coder.com/docs/v2/latest/install/kubernetes#install-coder-with-helm) to install Coder, you should set `coder.serviceAccount.enableDeployments=true` in your `values.yaml`
11+
12+
```diff
13+
coder:
14+
serviceAccount:
15+
workspacePerms: true
16+
- enableDeployments: false
17+
+ enableDeployments: true
18+
annotations: {}
19+
name: coder
20+
```
21+
22+
> Note: This is only required for Coder versions < 0.28.0, as this will be the default value for Coder versions >= 0.28.0
23+
24+
## Installation
25+
26+
Install the `coder-kubestream-logs` helm chart on the cluster where the deployment is running.
27+
28+
```shell
29+
helm repo add coder-logstream-kube https://helm.coder.com/logstream-kube
30+
helm install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
31+
--namespace coder \
32+
--set url=<your-coder-url-including-http-or-https>
33+
```
34+
35+
## Example logs
36+
37+
Here is an example of the logs you can expect to see in the workspace startup logs:
38+
39+
### Normal pod deployment
40+
41+
![normal pod deployment](./coder-logstream-kube-logs-normal.png)
42+
43+
### Wrong image
44+
45+
![Wrong image name](./coder-logstream-kube-logs-wrong-image.png)
46+
47+
### Kubernetes quota exceeded
48+
49+
![Kubernetes quota exceeded](./coder-logstream-kube-logs-quota-exceeded.png)
50+
51+
### Pod crash loop
52+
53+
![Pod crash loop](./coder-logstream-kube-logs-pod-crashed.png)
54+
55+
## How it works
56+
57+
Kubernetes provides an [informers](https://pkg.go.dev/k8s.io/client-go/informers) API that streams pod and event data from the API server.
58+
59+
coder-logstream-kube listens for pod creation events with containers that have the CODER_AGENT_TOKEN environment variable set. All pod events are streamed as logs to the Coder API using the agent token for authentication. For more details, see the [coder-logstream-kube](https://github.com/coder/coder-logstream-kube) repository.

docs/platforms/kubernetes/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ From the dashboard, import the Kubernetes starter template:
1818

1919
In the next screen, set the following template variables:
2020

21-
- use_kubeconfig: `false` (The ServiceAccount will authorize Coder to create pods on your cluster)
21+
- `use_kubeconfig`: `false` (The ServiceAccount will authorize Coder to create pods on your cluster)
2222
- `namespace`: `coder` (or whatever namespace you deployed Coder on)
2323

2424
![Variables for Kubernetes template](../../images/platforms/kubernetes/template-variables.png)

examples/templates/kubernetes/README.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,23 @@ icon: /icon/k8s.png
77

88
# Getting started
99

10-
This template creates a pod running the `codercom/enterprise-base:ubuntu` image.
10+
This template creates a deplyment running the `codercom/enterprise-base:ubuntu` image.
11+
12+
## Prerequisites
13+
14+
This template uses [`kubernetes_deployment`](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment) terraform resource, which requires the `coder` service account to have permission to create deploymnets. For example if you are using [helm](https://coder.com/docs/v2/latest/install/kubernetes#install-coder-with-helm) to install Coder, you should set `coder.serviceAccount.enableDeployments=true` in your `values.yaml`
15+
16+
```diff
17+
coder:
18+
serviceAccount:
19+
workspacePerms: true
20+
- enableDeployments: false
21+
+ enableDeployments: true
22+
annotations: {}
23+
name: coder
24+
```
25+
26+
> Note: This is only required for Coder versions < 0.28.0, as this will be the default value for Coder versions >= 0.28.0
1127
1228
## Authentication
1329

@@ -62,7 +78,7 @@ You may want to deploy workspaces on a cluster outside of the Coder control plan
6278

6379
## Namespace
6480

65-
The target namespace in which the pod will be deployed is defined via the `coder_workspace`
81+
The target namespace in which the deployment will be deployed is defined via the `coder_workspace`
6682
variable. The namespace must exist prior to creating workspaces.
6783

6884
## Persistence
@@ -96,3 +112,16 @@ resource "coder_agent" "main" {
96112
`code-server` is installed via the `startup_script` argument in the `coder_agent`
97113
resource block. The `coder_app` resource is defined to access `code-server` through
98114
the dashboard UI over `localhost:13337`.
115+
116+
## Deployment logs
117+
118+
To stream kubernetes pods events from the deployment, you can use Coder's [`coder-logstream-kube`](https://github.com/coder/coder-logstream-kube) tool. This can stream logs from the deployment to Coder's workspace startup logs. You just need to install the `coder-logstream-kube` helm chart on the cluster where the deployment is running.
119+
120+
```shell
121+
helm repo add coder-logstream-kube https://helm.coder.com/logstream-kube
122+
helm install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
123+
--namespace coder \
124+
--set url=<your-coder-url-including-http-or-https>
125+
```
126+
127+
For detailed instructions, see [Deployment logs](https://coder.com/docs/v2/latest/platforms/kubernetes/deployment-logs)

examples/templates/kubernetes/main.tf

Lines changed: 80 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ terraform {
22
required_providers {
33
coder = {
44
source = "coder/coder"
5-
version = "~> 0.7.0"
5+
version = "~> 0.11.0"
66
}
77
kubernetes = {
88
source = "hashicorp/kubernetes"
9-
version = "~> 2.18"
9+
version = "~> 2.22"
1010
}
1111
}
1212
}
@@ -198,7 +198,7 @@ resource "kubernetes_persistent_volume_claim" "home" {
198198
"app.kubernetes.io/name" = "coder-pvc"
199199
"app.kubernetes.io/instance" = "coder-pvc-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
200200
"app.kubernetes.io/part-of" = "coder"
201-
// Coder specific labels.
201+
//Coder-specific labels.
202202
"com.coder.resource" = "true"
203203
"com.coder.workspace.id" = data.coder_workspace.me.id
204204
"com.coder.workspace.name" = data.coder_workspace.me.name
@@ -220,82 +220,103 @@ resource "kubernetes_persistent_volume_claim" "home" {
220220
}
221221
}
222222

223-
resource "kubernetes_pod" "main" {
223+
resource "kubernetes_deployment" "main" {
224224
count = data.coder_workspace.me.start_count
225+
depends_on = [
226+
kubernetes_persistent_volume_claim.home
227+
]
228+
wait_for_rollout = false
225229
metadata {
226230
name = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
227231
namespace = var.namespace
228232
labels = {
229233
"app.kubernetes.io/name" = "coder-workspace"
230234
"app.kubernetes.io/instance" = "coder-workspace-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
231235
"app.kubernetes.io/part-of" = "coder"
232-
// Coder specific labels.
233-
"com.coder.resource" = "true"
234-
"com.coder.workspace.id" = data.coder_workspace.me.id
235-
"com.coder.workspace.name" = data.coder_workspace.me.name
236-
"com.coder.user.id" = data.coder_workspace.me.owner_id
237-
"com.coder.user.username" = data.coder_workspace.me.owner
236+
"com.coder.resource" = "true"
237+
"com.coder.workspace.id" = data.coder_workspace.me.id
238+
"com.coder.workspace.name" = data.coder_workspace.me.name
239+
"com.coder.user.id" = data.coder_workspace.me.owner_id
240+
"com.coder.user.username" = data.coder_workspace.me.owner
238241
}
239242
annotations = {
240243
"com.coder.user.email" = data.coder_workspace.me.owner_email
241244
}
242245
}
246+
243247
spec {
244-
security_context {
245-
run_as_user = "1000"
246-
fs_group = "1000"
247-
}
248-
container {
249-
name = "dev"
250-
image = "codercom/enterprise-base:ubuntu"
251-
image_pull_policy = "Always"
252-
command = ["sh", "-c", coder_agent.main.init_script]
253-
security_context {
254-
run_as_user = "1000"
255-
}
256-
env {
257-
name = "CODER_AGENT_TOKEN"
258-
value = coder_agent.main.token
259-
}
260-
resources {
261-
requests = {
262-
"cpu" = "250m"
263-
"memory" = "512Mi"
264-
}
265-
limits = {
266-
"cpu" = "${data.coder_parameter.cpu.value}"
267-
"memory" = "${data.coder_parameter.memory.value}Gi"
268-
}
269-
}
270-
volume_mount {
271-
mount_path = "/home/coder"
272-
name = "home"
273-
read_only = false
248+
# replicas = data.coder_workspace.me.start_count
249+
replicas = 1
250+
selector {
251+
match_labels = {
252+
"app.kubernetes.io/name" = "coder-workspace"
274253
}
275254
}
276255

277-
volume {
278-
name = "home"
279-
persistent_volume_claim {
280-
claim_name = kubernetes_persistent_volume_claim.home.metadata.0.name
281-
read_only = false
256+
template {
257+
metadata {
258+
labels = {
259+
"app.kubernetes.io/name" = "coder-workspace"
260+
}
282261
}
283-
}
262+
spec {
263+
security_context {
264+
run_as_user = 1000
265+
fs_group = 1000
266+
}
267+
268+
container {
269+
name = "dev"
270+
image = "codercom/enterprise-base:ubuntu"
271+
image_pull_policy = "Always"
272+
command = ["sh", "-c", coder_agent.main.init_script]
273+
security_context {
274+
run_as_user = "1000"
275+
}
276+
env {
277+
name = "CODER_AGENT_TOKEN"
278+
value = coder_agent.main.token
279+
}
280+
resources {
281+
requests = {
282+
"cpu" = "250m"
283+
"memory" = "512Mi"
284+
}
285+
limits = {
286+
"cpu" = "${data.coder_parameter.cpu.value}"
287+
"memory" = "${data.coder_parameter.memory.value}Gi"
288+
}
289+
}
290+
volume_mount {
291+
mount_path = "/home/coder"
292+
name = "home"
293+
read_only = false
294+
}
295+
}
284296

297+
volume {
298+
name = "home"
299+
persistent_volume_claim {
300+
claim_name = kubernetes_persistent_volume_claim.home.metadata.0.name
301+
read_only = false
302+
}
303+
}
285304

286-
affinity {
287-
pod_anti_affinity {
288-
// This affinity attempts to spread out all workspace pods evenly across
289-
// nodes.
290-
preferred_during_scheduling_ignored_during_execution {
291-
weight = 1
292-
pod_affinity_term {
293-
topology_key = "kubernetes.io/hostname"
294-
label_selector {
295-
match_expressions {
296-
key = "app.kubernetes.io/name"
297-
operator = "In"
298-
values = ["coder-workspace"]
305+
affinity {
306+
// This affinity attempts to spread out all workspace pods evenly across
307+
// nodes.
308+
pod_anti_affinity {
309+
preferred_during_scheduling_ignored_during_execution {
310+
weight = 1
311+
pod_affinity_term {
312+
topology_key = "kubernetes.io/hostname"
313+
label_selector {
314+
match_expressions {
315+
key = "app.kubernetes.io/name"
316+
operator = "In"
317+
values = ["coder-workspace"]
318+
}
319+
}
299320
}
300321
}
301322
}

0 commit comments

Comments
 (0)