# ScyllaClusters

## Introduction

[ScyllaCluster](https://operator.docs.scylladb.com/v1.18/api-reference/groups/scylla.scylladb.com/scyllaclusters.md) defines a ScyllaDB **datacenter** and manages the racks within.
This section aims to make you familiar with how it looks like and how to perform some of the basic configuration or accessing the APIs.
By no means is this a complete description of what it can do. Please consult our [generated API reference](https://operator.docs.scylladb.com/v1.18/api-reference/groups/scylla.scylladb.com/scyllaclusters.md) for a complete list of options.

Note that the Kubernetes clusters are only a regional concept, availability-wise they map into a ScyllaDB datacenter.
To deploy a ScyllaDB cluster with multiple datacenters use our multi datacenter resource [ScyllaDBCluster](https://operator.docs.scylladb.com/v1.18/resources/scylladbclusters/scylladbclusters.md), or combine multiple Kubernetes clusters, each running a [ScyllaCluster](https://operator.docs.scylladb.com/v1.18/api-reference/groups/scylla.scylladb.com/scyllaclusters.md),
To learn more about **manual** multi-dc deployments using ScyllaCluster resource, please see [the dedicated multi-datacenter guide](https://operator.docs.scylladb.com/v1.18/resources/scyllaclusters/multidc/multidc.md).

## Creating a ScyllaCluster

Before we go and create the ScyllaCluster, we’ll first create our ScyllaDB config file that we’ll reference later in the ScyllaCluster definition.

```bash
kubectl apply --server-side -f=- <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: scylladb-config
data:
  scylla.yaml: |
    authenticator: PasswordAuthenticator
    authorizer: CassandraAuthorizer
    # Other options
EOF
```

#### NOTE
Some of the ScyllaDB config is also generated by the Scylla Operator based on your ScyllaCluster definition.
While you shall not define conflicting options here (Scylla Operator config wins), we still want to give you a reasonable control to fine tune some ScyllaDB knobs.
IOW, please stay away from touching networking, listen or published addresses and so on, but feel free to tune buffer sizes and such.

Now we can create a simple ScyllaCluster to get ScyllaDB running.

#### WARNING
To ensure high availability and fault tolerance in ScyllaDB, it is crucial to **spread your nodes across multiple racks or availability zones**. As a general rule of thumb, you should use **as many racks as your desired replication factor**.

For example, if your replication factor is `3`, deploy your nodes across **3 different racks or availability zones**. This minimizes the risk of data loss and ensures your cluster remains available even if an entire rack or zone fails.

```bash
kubectl apply --server-side -f=- <<EOF
apiVersion: scylla.scylladb.com/v1
kind: ScyllaCluster
metadata:
  name: scylladb
spec:
  repository: docker.io/scylladb/scylla
  version: 2025.1.5
  agentVersion: 3.5.1
  developerMode: false
  automaticOrphanedNodeCleanup: true
  sysctls:
  - fs.aio-max-nr=30000000
  datacenter:
    name: us-east-1
    racks:
    - name: us-east-1a
      members: 1
      scyllaConfig: scylladb-config
      storage:
        capacity: 100Gi
        storageClassName: scylladb-local-xfs
      resources:
        requests:
          cpu: 1
          memory: 8Gi
        limits:
          cpu: 1
          memory: 8Gi
      placement:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - us-east-1a 
              - key: scylla.scylladb.com/node-type
                operator: In
                values:
                - scylla
        tolerations:
        - key: scylla-operator.scylladb.com/dedicated
          operator: Equal
          value: scyllaclusters
          effect: NoSchedule
    - name: us-east-1b
      members: 1
      scyllaConfig: scylladb-config
      storage:
        capacity: 100Gi
        storageClassName: scylladb-local-xfs
      resources:
        requests:
          cpu: 1
          memory: 8Gi
        limits:
          cpu: 1
          memory: 8Gi
      placement:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - us-east-1b
              - key: scylla.scylladb.com/node-type
                operator: In
                values:
                - scylla
        tolerations:
        - key: scylla-operator.scylladb.com/dedicated
          operator: Equal
          value: scyllaclusters
          effect: NoSchedule
    - name: us-east-1c
      members: 1
      scyllaConfig: scylladb-config
      storage:
        capacity: 100Gi
        storageClassName: scylladb-local-xfs
      resources:
        requests:
          cpu: 1
          memory: 8Gi
        limits:
          cpu: 1
          memory: 8Gi
      placement:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - us-east-1c
              - key: scylla.scylladb.com/node-type
                operator: In
                values:
                - scylla
        tolerations:
        - key: scylla-operator.scylladb.com/dedicated
          operator: Equal
          value: scyllaclusters
          effect: NoSchedule
EOF
```

#### NOTE
Values in these examples are only illustratory.
You should always adjust the resources and storage capacity depending on your needs or the size and the type of your Kubernetes nodes.
Similarly, the tolerations will differ depending on how and whether you set up dedicated node pools, or the placement if you want to set affinity for your rack to an availability zone or a failure domain.

#### NOTE
Scylla Operator works with both ScyllaDB Open Source and ScyllaDB Enterprise.
You only have to adjust the [repository and tag fields](https://operator.docs.scylladb.com/v1.18/api-reference/groups/scylla.scylladb.com/scyllaclusters.md#api-scylla-scylladb-com-scyllaclusters-v1-spec) for each ScyllaCluster.

In addition to it, if you want to use tuning from the Enterprise repository, you have to adjust [**scyllaUtilsImage** on the global ScyllaOperatorConfig/cluster](https://operator.docs.scylladb.com/v1.18/resources/scyllaoperatorconfigs.md#tuning-with-scylladb-enterprise).

```bash
apiVersion: scylla.scylladb.com/v1
kind: ScyllaCluster
metadata:
  name: scylladb
spec:
  repository: docker.io/scylladb/scylla-enterprise
  version: 2025.1.5
  # ...
EOF
```

```bash
# Wait for it to deploy.
kubectl wait --for='condition=Progressing=False' scyllacluster.scylla.scylladb.com/scylladb
kubectl wait --for='condition=Degraded=False' scyllacluster.scylla.scylladb.com/scylladb
kubectl wait --for='condition=Available=True' scyllacluster.scylla.scylladb.com/scylladb
```

## Forcing a rolling restart

When you change a ScyllaDB config option that’s not live reloaded by ScyllaDB, or want to trigger a rolling restart for a different reason, ScyllaCluster allows triggering the rolling restarts declaratively by changing `ScyllaCluster.spec.forceRedeploymentReason` to any other value. This will trigger a rolling restart of all ScyllaDB nodes in sequence, always respecting the [PodDistruptionsBudget](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets) and keeping the cluster available.

## Spreading racks over availability zones

ScyllaCluster give you the freedom to chose how you want to spread you rack over your Kubernetes nodes with generic [placement options](https://operator.docs.scylladb.com/v1.18/api-reference/groups/scylla.scylladb.com/scyllaclusters.md#api-scylla-scylladb-com-scyllaclusters-v1-spec-datacenter-racks-placement).
Here is a quick example of how you’d use them to spread your racks across different availability zone:

#### WARNING
To ensure high availability and fault tolerance in ScyllaDB, it is crucial to **spread your nodes across multiple racks or availability zones**. As a general rule of thumb, you should use **as many racks as your desired replication factor**.

For example, if your replication factor is `3`, deploy your nodes across **3 different racks or availability zones**. This minimizes the risk of data loss and ensures your cluster remains available even if an entire rack or zone fails.

### GKE

```yaml
spec:
  datacenter:
    name: <dc_name>
    racks:
    - name: <rack_name>
      placement:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: failure-domain.beta.kubernetes.io/zone
                operator: In
                values:
                - <gcp_zone>
```

### EKS

```yaml
spec:
  datacenter:
    name: <dc_name>
    racks:
    - name: <rack_name>
      placement:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - <aws_zone>
```

## Next steps

To follow up with other advanced topics, see [the section index for options](https://operator.docs.scylladb.com/v1.18/resources/scyllaclusters/index.md).
