Skip to content

Add support for multiple namespaces #107

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 49 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# coder-logstream-kube

[![discord](https://img.shields.io/discord/747933592273027093?label=discord)](https://discord.gg/coder)
[![release](https://img.shields.io/github/v/tag/coder/coder-logstream-kube)](https://github.com/coder/envbuilder/pkgs/container/coder-logstream-kube)
[![godoc](https://pkg.go.dev/badge/github.com/coder/coder-logstream-kube.svg)](https://pkg.go.dev/github.com/coder/coder-logstream-kube)
[![Go Reference](https://pkg.go.dev/badge/github.com/coder/coder-logstream-kube.svg)](https://pkg.go.dev/github.com/coder/coder-logstream-kube)
[![license](https://img.shields.io/github/license/coder/coder-logstream-kube)](./LICENSE)

Stream Kubernetes Pod events to the Coder startup logs.

- Easily determine the reason for a pod provision failure, or why a pod is stuck in a pending state.
- Visibility into when pods are OOMKilled, or when they are evicted.
- Filter by namespace, field selector, and label selector to reduce Kubernetes API load.
- Support for watching multiple namespaces or all namespaces cluster-wide.

![Log Stream](./scripts/demo.png)

Expand All @@ -24,6 +23,36 @@ helm install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
--set url=<your-coder-url-including-http-or-https>
```

### Multi-Namespace Support

By default, `coder-logstream-kube` watches pods in the namespace where it's deployed. You can configure it to watch multiple namespaces or all namespaces:

#### Watch specific namespaces
```console
helm install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
--namespace coder \
--set url=<your-coder-url> \
--set namespaces="namespace1,namespace2,namespace3"
```

#### Watch all namespaces
```console
helm install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
--namespace coder \
--set url=<your-coder-url> \
--set namespaces=""
```

When watching multiple namespaces or all namespaces, the chart automatically creates ClusterRole and ClusterRoleBinding resources instead of namespace-scoped Role and RoleBinding.

### Environment Variable Configuration

You can also configure namespaces using the `CODER_NAMESPACE` environment variable:

- Single namespace: `CODER_NAMESPACE=my-namespace`
- Multiple namespaces: `CODER_NAMESPACE=ns1,ns2,ns3`
- All namespaces: `CODER_NAMESPACE=""` (empty string)

> **Note**
> For additional customization (such as customizing the image, pull secrets, annotations, etc.), you can use the
> [values.yaml](helm/values.yaml) file directly.
Expand All @@ -46,7 +75,24 @@ Kubernetes provides an [informers](https://pkg.go.dev/k8s.io/client-go/informers

`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.

When configured for multiple namespaces, the application creates separate informers for each specified namespace. When configured to watch all namespaces (empty namespace list), it uses cluster-wide informers.

## Custom Certificates

- [`SSL_CERT_FILE`](https://go.dev/src/crypto/x509/root_unix.go#L19): Specifies the path to an SSL certificate.
- [`SSL_CERT_DIR`](https://go.dev/src/crypto/x509/root_unix.go#L25): Identifies which directory to check for SSL certificate files.

## RBAC Permissions

The required permissions depend on the scope of namespaces being watched:

### Single Namespace (Role/RoleBinding)
When watching a single namespace, the application uses namespace-scoped permissions:
- `pods`: get, watch, list
- `events`: get, watch, list
- `replicasets`: get, watch, list

### Multiple Namespaces or All Namespaces (ClusterRole/ClusterRoleBinding)
When watching multiple namespaces or all namespaces, the application requires cluster-wide permissions with the same resource access but across all namespaces.

The Helm chart automatically determines which type of RBAC resources to create based on your configuration.
58 changes: 51 additions & 7 deletions helm/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
{{/*
Determine if cluster-wide permissions are needed.
This happens when:
1. namespaces is explicitly set to empty string (watch all namespaces)
2. namespaces contains multiple comma-separated values
3. rbac.clusterWide is explicitly set to true
*/}}
{{- $namespaces := .Values.namespaces | default .Release.Namespace -}}
{{- $namespacesCount := 0 -}}
{{- if eq $namespaces "" -}}
{{- $namespacesCount = 0 -}}
{{- else -}}
{{- $namespacesCount = len (splitList "," $namespaces) -}}
{{- end -}}
{{- $useClusterWide := or .Values.rbac.clusterWide (eq $namespaces "") (gt $namespacesCount 1) -}}

{{- if $useClusterWide }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
kind: ClusterRole
metadata:
name: coder-logstream-kube-role
name: {{ .Release.Name }}-coder-logstream-kube-role
rules:
- apiGroups: [""]
resources: ["pods", "events"]
Expand All @@ -10,12 +27,30 @@ rules:
resources: ["replicasets", "events"]
verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ .Release.Name }}-coder-logstream-kube-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ .Release.Name }}-coder-logstream-kube-role
subjects:
- kind: ServiceAccount
name: {{ .Values.serviceAccount.name | quote }}
annotations: {{ toYaml .Values.serviceAccount.annotations | nindent 4 }}
labels: {{ toYaml .Values.serviceAccount.labels | nindent 4 }}
namespace: {{ .Release.Namespace }}
{{- else }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: coder-logstream-kube-role
rules:
- apiGroups: [""]
resources: ["pods", "events"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
resources: ["replicasets", "events"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
Expand All @@ -28,6 +63,14 @@ roleRef:
subjects:
- kind: ServiceAccount
name: {{ .Values.serviceAccount.name | quote }}
{{- end }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.serviceAccount.name | quote }}
annotations: {{ toYaml .Values.serviceAccount.annotations | nindent 4 }}
labels: {{ toYaml .Values.serviceAccount.labels | nindent 4 }}
---
apiVersion: apps/v1
kind: Deployment
Expand Down Expand Up @@ -76,7 +119,7 @@ spec:
- name: CODER_URL
value: {{ .Values.url }}
- name: CODER_NAMESPACE
value: {{ .Values.namespace | default .Release.Namespace }}
value: {{ $namespaces }}
{{- if .Values.image.sslCertFile }}
- name: SSL_CERT_FILE
value: {{ .Values.image.sslCertFile }}
Expand All @@ -95,3 +138,4 @@ spec:
{{- if .Values.volumes }}
volumes: {{- toYaml .Values.volumes | nindent 8 }}
{{- end }}

15 changes: 9 additions & 6 deletions helm/values.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# url -- The URL of your Coder deployment. Must prefix with http or https
url: ""

# namespace -- The namespace to searching for Pods within.
# namespaces -- Comma-separated list of namespaces to watch for Pods.
# If unspecified, this defaults to the Helm namespace.
namespace: ""
# If set to empty string (""), watches all namespaces (requires cluster-wide permissions).
namespaces: ""

# volumes -- A list of extra volumes to add to the coder-logstream pod.
volumes:
Expand Down Expand Up @@ -46,6 +46,12 @@ serviceAccount:
# coder.serviceAccount.name -- The service account name
name: coder-logstream-kube

# rbac -- RBAC configuration
rbac:
# rbac.clusterWide -- Whether to use cluster-wide permissions (ClusterRole/ClusterRoleBinding).
# This is automatically set to true when namespaces is empty or contains multiple namespaces.
clusterWide: false

# resources -- The resources to request for the Deployment. These are optional
# and are not set by default.
resources:
Expand Down Expand Up @@ -98,6 +104,3 @@ securityContext: {}
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# seccompProfile:
# type: RuntimeDefault
Loading