diff --git a/docs/server/kubernetes-operator/getting-started/resource-types.md b/docs/server/kubernetes-operator/getting-started/resource-types.md index b7cb74b6..18527874 100644 --- a/docs/server/kubernetes-operator/getting-started/resource-types.md +++ b/docs/server/kubernetes-operator/getting-started/resource-types.md @@ -13,37 +13,60 @@ This resource type is used to define a database deployment. ### API -| Field | Required | Description | -|---------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------| -| `replicas` _integer_ | Yes | Number of nodes in a database cluster (1 or 3) | -| `image` _string_ | Yes | KurrentDB container image URL | -| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core)_ | No | Database container resource limits and requests | -| `storage` _[PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#persistentvolumeclaimspec-v1-core)_ | Yes | Persistent volume claim settings for the underlying data volume | -| `network` _[KurrentDbNetwork](#kurrentdbnetwork)_ | Yes | Defines the network configuration to use with the database | -| `configuration` _yaml_ | No | Additional configuration to use with the database | -| `sourceBackup` _string_ | No | Backup name to restore a cluster from | -| `security` _[KurrentDbSecurity](#kurrentdbecurity)_ | No | Security configuration to use for the database. This is optional, if not specified the cluster will be created without security enabled. | -| `licenseSecret` _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#secret-v1-core)_ | No | A secret that contains the Enterprise license for the database | - -#### KurrentDbNetwork - -| Field | Required | Description | -|------------------------------------------------------------------|----------|--------------------------------------------------------------------------------| -| `domain` _string_ | Yes | Domain used for external DNS e.g. advertised address exposed in the gossip state | -| `loadBalancer` _[KurrentDbLoadBalancer](#kurrentdbloadbalancer)_ | Yes | Defines a load balancer to use with the database | - -#### KurrentDbLoadBalancer - -| Field | Required | Description | -|---------------------|----------|----------------------------------------------------------------| -| `enabled` _boolean_ | Yes | Determines if a load balancer should be deployed for each node | -| `allowedIps` _string array_ | No | List of IP ranges allowed by the load balancer (default will allow all access) | - -#### KurrentDbSecurity +| Field | Required | Description | +|---------------------------------------------------------------------------------------------------------------------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------| +| `replicas` _integer_ | Yes | Number of nodes in a database cluster (1 or 3) | +| `image` _string_ | Yes | KurrentDB container image URL | +| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core)_ | No | Database container resource limits and requests | +| `storage` _[PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#persistentvolumeclaimspec-v1-core)_ | Yes | Persistent volume claim settings for the underlying data volume | +| `network` _[KurrentDBNetwork](#kurrentdbnetwork)_ | Yes | Defines the network configuration to use with the database | +| `configuration` _yaml_ | No | Additional configuration to use with the database | +| `sourceBackup` _string_ | No | Backup name to restore a cluster from | +| `security` _[KurrentDBSecurity](#kurrentdbecurity)_ | No | Security configuration to use for the database. This is optional, if not specified the cluster will be created without security enabled. | +| `licenseSecret` _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#secret-v1-core)_ | No | A secret that contains the Enterprise license for the database | +| `constraints` _[KurrentDBConstraints](#kurrentdbconstraints)_ | No | Scheduling constraints for the Kurrent DB pod. | +| `readOnlyReplias` _[KurrentDBReadOnlyReplicasSpec](#kurrentdbreadonlyreplicasspec)_ | No | Read-only replica configuration the Kurrent DB Cluster. | + +#### KurrentDBReadOnlyReplicasSpec + +Other than `replicas`, each of the fields in `KurrentDBReadOnlyReplicasSpec` default to the corresponding values from the main KurrentDBSpec. + +| Field | Required | Description | +|---------------------------------------------------------------------------------------------------------------------------------------------|----------|------------------------------------------------------------------| +| `replicas` _integer_ | No | Number of read-only replicas in the cluster. Defaults to zero. | +| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#resourcerequirements-v1-core)_ | No | Database container resource limits and requests. | +| `storage` _[PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#persistentvolumeclaimspec-v1-core)_ | No | Persistent volume claim settings for the underlying data volume. | +| `configuration` _yaml_ | No | Additional configuration to use with the database. | +| `constraints` _[KurrentDBConstraints](#kurrentdbconstraints)_ | No | Scheduling constraints for the Kurrent DB pod. | + +#### KurrentDBConstraints + +| Field | Required | Description | +|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-------------------------------------------------------------------------------------------| +| `nodeSelector` _yaml_ | No | Identifies nodes that the Kurrent DB may consider during scheduling. | +| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#affinity-v1-core)_ | No | The node affinity, pod affinity, and pod anti-affinity for scheduling the Kurrent DB pod. | +| `Tolerations` _list of [Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#toleration-v1-core)_ | No | The tolerations for scheduling the Kurrent DB pod. | +| `TopologySpreadConstraints` _list of [TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#topologyspreadconstraint-v1-core)_ | No | The topology spread constraints for scheduling the Kurrent DB pod. | + +#### KurrentDBNetwork + +| Field | Required | Description | +|------------------------------------------------------------------|----------|----------------------------------------------------------------------------------| +| `domain` _string_ | Yes | Domain used for external DNS e.g. advertised address exposed in the gossip state | +| `loadBalancer` _[KurrentDBLoadBalancer](#kurrentdbloadbalancer)_ | Yes | Defines a load balancer to use with the database | + +#### KurrentDBLoadBalancer + +| Field | Required | Description | +|------------------------------|----------|--------------------------------------------------------------------------------| +| `enabled` _boolean_ | Yes | Determines if a load balancer should be deployed for each node | +| `allowedIps` _string array_ | No | List of IP ranges allowed by the load balancer (default will allow all access) | + +#### KurrentDBSecurity | Field | Required | Description | |------------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------| -| `certificateSubjectName` _string_ | No | Subject name used in the TLS certificate (this maps directly to the database property `CertificateSubjectName`) | +| `certificateSubjectName` _string_ | No | Subject name used in the TLS certificate (this maps directly to the database property `CertificateSubjectName`) | | `certificateReservedNodeCommonName` _string_ | No | Common name for the TLS certificate (this maps directly to the database property `CertificateReservedNodeCommonName`) | | `certificateAuthoritySecret` _[CertificateSecret](#certificatesecret)_ | No | Secret containing the CA TLS certificate | | `certificateSecret` _[CertificateSecret](#certificatesecret)_ | Yes | Secret containing the TLS certificate to use | @@ -59,7 +82,7 @@ This resource type is used to define a database deployment. ## KurrentDBBackup -This resource type is used to define a backup for an existing database deployment. +This resource type is used to define a backup for an existing database deployment. :::important Resources of this type must be created within the same namespace as the target database cluster to backup. @@ -67,8 +90,8 @@ Resources of this type must be created within the same namespace as the target d ### API -| Field | Required | Description | -|------------------------|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| -| `clusterName` _string_ | Yes | Name of the source database cluster | -| `nodeName` _string_ | No | Specific node name within the database cluster to use as the backup. If this is not specified, the leader will be picked as the source. | - | `volumeSnapshotClassName` _string_ | Yes | The name of the underlying volume snapshot class to use. | \ No newline at end of file +| Field | Required | Description | +|------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------| +| `clusterName` _string_ | Yes | Name of the source database cluster | +| `nodeName` _string_ | No | Specific node name within the database cluster to use as the backup. If this is not specified, the leader will be picked as the source. | +| `volumeSnapshotClassName` _string_ | Yes | The name of the underlying volume snapshot class to use. | diff --git a/docs/server/kubernetes-operator/operations/database-deployment.md b/docs/server/kubernetes-operator/operations/database-deployment.md index e4b6334b..65c5c920 100644 --- a/docs/server/kubernetes-operator/operations/database-deployment.md +++ b/docs/server/kubernetes-operator/operations/database-deployment.md @@ -118,6 +118,65 @@ kubectl apply -f cluster.yaml Once deployed, navigate to the [Viewing Deployments](#viewing-deployments) section. +## Three Node Insecure Cluster with Two Read-Only Replicas + +Note that read-only replicas are only supported by KurrentDB in clustered configurations, that is, +with multiple primary nodes. + +The following `KurrentDB` resource type defines a three node cluster with the following properties: +- The database will be deployed in the `kurrent` namespace with the name `kurrentdb-cluster` +- Security is not enabled +- KurrentDB version 25.0.0 will be used +- 1vcpu will be requested as the minimum (upper bound is unlimited) per node +- 1gb of memory will be used per primary node, but read-only replicas will have 2gb of memory +- 512mb of storage will be allocated for the data disk per node +- The main KurrentDB instances that are provisioned will be exposed as `kurrentdb-{idx}.kurrentdb-cluster.kurrent.test` +- The read-only replicas that are provisioned will be exposed as `kurrentdb-replica-{idx}.kurrentdb-cluster.kurrent.test` + +```yaml +apiVersion: kubernetes.kurrent.io/v1 +kind: KurrentDB +metadata: + name: kurrentdb-cluster + namespace: kurrent +spec: + replicas: 3 + image: docker.kurrent.io/kurrent-latest/kurrentdb:25.0.0 + resources: + requests: + cpu: 1000m + memory: 1Gi + storage: + volumeMode: "Filesystem" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 512Mi + network: + domain: kurrentdb-cluster.kurrent.test + loadBalancer: + enabled: true + readOnlyReplicas: + replicas: 2 + resources: + requests: + cpu: 1000m + memory: 1Gi + +``` + +This can be deployed using the following steps: +- Copy the YAML snippet above to a file called `cluster.yaml` +- Ensure that the `kurrent` namespace has been created +- Run the following command: + +```bash +kubectl apply -f cluster.yaml +``` + +Once deployed, navigate to the [Viewing Deployments](#viewing-deployments) section. + ## Single Node Secure Cluster (using self-signed certificates) The following `KurrentDB` resource type defines a single node cluster with the following properties: @@ -152,6 +211,8 @@ spec: dnsNames: - '*.kurrentdb-cluster.kurrent.svc.cluster.local' - '*.kurrentdb-cluster.kurrent.test' + - '*.kurrentdb-cluster-replica.kurrent.svc.cluster.local' + - '*.kurrentdb-cluster-replica.kurrent.test' privateKey: algorithm: RSA encoding: PKCS1 @@ -240,6 +301,8 @@ spec: dnsNames: - '*.kurrentdb-cluster.kurrent.svc.cluster.local' - '*.kurrentdb-cluster.kurrent.test' + - '*.kurrentdb-cluster-replica.kurrent.svc.cluster.local' + - '*.kurrentdb-cluster-replica.kurrent.test' privateKey: algorithm: RSA encoding: PKCS1 @@ -328,6 +391,8 @@ spec: dnsNames: - '*.kurrentdb-cluster.kurrent.svc.cluster.local' - '*.kurrentdb-cluster.kurrent.test' + - '*.kurrentdb-cluster-replica.kurrent.svc.cluster.local' + - '*.kurrentdb-cluster-replica.kurrent.test' privateKey: algorithm: RSA encoding: PKCS1 @@ -411,6 +476,8 @@ spec: dnsNames: - '*.kurrentdb-cluster.kurrent.svc.cluster.local' - '*.kurrentdb-cluster.kurrent.test' + - '*.kurrentdb-cluster-replica.kurrent.svc.cluster.local' + - '*.kurrentdb-cluster-replica.kurrent.test' privateKey: algorithm: RSA encoding: PKCS1 @@ -463,6 +530,58 @@ kubectl apply -f cluster.yaml Once deployed, navigate to the [Viewing Deployments](#viewing-deployments) section. +## Deploying With Scheduling Constraints + +The pods created for a KurrentDB resource can be configured with any of the constraints commonly applied to pods: + +- [Node Selectors](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) +- [Affinity and Anti-Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) +- [Topology Spread Constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/) +- [Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) +- [Node Name](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename) + +For example, the following KurrentDB resource would schedule KurrentDB pods onto nodes labeled with `machine-size:large`, preferring to spread the replicas each in their own availability zone: + +```yaml +apiVersion: kubernetes.kurrent.io/v1 +kind: KurrentDB +metadata: + name: my-kurrentdb-cluster + namespace: kurrent +spec: + replicas: 3 + image: docker.kurrent.io/kurrent-latest/kurrentdb:25.0.0 + resources: + requests: + cpu: 1000m + memory: 1Gi + storage: + volumeMode: "Filesystem" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 512Mi + network: + domain: kurrentdb-cluster.kurrent.test + loadBalancer: + enabled: true + nodeSelector: + machine-size: large + topologySpreadConstraints: + maxSkew: 1 + topologyKey: zone + labelSelector: + matchLabels: + app.kubernetes.io/part-of: kurrentdb-operator + app.kubernetes.io/name: my-kurrentdb-cluster + whenUnsatisfiable: DoNotSchedule + +``` + +If no scheduling constraints are configured, the operator sets a default soft constraint configuring pod anti-affinity such that multiple replicas will prefer to run on different nodes, for better fault tolerance. + + ## Viewing Deployments Using the k9s tool, navigate to the namespaces list using the command `:namespaces`, it should show a screen similar to: @@ -488,7 +607,7 @@ Scrolling further will also show the events related to the deployment, such as: ### External -The Operator will create services of type `LoadBalancer` to access a KurrentDB cluster (for each node) when the `spec.network.loadBalancer.enabled` flag is set to `true`. +The Operator will create services of type `LoadBalancer` to access a KurrentDB cluster (for each node) when the `spec.network.loadBalancer.enabled` flag is set to `true`. Each service is annotated with `external-dns.alpha.kubernetes.io/hostname: {external cluster endpoint}` to allow the third-party tool [ExternalDNS](https://github.com/kubernetes-sigs/external-dns) to configure external access. @@ -580,4 +699,4 @@ kubectl -n kurrent patch kurrentdb kurrentdb-cluster --type=merge -p '{"spec":{" ```bash kubectl -n kurrent patch kurrentdb kurrentdb-cluster --type=merge -p '{"spec":{"configuration": {"ProjectionsLevel": "all", "StartStandardProjections": "true"}}}' -``` \ No newline at end of file +```