Skip to content
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ zed --insecure --endpoint=localhost:50051 --token=averysecretpresharedkey schema

## Where To Go From Here

- Check out the [examples](examples) directory to see how to configure `SpiceDBCluster` for production, including datastore backends, TLS, and Ingress.
- Check out the [examples](examples) directory to see how to configure `SpiceDBCluster` for production, including datastore backends, TLS, Ingress, and operator features like JSON logging.
- Learn how to use SpiceDB via the [docs](https://docs.authzed.com/) and [playground](https://play.authzed.com/).
- Ask questions and join the community in [discord](https://authzed.com/discord).

Expand Down
9 changes: 9 additions & 0 deletions config/crds/authzed.com_spicedbclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ spec:
baseImage:
description: |-
BaseImage specifies the base container image to use for SpiceDB.
This is useful for air-gapped environments or when using a private registry.
The operator will append the appropriate tag based on version/channel.
Must not include a tag or digest - use spec.version or spec.config.image instead.
If not specified, will fall back to the operator's --base-image flag,
then to the imageName defined in the update graph.
type: string
Expand Down Expand Up @@ -244,6 +247,12 @@ spec:
description: Phase is the currently running phase (used for phased
migrations)
type: string
resolvedBaseImage:
description: |-
ResolvedBaseImage is the base image that was resolved for this cluster.
This shows which registry/image the operator is using before appending
the version tag. Useful for debugging alternative registry configurations.
type: string
secretHash:
description: SecretHash is a digest of the last applied secret
type: string
Expand Down
128 changes: 128 additions & 0 deletions examples/alternative-registry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Using Alternative Container Registry

This example demonstrates how to configure the SpiceDB operator to use an alternative container registry instead of the default one.

## Overview

The SpiceDB operator supports specifying a custom base image for SpiceDB containers through the `baseImage` field in the `SpiceDBCluster` spec. This is useful when:

- You need to use a private container registry
- You want to mirror images to your own registry for security or compliance reasons
- You need to use a registry proxy for better performance
- You're running in an air-gapped environment

## Configuration

The image selection follows this precedence order (highest to lowest):

1. `.spec.config.image` with explicit tag/digest (overrides everything)
2. `.spec.baseImage` field (what this example uses)
3. The operator's `--base-image` flag
4. The `imageName` defined in the update graph

**Important:** The `baseImage` field must NOT contain a tag (`:tag`) or digest (`@sha256:...`). The operator will automatically append the appropriate tag based on the `version` or `channel` you specify. If you need to specify an exact image with tag, use `.spec.config.image` instead.

## Example

See [spicedb-cluster.yaml](spicedb-cluster.yaml) for a complete example.

```yaml
apiVersion: authzed.com/v1alpha1
kind: SpiceDBCluster
metadata:
name: example-with-custom-registry
spec:
# Specify your alternative registry here (NO TAG!)
baseImage: "my-registry.company.com/authzed/spicedb"

# The operator will append the appropriate tag based on the version/channel
version: "v1.33.0"

config:
datastoreEngine: postgres
# ... other config

# If using a private registry, use patches to add imagePullSecrets
patches:
- kind: Deployment
patch: |
spec:
template:
spec:
imagePullSecrets:
- name: registry-credentials
```

## How it Works

When you specify a `baseImage`, the operator will:

1. Use your specified registry as the base
2. Append the appropriate tag or digest based on the `version` or `channel` you specify
3. The final image will be: `<baseImage>:<tag>` or `<baseImage>@<digest>`

For example, if you specify:

- `baseImage: "my-registry.company.com/authzed/spicedb"`
- `version: "v1.33.0"`

The operator will use: `my-registry.company.com/authzed/spicedb:v1.33.0`

## Private Registry Authentication

If your alternative registry requires authentication, you need to:

1. Create an image pull secret with your registry credentials:

```bash
kubectl create secret docker-registry registry-credentials \
--docker-server=my-registry.company.com \
--docker-username=YOUR-USERNAME \
--docker-password=YOUR-PASSWORD \
--namespace=spicedb-custom-registry
```

2. Use the `patches` field to inject the image pull secret into the deployment:

```yaml
spec:
patches:
- kind: Deployment
patch: |
spec:
template:
spec:
imagePullSecrets:
- name: registry-credentials
```

## Common Mistakes

### Including a tag in baseImage

**Wrong:**

```yaml
spec:
baseImage: "my-registry.company.com/authzed/spicedb:v1.33.0" # Don't include tag!
```

**Correct:**

```yaml
spec:
baseImage: "my-registry.company.com/authzed/spicedb"
version: "v1.33.0"
```

### Confusing baseImage with config.image

- Use `baseImage` when you want the operator to manage versions via the update graph
- Use `config.image` (with full tag/digest) when you want to bypass the update graph entirely

## Important Notes

- Make sure your Kubernetes nodes can pull from your alternative registry
- If using a private registry, use the `patches` field to configure image pull secrets
- The operator still uses the update graph to determine valid versions and migration paths
- The alternative registry must contain the exact same images as the official registry
58 changes: 58 additions & 0 deletions examples/alternative-registry/spicedb-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
apiVersion: v1
kind: Namespace
metadata:
name: spicedb-custom-registry
---
apiVersion: authzed.com/v1alpha1
kind: SpiceDBCluster
metadata:
name: example-with-custom-registry
namespace: spicedb-custom-registry
spec:
# Use an alternative container registry
# The operator will append the appropriate tag based on version/channel
# NOTE: Do NOT include a tag here - just the registry and image name
baseImage: "my-registry.company.com/authzed/spicedb"

# Specify the version to use
version: "v1.33.0"

# Alternatively, use a channel for automatic updates within that channel
# channel: "stable"

config:
datastoreEngine: postgres
logLevel: info

secretName: spicedb-config

# If using a private registry, use patches to add imagePullSecrets to the deployment
patches:
- kind: Deployment
patch: |
spec:
template:
spec:
imagePullSecrets:
- name: registry-credentials
---
apiVersion: v1
kind: Secret
metadata:
name: spicedb-config
namespace: spicedb-custom-registry
stringData:
datastore_uri: "postgresql://<CHANGE-ME-USERNAME>:<CHANGE-ME-PASSWORD>@<CHANGE-ME-POSTGRES-HOST>:5432/<CHANGE-ME-DATABASE>?sslmode=require"
preshared_key: "<CHANGE-ME-TO-A-VERY-SECRET-PRESHARED-KEY>"
---
# If using a private registry, you may need an image pull secret
apiVersion: v1
kind: Secret
metadata:
name: registry-credentials
namespace: spicedb-custom-registry
type: kubernetes.io/dockerconfigjson
data:
# CHANGE-ME: This is a placeholder - replace with your actual registry credentials
# Generate with: kubectl create secret docker-registry registry-credentials --docker-server=my-registry.company.com --docker-username=YOUR-USERNAME --docker-password=YOUR-PASSWORD --dry-run=client -o yaml
.dockerconfigjson: <CHANGE-ME-BASE64-ENCODED-DOCKER-CONFIG>
89 changes: 89 additions & 0 deletions examples/json-logging/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# JSON Logging for SpiceDB Operator

This example demonstrates how to configure the SpiceDB Operator to output logs in JSON format, which is useful for integration with log aggregation systems like ELK (Elasticsearch, Logstash, Kibana) stack, Splunk, or other structured logging solutions.

## Overview

By default, the SpiceDB Operator uses a text-based log format. However, for production environments where logs need to be parsed and analyzed by log aggregation systems, JSON format is often preferred.

## Configuration

### Using the Command Line Flag

The simplest way to enable JSON logging is by using the `--log-format` flag when starting the operator:

```bash
spicedb-operator run --log-format=json
```

### In Kubernetes Deployment

To enable JSON logging in a Kubernetes deployment, modify the operator's deployment manifest:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spicedb-operator
namespace: spicedb-operator
spec:
template:
spec:
containers:
- name: spicedb-operator
image: authzed/spicedb-operator:latest
args:
- "run"
- "--log-format=json"
# ... other flags
```

## Log Format Comparison

### Text Format (Default)

```text
2024-01-15T10:30:45.123Z INFO controller Reconciling SpiceDBCluster {"namespace": "default", "name": "my-spicedb"}
2024-01-15T10:30:45.456Z INFO controller Created deployment {"namespace": "default", "name": "my-spicedb-spicedb"}
```

### JSON Format

```json
{"level":"info","ts":"2024-01-15T10:30:45.123Z","logger":"controller","msg":"Reconciling SpiceDBCluster","namespace":"default","name":"my-spicedb"}
{"level":"info","ts":"2024-01-15T10:30:45.456Z","logger":"controller","msg":"Created deployment","namespace":"default","name":"my-spicedb-spicedb"}
```

## Integration with ELK Stack

When using JSON logging with the ELK stack:

1. **Filebeat Configuration**: Configure Filebeat to read the operator logs:

```yaml
filebeat.inputs:
- type: container
paths:
- /var/log/containers/spicedb-operator-*.log
processors:
- decode_json_fields:
fields: ["message"]
target: ""
overwrite_keys: true
```

2. **Logstash Pipeline**: No special parsing is needed as the logs are already structured.

3. **Kibana**: You can directly query and visualize the structured log fields.

## Benefits

- **Structured Data**: Each log entry is a valid JSON object with consistent fields
- **Easy Parsing**: No need for complex regular expressions to parse log entries
- **Better Search**: Log aggregation systems can index individual fields for faster searching
- **Standardized Format**: Compatible with most modern logging infrastructure
- **Machine-Readable**: Easier to process logs programmatically for alerting or analysis

## Complete Example

See the [operator-with-json-logging.yaml](operator-with-json-logging.yaml) file for a complete example of deploying the SpiceDB Operator with JSON logging enabled.
Loading
Loading