diff --git a/docs/examples/singlestore/autoscaling/compute/sdb-cluster-autoscaler.yaml b/docs/examples/singlestore/autoscaling/compute/sdb-cluster-autoscaler.yaml new file mode 100644 index 0000000000..82ea644abb --- /dev/null +++ b/docs/examples/singlestore/autoscaling/compute/sdb-cluster-autoscaler.yaml @@ -0,0 +1,21 @@ +apiVersion: autoscaling.kubedb.com/v1alpha1 +kind: SinglestoreAutoscaler +metadata: + name: sdb-cluster-autoscaler + namespace: demo +spec: + databaseRef: + name: sdb-sample + compute: + aggregator: + trigger: "On" + podLifeTimeThreshold: 5m + minAllowed: + cpu: 900m + memory: 3Gi + maxAllowed: + cpu: 2000m + memory: 6Gi + controlledResources: ["cpu", "memory"] + containerControlledValues: "RequestsAndLimits" + resourceDiffPercentage: 10 \ No newline at end of file diff --git a/docs/examples/singlestore/autoscaling/compute/sdb-compute.yaml b/docs/examples/singlestore/autoscaling/compute/sdb-compute.yaml new file mode 100644 index 0000000000..e298b63c12 --- /dev/null +++ b/docs/examples/singlestore/autoscaling/compute/sdb-compute.yaml @@ -0,0 +1,52 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: 8.7.10 + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 3 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/singlestore/autoscaling/storage/sdb-compute.yaml b/docs/examples/singlestore/autoscaling/storage/sdb-compute.yaml new file mode 100644 index 0000000000..e298b63c12 --- /dev/null +++ b/docs/examples/singlestore/autoscaling/storage/sdb-compute.yaml @@ -0,0 +1,52 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: 8.7.10 + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 3 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/singlestore/autoscaling/storage/sdb-storage-autoscaler.yaml b/docs/examples/singlestore/autoscaling/storage/sdb-storage-autoscaler.yaml new file mode 100644 index 0000000000..709180850b --- /dev/null +++ b/docs/examples/singlestore/autoscaling/storage/sdb-storage-autoscaler.yaml @@ -0,0 +1,15 @@ +apiVersion: autoscaling.kubedb.com/v1alpha1 +kind: SinglestoreAutoscaler +metadata: + name: sdb-cluster-autoscaler + namespace: demo +spec: + databaseRef: + name: sdb-sample + storage: + leaf: + trigger: "On" + usageThreshold: 30 + scalingThreshold: 50 + expansionMode: "Online" + upperBound: "100Gi" \ No newline at end of file diff --git a/docs/guides/mysql/backup/kubestash/application-level/index.md b/docs/guides/mysql/backup/kubestash/application-level/index.md index 3ba6030722..afe3c4a98d 100644 --- a/docs/guides/mysql/backup/kubestash/application-level/index.md +++ b/docs/guides/mysql/backup/kubestash/application-level/index.md @@ -3,7 +3,7 @@ title: Application Level Backup & Restore MySQL | KubeStash description: Application Level Backup and Restore using KubeStash menu: docs_{{ .version }}: - identifier: guides-application-level-backup-stashv2 + identifier: guides-mysql-application-level-backup-stashv2 name: Application Level Backup parent: guides-mysql-backup-stashv2 weight: 40 diff --git a/docs/guides/mysql/pitr/archiver.md b/docs/guides/mysql/pitr/archiver.md index 00ad0fae62..4be52657b9 100644 --- a/docs/guides/mysql/pitr/archiver.md +++ b/docs/guides/mysql/pitr/archiver.md @@ -143,13 +143,13 @@ spec: scheduler: successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 1 - schedule: "/30 * * * *" + schedule: "*/30 * * * *" sessionHistoryLimit: 2 manifestBackup: scheduler: successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 1 - schedule: "/30 * * * *" + schedule: "*/30 * * * *" sessionHistoryLimit: 2 backupStorage: ref: diff --git a/docs/guides/mysql/pitr/yamls/mysqlarchiver.yaml b/docs/guides/mysql/pitr/yamls/mysqlarchiver.yaml index f3818455e6..4fe652feed 100644 --- a/docs/guides/mysql/pitr/yamls/mysqlarchiver.yaml +++ b/docs/guides/mysql/pitr/yamls/mysqlarchiver.yaml @@ -28,13 +28,13 @@ spec: scheduler: successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 1 - schedule: "/30 * * * *" + schedule: "*/30 * * * *" sessionHistoryLimit: 2 manifestBackup: scheduler: successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 1 - schedule: "/30 * * * *" + schedule: "*/30 * * * *" sessionHistoryLimit: 2 backupStorage: ref: diff --git a/docs/guides/postgres/backup/kubestash/application-level/index.md b/docs/guides/postgres/backup/kubestash/application-level/index.md index 6cc1d97d44..e1a85772c7 100644 --- a/docs/guides/postgres/backup/kubestash/application-level/index.md +++ b/docs/guides/postgres/backup/kubestash/application-level/index.md @@ -3,7 +3,7 @@ title: Application Level Backup & Restore PostgreSQL | KubeStash description: Application Level Backup and Restore using KubeStash menu: docs_{{ .version }}: - identifier: guides-application-level-backup-stashv2 + identifier: guides-pg-application-level-backup-stashv2 name: Application Level Backup parent: guides-pg-backup-stashv2 weight: 40 diff --git a/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1.yaml b/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1.yaml index 7d4e68f246..c3f58173c7 100644 --- a/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1.yaml +++ b/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1.yaml @@ -5,7 +5,26 @@ metadata: namespace: demo spec: version: "2.3.2-debian" - replicas: 1 + replicas: 3 + podTemplate: + spec: + containers: + - name: proxysql + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 250m + memory: 64Mi + securityContext: + runAsGroup: 999 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + podPlacementPolicy: + name: default syncUsers: true backend: name: mysql-server diff --git a/docs/guides/redis/backup/kubestash/application-level/index.md b/docs/guides/redis/backup/kubestash/application-level/index.md index 7c07ad1eaf..15c0cdd0b2 100644 --- a/docs/guides/redis/backup/kubestash/application-level/index.md +++ b/docs/guides/redis/backup/kubestash/application-level/index.md @@ -3,7 +3,7 @@ title: Application Level Backup & Restore Redis | KubeStash description: Application Level Backup and Restore using KubeStash menu: docs_{{ .version }}: - identifier: guides-application-level-backup-stashv2 + identifier: guides-rd-application-level-backup-stashv2 name: Application Level Backup parent: guides-rd-backup-stashv2 weight: 40 diff --git a/docs/guides/singlestore/README.md b/docs/guides/singlestore/README.md index b5cfacad89..c1f29a33dd 100644 --- a/docs/guides/singlestore/README.md +++ b/docs/guides/singlestore/README.md @@ -42,7 +42,8 @@ SingleStore, a distributed SQL database for real-time analytics, transactional w KubeDB supports the following SingleSore Versions. - `8.1.32` -- `8.5.7` +- `8.5.30` +- `8.7.10` ## Life Cycle of a SingleStore Object diff --git a/docs/guides/singlestore/_index.md b/docs/guides/singlestore/_index.md index b8bca4c8b4..5548c5e483 100644 --- a/docs/guides/singlestore/_index.md +++ b/docs/guides/singlestore/_index.md @@ -5,6 +5,6 @@ menu: identifier: guides-singlestore name: SingleStore parent: guides - weight: 10 + weight: 20 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/singlestore/autoscaler/_index.md b/docs/guides/singlestore/autoscaler/_index.md new file mode 100644 index 0000000000..890618438e --- /dev/null +++ b/docs/guides/singlestore/autoscaler/_index.md @@ -0,0 +1,10 @@ +--- +title: Autoscaling +menu: + docs_{{ .version }}: + identifier: sdb-auto-scaling + name: Autoscaling + parent: guides-singlestore + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/autoscaler/compute/_index.md b/docs/guides/singlestore/autoscaler/compute/_index.md new file mode 100644 index 0000000000..13d55d0e5e --- /dev/null +++ b/docs/guides/singlestore/autoscaler/compute/_index.md @@ -0,0 +1,10 @@ +--- +title: Compute Autoscaling +menu: + docs_{{ .version }}: + identifier: sdb-compute-auto-scaling + name: Compute Autoscaling + parent: sdb-auto-scaling + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/autoscaler/compute/cluster.md b/docs/guides/singlestore/autoscaler/compute/cluster.md new file mode 100644 index 0000000000..d9e2b6bb39 --- /dev/null +++ b/docs/guides/singlestore/autoscaler/compute/cluster.md @@ -0,0 +1,538 @@ +--- +title: SingleStore Compute Autoscaling Overview +menu: + docs_{{ .version }}: + identifier: sdb-auto-scaling-cluster + name: SingleStore Compute + parent: sdb-compute-auto-scaling + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +# Autoscaling the Compute Resource of a SingleStore Cluster + +This guide will show you how to use `KubeDB` to autoscale compute resources i.e. cpu and memory of a singlestore cluster for aggregator and leaf nodes. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the `kubectl` command-line tool must be configured to communicate with your cluster. + +- Install `KubeDB` Provisioner, Ops-manager and Autoscaler operator in your cluster following the steps [here](/docs/setup/README.md). + +- Install `Metrics Server` from [here](https://github.com/kubernetes-sigs/metrics-server#installation) + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreAutoscaler](/docs/guides/singlestore/concepts/autoscaler.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + - [Compute Resource Autoscaling Overview](/docs/guides/singlestore/autoscaler/compute/overview.md) + +To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +> **Note:** YAML files used in this tutorial are stored in [docs/examples/singlestore](/docs/examples/singlestore) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. + +## Autoscaling of SingleStore Cluster + +Here, we are going to deploy a `SingleStore` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `SingleStoreAutoscaler` to set up autoscaling. + +#### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +#### Deploy SingleStore Cluster + +In this section, we are going to deploy a SingleStore with version `8.7.10`. Then, in the next section we will set up autoscaling for this database using `SingleStoreAutoscaler` CRD. Below is the YAML of the `SingleStore` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: 8.7.10 + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 3 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + +``` +Let's create the `SingleStore` CRO we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/compute/sdb-cluster.yaml +singlestore.kubedb.com/sdb-cluster created +``` + +Now, wait until `sdb-sample` has status `Ready`. i.e, + +```bash +NAME TYPE VERSION STATUS AGE +singlestore.kubedb.com/sdb-sample kubedb.com/v1alpha2 8.7.10 Ready 4m35s +``` + +Let's check the aggregator pod containers resources, + +```bash +kubectl get pod -n demo sdb-sample-aggregator-0 -o json | jq '.spec.containers[].resources' +{ + "limits": { + "cpu": "700m", + "memory": "2Gi" + }, + "requests": { + "cpu": "700m", + "memory": "2Gi" + } +} +``` + +Let's check the SingleStore aggregator node resources, +```bash +kubectl get singlestore -n demo sdb-sample -o json | jq '.spec.topology.aggregator.podTemplate.spec.containers[] | select(.name == "singlestore") | .resources' +{ + "limits": { + "cpu": "700m", + "memory": "2Gi" + }, + "requests": { + "cpu": "700m", + "memory": "2Gi" + } +} + +``` + +You can see from the above outputs that the resources are same as the one we have assigned while deploying the singlestore. + +We are now ready to apply the `SingleStoreAutoscaler` CRO to set up autoscaling for this database. + +### Compute Resource Autoscaling + +Here, we are going to set up compute resource autoscaling using a SingleStoreAutoscaler Object. + +#### Create SingleStoreAutoscaler Object + +In order to set up compute resource autoscaling for this singlestore cluster, we have to create a `SingleStoreAutoscaler` CRO with our desired configuration. Below is the YAML of the `SingleStoreAutoscaler` object that we are going to create, + +```yaml +apiVersion: autoscaling.kubedb.com/v1alpha1 +kind: SinglestoreAutoscaler +metadata: + name: sdb-cluster-autoscaler + namespace: demo +spec: + databaseRef: + name: sdb-sample + compute: + aggregator: + trigger: "On" + podLifeTimeThreshold: 5m + minAllowed: + cpu: 900m + memory: 3Gi + maxAllowed: + cpu: 2000m + memory: 6Gi + controlledResources: ["cpu", "memory"] + containerControlledValues: "RequestsAndLimits" + resourceDiffPercentage: 10 +``` + + +Here, + +- `spec.databaseRef.name` specifies that we are performing compute resource scaling operation on `sdb-sample` cluster. +- `spec.compute.aggregator.trigger` or `spec.compute.leaf.trigger` specifies that compute autoscaling is enabled for this cluster. +- `spec.compute.aggregator.podLifeTimeThreshold` or `spec.compute.leaf.podLifeTimeThreshold` specifies the minimum lifetime for at least one of the pod to initiate a vertical scaling. +- `spec.compute.aggregator.resourceDiffPercentage` or `spec.compute.leaf.resourceDiffPercentage` specifies the minimum resource difference in percentage. The default is 10%.If the difference between current & recommended resource is less than ResourceDiffPercentage, Autoscaler Operator will ignore the updating. +- `spec.compute.aggregator.minAllowed` or `spec.compute.leaf.minAllowed` specifies the minimum allowed resources for the cluster. +- `spec.compute.aggregator.maxAllowed` or `spec.compute.leaf.maxAllowed` specifies the maximum allowed resources for the cluster. +- `spec.compute.aggregator.controlledResources` or `spec.compute.leaf.controlledResources` specifies the resources that are controlled by the autoscaler. +- `spec.compute.aggregator.containerControlledValues` or `spec.compute.leaf.containerControlledValues` specifies which resource values should be controlled. The default is "RequestsAndLimits". +- `spec.opsRequestOptions` contains the options to pass to the created OpsRequest. It has 2 fields. + - `timeout` specifies the timeout for the OpsRequest. + - `apply` specifies when the OpsRequest should be applied. The default is "IfReady". + +Let's create the `SinglestoreAutoscaler` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaler/compute/sdb-cluster-autoscaler.yaml +singlestoreautoscaler.autoscaling.kubedb.com/sdb-cluster-autoscaler created +``` + +#### Verify Autoscaling is set up successfully + +Let's check that the `singlestoreautoscaler` resource is created successfully, + +```bash +$ kubectl describe singlestoreautoscaler -n demo sdb-cluster-autoscaler +Name: sdb-cluster-autoscaler +Namespace: demo +Labels: +Annotations: +API Version: autoscaling.kubedb.com/v1alpha1 +Kind: SinglestoreAutoscaler +Metadata: + Creation Timestamp: 2024-09-10T08:55:26Z + Generation: 1 + Owner References: + API Version: kubedb.com/v1alpha2 + Block Owner Deletion: true + Controller: true + Kind: Singlestore + Name: sdb-sample + UID: f81d0592-9dda-428a-b0b4-e72ab3643e22 + Resource Version: 424275 + UID: 6b7b3d72-b92f-4e6f-88eb-4e891c24c550 +Spec: + Compute: + Aggregator: + Container Controlled Values: RequestsAndLimits + Controlled Resources: + cpu + memory + Max Allowed: + Cpu: 2 + Memory: 6Gi + Min Allowed: + Cpu: 900m + Memory: 3Gi + Pod Life Time Threshold: 5m0s + Resource Diff Percentage: 10 + Trigger: On + Database Ref: + Name: sdb-sample + Ops Request Options: + Apply: IfReady +Status: + Checkpoints: + Cpu Histogram: + Bucket Weights: + Index: 0 + Weight: 2455 + Index: 1 + Weight: 2089 + Index: 2 + Weight: 10000 + Index: 3 + Weight: 361 + Reference Timestamp: 2024-09-10T09:05:00Z + Total Weight: 5.5790751974302655 + First Sample Start: 2024-09-10T08:59:26Z + Last Sample Start: 2024-09-10T09:15:18Z + Last Update Time: 2024-09-10T09:15:27Z + Memory Histogram: + Bucket Weights: + Index: 1 + Weight: 1821 + Index: 2 + Weight: 10000 + Reference Timestamp: 2024-09-10T09:05:00Z + Total Weight: 14.365194626381038 + Ref: + Container Name: singlestore-coordinator + Vpa Object Name: sdb-sample-aggregator + Total Samples Count: 32 + Version: v3 + Cpu Histogram: + Bucket Weights: + Index: 5 + Weight: 3770 + Index: 6 + Weight: 10000 + Index: 7 + Weight: 132 + Index: 20 + Weight: 118 + Reference Timestamp: 2024-09-10T09:05:00Z + Total Weight: 6.533759718059768 + First Sample Start: 2024-09-10T08:59:26Z + Last Sample Start: 2024-09-10T09:16:19Z + Last Update Time: 2024-09-10T09:16:28Z + Memory Histogram: + Bucket Weights: + Index: 17 + Weight: 8376 + Index: 18 + Weight: 10000 + Reference Timestamp: 2024-09-10T09:05:00Z + Total Weight: 17.827743425726553 + Ref: + Container Name: singlestore + Vpa Object Name: sdb-sample-aggregator + Total Samples Count: 34 + Version: v3 + Conditions: + Last Transition Time: 2024-09-10T08:59:43Z + Message: Successfully created SinglestoreOpsRequest demo/sdbops-sdb-sample-aggregator-c0u141 + Observed Generation: 1 + Reason: CreateOpsRequest + Status: True + Type: CreateOpsRequest + Vpas: + Conditions: + Last Transition Time: 2024-09-10T08:59:42Z + Status: True + Type: RecommendationProvided + Recommendation: + Container Recommendations: + Container Name: singlestore + Lower Bound: + Cpu: 900m + Memory: 3Gi + Target: + Cpu: 900m + Memory: 3Gi + Uncapped Target: + Cpu: 100m + Memory: 351198544 + Upper Bound: + Cpu: 2 + Memory: 6Gi + Vpa Name: sdb-sample-aggregator +Events: +``` +So, the `singlestoreautoscaler` resource is created successfully. + +you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `singlestoreopsrequest` based on the recommendations, if the database pods resources are needed to scaled up or down. + +Let's watch the `singlestoreopsrequest` in the demo namespace to see if any `singlestoreopsrequest` object is created. After some time you'll see that a `singlestoreopsrequest` will be created based on the recommendation. + +```bash +$ watch kubectl get singlestoreopsrequest -n demo +Every 2.0s: kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-sdb-sample-aggregator-c0u141 VerticalScaling Progressing 10s +``` + +Let's wait for the ops request to become successful. + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-sdb-sample-aggregator-c0u141 VerticalScaling Successful 3m2s +``` + +We can see from the above output that the `SinglestoreOpsRequest` has succeeded. If we describe the `SinglestoreOpsRequest` we will get an overview of the steps that were followed to scale the cluster. + +```bash +$ kubectl describe singlestoreopsrequest -n demo sdbops-sdb-sample-aggregator-c0u141 +Name: sdbops-sdb-sample-aggregator-c0u141 +Namespace: demo +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=sdb-sample + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=singlestores.kubedb.com +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: SinglestoreOpsRequest +Metadata: + Creation Timestamp: 2024-09-10T08:59:43Z + Generation: 1 + Owner References: + API Version: autoscaling.kubedb.com/v1alpha1 + Block Owner Deletion: true + Controller: true + Kind: SinglestoreAutoscaler + Name: sdb-cluster-autoscaler + UID: 6b7b3d72-b92f-4e6f-88eb-4e891c24c550 + Resource Version: 406111 + UID: 978a1a00-f217-4326-b103-f66bbccf2943 +Spec: + Apply: IfReady + Database Ref: + Name: sdb-sample + Type: VerticalScaling + Vertical Scaling: + Aggregator: + Resources: + Limits: + Cpu: 900m + Memory: 3Gi + Requests: + Cpu: 900m + Memory: 3Gi +Status: + Conditions: + Last Transition Time: 2024-09-10T09:01:55Z + Message: Timeout: request did not complete within requested timeout - context deadline exceeded + Observed Generation: 1 + Reason: Failed + Status: True + Type: VerticalScaling + Last Transition Time: 2024-09-10T08:59:46Z + Message: Successfully paused database + Observed Generation: 1 + Reason: DatabasePauseSucceeded + Status: True + Type: DatabasePauseSucceeded + Last Transition Time: 2024-09-10T08:59:46Z + Message: Successfully updated PetSets Resources + Observed Generation: 1 + Reason: UpdatePetSets + Status: True + Type: UpdatePetSets + Last Transition Time: 2024-09-10T09:01:21Z + Message: Successfully Restarted Pods With Resources + Observed Generation: 1 + Reason: RestartPods + Status: True + Type: RestartPods + Last Transition Time: 2024-09-10T08:59:52Z + Message: get pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + Observed Generation: 1 + Status: True + Type: GetPod--sdb-sample-aggregator-0 + Last Transition Time: 2024-09-10T08:59:52Z + Message: evict pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + Observed Generation: 1 + Status: True + Type: EvictPod--sdb-sample-aggregator-0 + Last Transition Time: 2024-09-10T09:00:31Z + Message: check pod ready; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + Observed Generation: 1 + Status: True + Type: CheckPodReady--sdb-sample-aggregator-0 + Last Transition Time: 2024-09-10T09:00:36Z + Message: get pod; ConditionStatus:True; PodName:sdb-sample-aggregator-1 + Observed Generation: 1 + Status: True + Type: GetPod--sdb-sample-aggregator-1 + Last Transition Time: 2024-09-10T09:00:36Z + Message: evict pod; ConditionStatus:True; PodName:sdb-sample-aggregator-1 + Observed Generation: 1 + Status: True + Type: EvictPod--sdb-sample-aggregator-1 + Last Transition Time: 2024-09-10T09:01:16Z + Message: check pod ready; ConditionStatus:True; PodName:sdb-sample-aggregator-1 + Observed Generation: 1 + Status: True + Type: CheckPodReady--sdb-sample-aggregator-1 + Observed Generation: 1 + Phase: Successful +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Starting 25m KubeDB Ops-manager Operator Start processing for SinglestoreOpsRequest: demo/sdbops-sdb-sample-aggregator-c0u141 + Normal Starting 25m KubeDB Ops-manager Operator Pausing Singlestore database: demo/sdb-sample + Normal Successful 25m KubeDB Ops-manager Operator Successfully paused Singlestore database: demo/sdb-sample for SinglestoreOpsRequest: sdbops-sdb-sample-aggregator-c0u141 + Normal UpdatePetSets 25m KubeDB Ops-manager Operator Successfully updated PetSets Resources + Warning get pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 25m KubeDB Ops-manager Operator get pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + Warning evict pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 25m KubeDB Ops-manager Operator evict pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + Warning check pod ready; ConditionStatus:False; PodName:sdb-sample-aggregator-0 25m KubeDB Ops-manager Operator check pod ready; ConditionStatus:False; PodName:sdb-sample-aggregator-0 + Warning check pod ready; ConditionStatus:True; PodName:sdb-sample-aggregator-0 24m KubeDB Ops-manager Operator check pod ready; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + Warning get pod; ConditionStatus:True; PodName:sdb-sample-aggregator-1 24m KubeDB Ops-manager Operator get pod; ConditionStatus:True; PodName:sdb-sample-aggregator-1 + Warning evict pod; ConditionStatus:True; PodName:sdb-sample-aggregator-1 24m KubeDB Ops-manager Operator evict pod; ConditionStatus:True; PodName:sdb-sample-aggregator-1 + Warning check pod ready; ConditionStatus:False; PodName:sdb-sample-aggregator-1 24m KubeDB Ops-manager Operator check pod ready; ConditionStatus:False; PodName:sdb-sample-aggregator-1 + Warning check pod ready; ConditionStatus:True; PodName:sdb-sample-aggregator-1 24m KubeDB Ops-manager Operator check pod ready; ConditionStatus:True; PodName:sdb-sample-aggregator-1 + Normal RestartPods 24m KubeDB Ops-manager Operator Successfully Restarted Pods With Resources + Normal Starting + Normal Successful +``` + +Now, we are going to verify from the Pod, and the singlestore yaml whether the resources of the topology database has updated to meet up the desired state, Let's check, + +```bash +kubectl get pod -n demo sdb-sample-aggregator-0 -o json | jq '.spec.containers[].resources' +{ + "limits": { + "cpu": "900m", + "memory": "3Gi" + }, + "requests": { + "cpu": "900m", + "memory": "3Gi" + } +} + + +kubectl get singlestore -n demo sdb-sample -o json | jq '.spec.topology.aggregator.podTemplate.spec.containers[] | select(.name == "singlestore") | .resources' +{ + "limits": { + "cpu": "900m", + "memory": "3Gi" + }, + "requests": { + "cpu": "900m", + "memory": "3Gi" + } +} + +``` + + +The above output verifies that we have successfully auto scaled the resources of the SingleStore cluster. + +## Cleaning Up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete singlestoreopsrequest -n demo sdbops-sdb-sample-aggregator-c0u141 +kubectl delete singlestoreautoscaler -n demo sdb-cluster-autoscaler +kubectl delete kf -n demo sdb-sample +kubectl delete ns demo +``` +## Next Steps + +- Detail concepts of [SingleStore object](/docs/guides/singlestore/concepts/singlestore.md). +- Different SingleStore clustering modes [here](/docs/guides/singlestore/clustering/_index.md). +- Monitor your singlestore database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/singlestore/monitoring/prometheus-operator/index.md). +- Monitor your singlestore database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/singlestore/monitoring/builtin-prometheus/index.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). + diff --git a/docs/guides/singlestore/autoscaler/compute/overview.md b/docs/guides/singlestore/autoscaler/compute/overview.md new file mode 100644 index 0000000000..11b9a28f63 --- /dev/null +++ b/docs/guides/singlestore/autoscaler/compute/overview.md @@ -0,0 +1,55 @@ +--- +title: SingleStore Compute Autoscaling Overview +menu: + docs_{{ .version }}: + identifier: sdb-auto-scaling-overview + name: Overview + parent: sdb-compute-auto-scaling + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore Compute Resource Autoscaling + +This guide will give an overview on how KubeDB Autoscaler operator autoscales the database compute resources i.e. cpu and memory using `singlestoreautoscaler` crd. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreAutoscaler](/docs/guides/singlestore/concepts/autoscaler.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +## How Compute Autoscaling Works + +The following diagram shows how KubeDB Autoscaler operator autoscales the resources of `SingleStore` database components. Open the image in a new tab to see the enlarged version. + +
+  Compute Auto Scaling process of SingleStore +
Fig: Compute Auto Scaling process of SingleStore
+
+ +The Auto Scaling process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource Object (CRO). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CRO. + +3. When the operator finds a `SingleStore` CRO, it creates required number of `PetSets` and related necessary stuff like secrets, services, etc. + +4. Then, in order to set up autoscaling of the various components (ie. Aggregator, Leaf, Standalone) of the `SingleStore` database the user creates a `SingleStoreAutoscaler` CRO with desired configuration. + +5. `KubeDB` Autoscaler operator watches the `SingleStoreAutoscaler` CRO. + +6. `KubeDB` Autoscaler operator generates recommendation using the modified version of kubernetes [official recommender](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler/pkg/recommender) for different components of the database, as specified in the `SingleStoreAutoscaler` CRO. + +7. If the generated recommendation doesn't match the current resources of the database, then `KubeDB` Autoscaler operator creates a `SingleStoreOpsRequest` CRO to scale the database to match the recommendation generated. + +8. `KubeDB` Ops-manager operator watches the `SingleStoreOpsRequest` CRO. + +9. Then the `KubeDB` Ops-manager operator will scale the database component vertically as specified on the `SingleStoreOpsRequest` CRO. + +In the next docs, we are going to show a step by step guide on Autoscaling of various SingleStore database components using `SingleStoreAutoscaler` CRD. \ No newline at end of file diff --git a/docs/guides/singlestore/autoscaler/storage/_index.md b/docs/guides/singlestore/autoscaler/storage/_index.md new file mode 100644 index 0000000000..91b59b6898 --- /dev/null +++ b/docs/guides/singlestore/autoscaler/storage/_index.md @@ -0,0 +1,10 @@ +--- +title: Storage Autoscaling +menu: + docs_{{ .version }}: + identifier: sdb-storage-auto-scaling + name: Storage Autoscaling + parent: sdb-auto-scaling + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/autoscaler/storage/cluster.md b/docs/guides/singlestore/autoscaler/storage/cluster.md new file mode 100644 index 0000000000..318406e8d6 --- /dev/null +++ b/docs/guides/singlestore/autoscaler/storage/cluster.md @@ -0,0 +1,476 @@ +--- +title: SingleStore Cluster Autoscaling +menu: + docs_{{ .version }}: + identifier: sdb-storage-auto-scaling-cluster + name: SingleStore Storage + parent: sdb-storage-auto-scaling + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Storage Autoscaling of a SingleStore Cluster + +This guide will show you how to use `KubeDB` to autoscale the storage of a SingleStore cluster. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the `kubectl` command-line tool must be configured to communicate with your cluster. + +- Install `KubeDB` Provisioner, Ops-manager and Autoscaler operator in your cluster following the steps [here](/docs/setup/README.md). + +- Install `Metrics Server` from [here](https://github.com/kubernetes-sigs/metrics-server#installation) + +- Install Prometheus from [here](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) + +- You must have a `StorageClass` that supports volume expansion. + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreAutoscaler](/docs/guides/singlestore/concepts/autoscaler.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + - [Storage Autoscaling Overview](/docs/guides/singlestore/autoscaler/storage/overview.md) + +To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +> **Note:** YAML files used in this tutorial are stored in [docs/examples/singlestore](/docs/examples/singlestore) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. + +## Storage Autoscaling of SingleStore Cluster + +At first verify that your cluster has a storage class, that supports volume expansion. Let's check, + +```bash +$ kubectl get storageclass +NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE +standard (default) kubernetes.io/gce-pd Delete Immediate true 2m49s +``` + +#### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +#### Deploy SingleStore Cluster + +In this section, we are going to deploy a SingleStore with version `8.7.10`. Then, in the next section we will set up autoscaling for this database using `SingleStoreAutoscaler` CRD. Below is the YAML of the `SingleStore` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: 8.7.10 + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 3 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.7" + requests: + memory: "2Gi" + cpu: "0.7" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + +``` +Let's create the `SingleStore` CRO we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/storage/sdb-cluster.yaml +singlestore.kubedb.com/sdb-cluster created +``` + +Now, wait until `sdb-sample` has status `Ready`. i.e, + +```bash +NAME TYPE VERSION STATUS AGE +singlestore.kubedb.com/sdb-sample kubedb.com/v1alpha2 8.7.10 Ready 4m35s +``` + +> **Note:** You can manage storage autoscale for aggregator and leaf nodes separately. Here, we will focus on leaf nodes. + +Let's check volume size from petset, and from the persistent volume, + +```bash +$ kubectl get petset -n demo sdb-sample-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +"10Gi" + +$ kubectl get pv -n demo | grep 'leaf' +pvc-5cf8638e365544dd 10Gi RWO Retain Bound demo/data-sdb-sample-leaf-0 linode-block-storage-retain 50s +pvc-a99e7adb282a4f9c 10Gi RWO Retain Bound demo/data-sdb-sample-leaf-2 linode-block-storage-retain 60s +pvc-da8e9e5162a748df 10Gi RWO Retain Bound demo/data-sdb-sample-leaf-1 linode-block-storage-retain 70s + +``` + +You can see the petset of leaf has 10GB storage, and the capacity of all the persistent volume is also 10GB. + +We are now ready to apply the `SingleStoreAutoscaler` CRO to set up storage autoscaling for this cluster. + +### Storage Autoscaling + +Here, we are going to set up storage autoscaling using a SingleStoreAutoscaler Object. + +#### Create SingleStoreAutoscaler Object + +In order to set up vertical autoscaling for this singlestore cluster, we have to create a `SinglestoreAutoscaler` CRO with our desired configuration. Below is the YAML of the `SinglestoreAutoscaler` object that we are going to create, + +```yaml +apiVersion: autoscaling.kubedb.com/v1alpha1 +kind: SinglestoreAutoscaler +metadata: + name: sdb-cluster-autoscaler + namespace: demo +spec: + databaseRef: + name: sdb-sample + storage: + leaf: + trigger: "On" + usageThreshold: 30 + scalingThreshold: 50 + expansionMode: "Online" + upperBound: "100Gi" +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing vertical scaling operation on `sdb-sample` cluster. +- `spec.storage.leaf.trigger` specifies that storage autoscaling is enabled for leaf nodes on this cluster. +- `spec.storage.leaf.usageThreshold` specifies storage usage threshold, if storage usage exceeds `30%` then storage autoscaling will be triggered. +- `spec.storage.leaf.scalingThreshold` specifies the scaling threshold. Storage will be scaled to `50%` of the current amount. +- It has another field `spec.storage.leaf.expansionMode` to set the opsRequest volumeExpansionMode, which support two values: `Online` & `Offline`. Default value is `Online`. + +Let's create the `SinglestoreAutoscaler` CR we have shown above, + + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/storage/sdb-storage-autoscaler.yaml +singlestoreautoscaler.autoscaling.kubedb.com/sdb-storage-autoscaler created +``` + +#### Storage Autoscaling is set up successfully + +Let's check that the `singlestoreautoscaler` resource is created successfully, + +```bash +$ kubectl get singlestoreautoscaler -n demo +NAME AGE +sdb-cluster-autoscaler 2m5s + + +$ kubectl describe singlestoreautoscaler -n demo sdb-cluster-autoscaler +Name: sdb-cluster-autoscaler +Namespace: demo +Labels: +Annotations: +API Version: autoscaling.kubedb.com/v1alpha1 +Kind: SinglestoreAutoscaler +Metadata: + Creation Timestamp: 2024-09-11T07:05:11Z + Generation: 1 + Owner References: + API Version: kubedb.com/v1alpha2 + Block Owner Deletion: true + Controller: true + Kind: Singlestore + Name: sdb-sample + UID: e08e1f37-d869-437d-9b15-14c6aef3f406 + Resource Version: 4904325 + UID: 471afa65-6d12-4e7d-a2a6-6d28ce440c4d +Spec: + Database Ref: + Name: sdb-sample + Ops Request Options: + Apply: IfReady + Storage: + Leaf: + Expansion Mode: Online + Scaling Rules: + Applies Upto: + Threshold: 50pc + Scaling Threshold: 50 + Trigger: On + Upper Bound: 100Gi + Usage Threshold: 30 +Events: + + +``` + +So, the `singlestoreautoscaler` resource is created successfully. + +Now, for this demo, we are going to manually fill up the persistent volume to exceed the `usageThreshold` creating new database with partitions 6 to see if storage autoscaling is working or not. + +Let's exec into the cluster pod and fill the cluster volume using the following commands: + +```bash +$ kubectl exec -it -n demo sdb-sample-leaf-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sdb-sample-leaf-0 /]$ df -h var/lib/memsql +Filesystem Size Used Avail Use% Mounted on +/dev/disk/by-id/scsi-0Linode_Volume_pvcc50e0d73d07349f9 9.8G 1.4G 8.4G 15% /var/lib/memsql + +$ kubectl exec -it -n demo sdb-sample-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sdb-sample-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 113 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) +Copyright (c) 2000, 2022, Oracle and/or its affiliates. +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. +singlestore> create database demo partitions 6; +Query OK, 1 row affected (3.78 sec) + +$ kubectl exec -it -n demo sdb-sample-leaf-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sdb-sample-leaf-0 /]$ df -h var/lib/memsql +Filesystem Size Used Avail Use% Mounted on +/dev/disk/by-id/scsi-0Linode_Volume_pvcc50e0d73d07349f9 9.8G 3.2G 6.7G 33% /var/lib/memsql + +``` + +So, from the above output we can see that the storage usage is 33%, which exceeded the `usageThreshold` 30%. + +Let's watch the `singlestoreopsrequest` in the demo namespace to see if any `singlestoreopsrequest` object is created. After some time you'll see that a `singlestoreopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. + +```bash +$ watch kubectl get singlestoreopsrequest -n demo +Every 2.0s: kubectl get singlestoreopsrequest -n demo ashraful: Wed Sep 11 13:39:25 2024 + +NAME TYPE STATUS AGE +sdbops-sdb-sample-th2r62 VolumeExpansion Progressing 10s +``` + +Let's wait for the ops request to become successful. + +```bash +$ watch kubectl get singlestoreopsrequest -n demo +Every 2.0s: kubectl get singlestoreopsrequest -n demo ashraful: Wed Sep 11 13:41:12 2024 + +NAME TYPE STATUS AGE +sdbops-sdb-sample-th2r62 VolumeExpansion Successful 2m31s + +``` + +We can see from the above output that the `SinglestoreOpsRequest` has succeeded. If we describe the `SinglestoreOpsRequest` we will get an overview of the steps that were followed to expand the volume of the cluster. + +```bash +$ kubectl describe singlestoreopsrequest -n demo sdbops-sdb-sample-th2r62 +Name: sdbops-sdb-sample-th2r62 +Namespace: demo +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=sdb-sample + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=singlestores.kubedb.com +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: SinglestoreOpsRequest +Metadata: + Creation Timestamp: 2024-09-11T07:36:42Z + Generation: 1 + Owner References: + API Version: autoscaling.kubedb.com/v1alpha1 + Block Owner Deletion: true + Controller: true + Kind: SinglestoreAutoscaler + Name: sdb-cluster-autoscaler + UID: 471afa65-6d12-4e7d-a2a6-6d28ce440c4d + Resource Version: 4909632 + UID: 3dce68d0-b5ee-4ad6-bd1f-f712bae39630 +Spec: + Apply: IfReady + Database Ref: + Name: sdb-sample + Type: VolumeExpansion + Volume Expansion: + Leaf: 15696033792 + Mode: Online +Status: + Conditions: + Last Transition Time: 2024-09-11T07:36:42Z + Message: Singlestore ops-request has started to expand volume of singlestore nodes. + Observed Generation: 1 + Reason: VolumeExpansion + Status: True + Type: VolumeExpansion + Last Transition Time: 2024-09-11T07:36:45Z + Message: Successfully paused database + Observed Generation: 1 + Reason: DatabasePauseSucceeded + Status: True + Type: DatabasePauseSucceeded + Last Transition Time: 2024-09-11T07:37:00Z + Message: successfully deleted the petSets with orphan propagation policy + Observed Generation: 1 + Reason: OrphanPetSetPods + Status: True + Type: OrphanPetSetPods + Last Transition Time: 2024-09-11T07:36:50Z + Message: get pet set; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetPetSet + Last Transition Time: 2024-09-11T07:36:50Z + Message: delete pet set; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: DeletePetSet + Last Transition Time: 2024-09-11T07:37:40Z + Message: successfully updated Leaf node PVC sizes + Observed Generation: 1 + Reason: UpdateLeafNodePVCs + Status: True + Type: UpdateLeafNodePVCs + Last Transition Time: 2024-09-11T07:37:05Z + Message: get pvc; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetPvc + Last Transition Time: 2024-09-11T07:37:06Z + Message: is pvc patched; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: IsPvcPatched + Last Transition Time: 2024-09-11T07:37:15Z + Message: compare storage; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CompareStorage + Last Transition Time: 2024-09-11T07:37:46Z + Message: successfully reconciled the Singlestore resources + Observed Generation: 1 + Reason: UpdatePetSets + Status: True + Type: UpdatePetSets + Last Transition Time: 2024-09-11T07:37:51Z + Message: PetSet is recreated + Observed Generation: 1 + Reason: ReadyPetSets + Status: True + Type: ReadyPetSets + Last Transition Time: 2024-09-11T07:38:19Z + Message: Successfully completed volumeExpansion for Singlestore + Observed Generation: 1 + Reason: Successful + Status: True + Type: Successful + Observed Generation: 1 + Phase: Successful +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Starting 6m4s KubeDB Ops-manager Operator Start processing for SinglestoreOpsRequest: demo/sdbops-sdb-sample-th2r62 + Normal Starting 6m4s KubeDB Ops-manager Operator Pausing Singlestore database: demo/sdb-sample + Normal Successful 6m4s KubeDB Ops-manager Operator Successfully paused Singlestore database: demo/sdb-sample for SinglestoreOpsRequest: sdbops-sdb-sample-th2r62 + Warning get pet set; ConditionStatus:True 5m56s KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Warning delete pet set; ConditionStatus:True 5m56s KubeDB Ops-manager Operator delete pet set; ConditionStatus:True + Warning get pet set; ConditionStatus:True 5m51s KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Normal OrphanPetSetPods 5m46s KubeDB Ops-manager Operator successfully deleted the petSets with orphan propagation policy + Warning get pvc; ConditionStatus:True 5m41s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning is pvc patched; ConditionStatus:True 5m40s KubeDB Ops-manager Operator is pvc patched; ConditionStatus:True + Warning get pvc; ConditionStatus:True 5m36s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning compare storage; ConditionStatus:False 5m36s KubeDB Ops-manager Operator compare storage; ConditionStatus:False + Warning get pvc; ConditionStatus:True 5m31s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning compare storage; ConditionStatus:True 5m31s KubeDB Ops-manager Operator compare storage; ConditionStatus:True + Warning get pvc; ConditionStatus:True 5m26s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning is pvc patched; ConditionStatus:True 5m26s KubeDB Ops-manager Operator is pvc patched; ConditionStatus:True + Warning get pvc; ConditionStatus:True 5m21s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning compare storage; ConditionStatus:True 5m21s KubeDB Ops-manager Operator compare storage; ConditionStatus:True + Warning get pvc; ConditionStatus:True 5m16s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning is pvc patched; ConditionStatus:True 5m16s KubeDB Ops-manager Operator is pvc patched; ConditionStatus:True + Warning get pvc; ConditionStatus:True 5m11s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning compare storage; ConditionStatus:True 5m11s KubeDB Ops-manager Operator compare storage; ConditionStatus:True + Normal UpdateLeafNodePVCs 5m6s KubeDB Ops-manager Operator successfully updated Leaf node PVC sizes + Normal UpdatePetSets 5m KubeDB Ops-manager Operator successfully reconciled the Singlestore resources + Warning get pet set; ConditionStatus:True 4m55s KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Normal ReadyPetSets 4m55s KubeDB Ops-manager Operator PetSet is recreated + Normal Starting 4m27s KubeDB Ops-manager Operator Resuming Singlestore database: demo/sdb-sample + Normal Successful 4m27s KubeDB Ops-manager Operator Successfully resumed Singlestore database: demo/sdb-sample for SinglestoreOpsRequest: sdbops-sdb-sample-th2r62 +``` + +Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the combined cluster has expanded to meet the desired state, Let's check, + +```bash +kubectl get petset -n demo sdb-sample-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +"15696033792" + +~ $ kubectl get pv -n demo | grep 'leaf' +pvc-8df67f3178964106 15328158Ki RWO Retain Bound demo/data-sdb-sample-leaf-2 linode-block-storage-retain 42m +pvc-c50e0d73d07349f9 15328158Ki RWO Retain Bound demo/data-sdb-sample-leaf-0 linode-block-storage-retain 43m +pvc-f8b95ff9a9bd4fa2 15328158Ki RWO Retain Bound demo/data-sdb-sample-leaf-1 linode-block-storage-retain 42m + +``` + +The above output verifies that we have successfully autoscaled the volume of the SingleStore cluster. + +## Cleaning Up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete singlestoreopsrequests -n demo sdbops-sdb-sample-th2r62 +kubectl delete singlestoreautoscaler -n demo sdb-storage-autoscaler +kubectl delete sdb -n demo sdb-sample +``` + +## Next Steps + +- Detail concepts of [SingleStore object](/docs/guides/singlestore/concepts/singlestore.md). +- Different SingleStore clustering modes [here](/docs/guides/singlestore/clustering/_index.md). +- Monitor your SingleStore database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/singlestore/monitoring/prometheus-operator/index.md). +- Monitor your SingleStore database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/singlestore/monitoring/builtin-prometheus/index.md) +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). \ No newline at end of file diff --git a/docs/guides/singlestore/autoscaler/storage/overview.md b/docs/guides/singlestore/autoscaler/storage/overview.md new file mode 100644 index 0000000000..95ada0dc27 --- /dev/null +++ b/docs/guides/singlestore/autoscaler/storage/overview.md @@ -0,0 +1,57 @@ +--- +title: SingleStore Storage Autoscaling Overview +menu: + docs_{{ .version }}: + identifier: sdn-storage-auto-scaling-overview + name: Overview + parent: sdb-storage-auto-scaling + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore Vertical Autoscaling + +This guide will give an overview on how KubeDB Autoscaler operator autoscales the database storage using `singlestoreautoscaler` crd. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreAutoscaler](/docs/guides/singlestore/concepts/autoscaler.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +## How Storage Autoscaling Works + +The following diagram shows how KubeDB Autoscaler operator autoscales the resources of `SingleStore` cluster components. Open the image in a new tab to see the enlarged version. + +
+  Storage Auto Scaling process of SingleStore +
Fig: Storage Auto Scaling process of SingleStore
+
+ + +The Auto Scaling process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource (CR). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CR. + +3. When the operator finds a `SingleStore` CR, it creates required number of `PetSets` and related necessary stuff like secrets, services, etc. + +- Each PetSet creates a Persistent Volume according to the Volume Claim Template provided in the petset configuration. + +4. Then, in order to set up storage autoscaling of the various components (ie. Aggregator, Leaf, Standalone.) of the `singlestore` cluster, the user creates a `SingleStoreAutoscaler` CRO with desired configuration. + +5. `KubeDB` Autoscaler operator watches the `SingleStoreAutoscaler` CRO. + +6. `KubeDB` Autoscaler operator continuously watches persistent volumes of the clusters to check if it exceeds the specified usage threshold. +- If the usage exceeds the specified usage threshold, then `KubeDB` Autoscaler operator creates a `SinglestoreOpsRequest` to expand the storage of the database. + +7. `KubeDB` Ops-manager operator watches the `SinglestoreOpsRequest` CRO. + +8. Then the `KubeDB` Ops-manager operator will expand the storage of the cluster component as specified on the `SinglestoreOpsRequest` CRO. + +In the next docs, we are going to show a step by step guide on Autoscaling storage of various Kafka cluster components using `SinglestoreAutoscaler` CRD. diff --git a/docs/guides/singlestore/backup/_index.md b/docs/guides/singlestore/backup/_index.md index f6b4e6f801..60dfa7346c 100644 --- a/docs/guides/singlestore/backup/_index.md +++ b/docs/guides/singlestore/backup/_index.md @@ -1,5 +1,5 @@ --- -title: Backup & Restore SingleStore +title: Monitoring SingleStore menu: docs_{{ .version }}: identifier: guides-sdb-backup diff --git a/docs/guides/singlestore/backup/kubestash/application-level/index.md b/docs/guides/singlestore/backup/kubestash/application-level/index.md index 64b7929728..e998a33e02 100644 --- a/docs/guides/singlestore/backup/kubestash/application-level/index.md +++ b/docs/guides/singlestore/backup/kubestash/application-level/index.md @@ -3,7 +3,7 @@ title: Application Level Backup & Restore SingleStore | KubeStash description: Application Level Backup and Restore using KubeStash menu: docs_{{ .version }}: - identifier: guides-application-level-backup-stashv2 + identifier: guides-sdb-application-level-backup-stashv2 name: Application Level Backup parent: guides-sdb-backup-stashv2 weight: 40 @@ -165,7 +165,7 @@ sample-singlestore-pods ClusterIP None 3306/TCP ``` -Here, we have to use service `sample-singlestore` and secret `sample-singlestore-root-cred` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/mysql/concepts/appbinding/index.md) CR that holds the necessary information to connect with the database. +Here, we have to use service `sample-singlestore` and secret `sample-singlestore-root-cred` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/singlestore/concepts/appbinding.md) CR that holds the necessary information to connect with the database. **Verify AppBinding:** @@ -493,7 +493,7 @@ If everything goes well, the phase of the `BackupConfiguration` should be `Ready ```bash $ kubectl get backupconfiguration -n demo -NAME PHASE PAUSED AGE +NAME PHASE PAUSED AGE sample-singlestore-backup Ready 2m50s ``` @@ -501,7 +501,7 @@ Additionally, we can verify that the `Repository` specified in the `BackupConfig ```bash $ kubectl get repo -n demo -NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE +NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-singlestore-repo 0 0 B Ready 3m ``` @@ -515,8 +515,8 @@ Verify that the `CronJob` has been created using the following command, ```bash $ kubectl get cronjob -n demo -NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE -trigger-sample-singlestore-backup-frequent-backup */5 * * * * 0 2m45s 3m25s +NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE +trigger-sample-singlestore-backup-frequent-backup */5 * * * * 0 2m45s 3m25s ``` **Verify BackupSession:** @@ -528,7 +528,7 @@ Run the following command to watch `BackupSession` CR, ```bash $ kubectl get backupsession -n demo -w -NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE +NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-singlestore-backup-frequent-backup-1724065200 BackupConfiguration sample-singlestore-backup Succeeded 7m22s ``` @@ -540,8 +540,8 @@ Once a backup is complete, KubeStash will update the respective `Repository` CR ```bash $ kubectl get repository -n demo gcs-singlestore-repo -NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE -gcs-singlestore-repo true 1 806 B Ready 8m27s 9m18s +NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE +gcs-singlestore-repo true 1 806 B Ready 8m27s 9m18s ``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. diff --git a/docs/guides/singlestore/clustering/_index.md b/docs/guides/singlestore/clustering/_index.md new file mode 100644 index 0000000000..58610731fd --- /dev/null +++ b/docs/guides/singlestore/clustering/_index.md @@ -0,0 +1,10 @@ +--- +title: Clustering +menu: + docs_{{ .version }}: + identifier: sdb-clustering + name: Clustering + parent: guides-singlestore + weight: 25 +menu_name: docs_{{ .version }} +--- \ No newline at end of file diff --git a/docs/guides/singlestore/clustering/overview/images/sdb-cluster-1.png b/docs/guides/singlestore/clustering/overview/images/sdb-cluster-1.png new file mode 100644 index 0000000000..b008f51987 Binary files /dev/null and b/docs/guides/singlestore/clustering/overview/images/sdb-cluster-1.png differ diff --git a/docs/guides/singlestore/clustering/overview/images/sdb-cluster-2.png b/docs/guides/singlestore/clustering/overview/images/sdb-cluster-2.png new file mode 100644 index 0000000000..72e9db9808 Binary files /dev/null and b/docs/guides/singlestore/clustering/overview/images/sdb-cluster-2.png differ diff --git a/docs/guides/singlestore/clustering/overview/images/sdb-cluster.png b/docs/guides/singlestore/clustering/overview/images/sdb-cluster.png new file mode 100644 index 0000000000..f082999156 Binary files /dev/null and b/docs/guides/singlestore/clustering/overview/images/sdb-cluster.png differ diff --git a/docs/guides/singlestore/clustering/overview/index.md b/docs/guides/singlestore/clustering/overview/index.md new file mode 100644 index 0000000000..94cf77c47a --- /dev/null +++ b/docs/guides/singlestore/clustering/overview/index.md @@ -0,0 +1,90 @@ +--- +title: Cluster Overview +menu: + docs_{{ .version }}: + identifier: guides-sdb-clustering-overview + name: Cluster Overview + parent: sdb-clustering + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore Cluster + +Here we'll discuss some concepts about SingleStore Cluster. + +### what is SingleStore Cluster + +A `SingleStore cluster` is a distributed database system that consists of multiple servers (nodes) working together to provide high performance, scalability, and fault tolerance for data storage and processing. It is specifically designed to handle both transactional (OLTP) and analytical (OLAP) workloads, making it suitable for a wide range of real-time data use cases. Here’s a detailed look at what a SingleStore cluster is and how it functions: + +
+  SingleStore Cluster +
Fig: SingleStore Cluster
+
+ +### Components of a SingleStore Cluster + +A SingleStore cluster is made up of two main types of nodes: + +- Aggregators: + - Purpose: These nodes act as query routers. Aggregators handle query parsing, optimization, and distribution to the other nodes in the cluster. They do not store data themselves. + - Role: Aggregators receive SQL queries, optimize them, and then route them to the appropriate leaf nodes that actually store and process the data. + - Benefits: They help balance the workload and ensure that queries are efficiently executed by leveraging the full processing power of the cluster. + +- Leaves: + - Purpose: These are the nodes responsible for data storage and processing. They store data in distributed partitions called shards. + - Role: Leaf nodes are responsible for executing the actual query tasks. They perform data retrieval, computation, and provide results back to the aggregators. + - Benefits: Leaf nodes ensure that data is distributed across the cluster, enabling horizontal scalability and high fault tolerance. + +### How a SingleStore Cluster Works + +- Data Sharding and Partitioning: + - In a SingleStore cluster, data is partitioned into `shards` that are distributed across multiple leaf nodes. Each shard is a portion of the overall dataset, and the distribution allows the workload to be spread evenly, improving both read and write performance. + - Sharding also allows for `parallel processing`, which enhances query performance by splitting tasks among several nodes. + +- Scalability: + - SingleStore clusters can be `scaled horizontally` by adding more nodes (both leaf and aggregator). As data volume grows, adding more leaf nodes allows the system to continue performing efficiently without the need for massive hardware upgrades. + - Aggregator nodes can also be scaled to handle more queries concurrently, helping balance the load during times of high user activity. + +- High Availability and Fault Tolerance: + - SingleStore clusters maintain multiple replicas of each shard on different leaf nodes. This replication provides `high availability (HA)` because if one node fails, another node holding a replica can take over, ensuring no data loss and minimizing downtime. + - The automatic failover and `self-healing` capabilities ensure that the system continues to operate smoothly even in the face of hardware or software failures. + +- Distributed Query Processing: + - When a query is submitted to an aggregator, it breaks down the query into smaller tasks and sends them to relevant leaf nodes. + - `Parallel processing` at the leaf nodes enables quick handling of large, complex queries, making it particularly effective for real-time analytics. + +- Hybrid Workload Handling: + - SingleStore is a `unified database`, meaning it can handle `both OLTP (Online Transaction Processing)` and `OLAP (Online Analytical Processing)` workloads within the same cluster. + - This capability is achieved by storing data in rowstore for fast transactions and `columnstore` for efficient analytical queries, which can be leveraged simultaneously. + +### Key Features of a SingleStore Cluster + +- Elastic Scaling: Nodes can be added or removed without significant downtime, allowing the system to adjust to changing workload requirements. +- In-Memory Storage: Data can be stored in memory to enhance processing speed, particularly useful for applications requiring real-time performance. +- Cloud Integration: SingleStore clusters are designed to work well in cloud environments, supporting deployments on cloud infrastructure or container orchestration platforms like `Kubernetes`. + +### Use Cases + +- Real-Time Analytics: The combination of in-memory processing and distributed architecture allows SingleStore clusters to handle real-time analytical queries over large datasets, which is valuable in industries like finance, retail, and IoT. +- Mixed Workloads: SingleStore can handle simultaneous read-heavy analytics and write-heavy transactional workloads, making it a good choice for applications that need both low-latency transactions and in-depth data analysis. +- Data Warehousing: The ability to process large volumes of data quickly also makes SingleStore suitable for `modern data warehousing`, where performance is crucial for handling big data operations. + +### Benefits of SingleStore Clusters + +- High Throughput: The distributed nature allows the system to support high data ingestion rates and large-scale analytical processing. +- Fault Tolerance: With multiple replicas of each shard, SingleStore clusters provide redundancy, helping to ensure that data is not lost and the system remains available. +- Simplified Management: SingleStore offers tools that simplify the management of clusters, including auto-failover and data rebalancing. + +### Limitations + +- Resource Overhead: Running a distributed cluster comes with extra costs in terms of hardware or cloud resources, especially due to the need for replication. +- Complexity in Management: Managing a large cluster, particularly in hybrid cloud or on-prem environments, can become complex and requires knowledge of distributed systems. +- Network Dependency: The cluster performance relies heavily on the network, and any issues with network latency or bandwidth can impact overall efficiency. + +## Next Steps + +- [Deploy SingleStore Cluster](/docs/guides/singlestore/clustering/singlestore-clustering) using KubeDB. \ No newline at end of file diff --git a/docs/guides/singlestore/clustering/singlestore-clustering/examples/sample-sdb.yaml b/docs/guides/singlestore/clustering/singlestore-clustering/examples/sample-sdb.yaml new file mode 100644 index 0000000000..6724836ede --- /dev/null +++ b/docs/guides/singlestore/clustering/singlestore-clustering/examples/sample-sdb.yaml @@ -0,0 +1,52 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.6" + requests: + memory: "2Gi" + cpu: "0.6" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.6" + requests: + memory: "2Gi" + cpu: "0.6" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/clustering/singlestore-clustering/index.md b/docs/guides/singlestore/clustering/singlestore-clustering/index.md new file mode 100644 index 0000000000..02a5ebab14 --- /dev/null +++ b/docs/guides/singlestore/clustering/singlestore-clustering/index.md @@ -0,0 +1,458 @@ +--- +title: Cluster Guide +menu: + docs_{{ .version }}: + identifier: guides-sdb-clustering + name: Cluster Guide + parent: sdb-clustering + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# KubeDB - SingleStore Cluster + +This tutorial will show you how to use KubeDB to provision a `singlestore cluster`. + +## Before You Begin + +Before proceeding: + +- Read [singlestore cluster concept](/docs/guides/singlestore/clustering/overview) to learn about SingleStore cluster. + +- You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: The yaml files used in this tutorial are stored in [docs/examples/singlestore](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/clustering/singlestore-clustering/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +## Create a SingleStore database + +KubeDB implements a `Singlestore` CRD to define the specification of a SingleStore database. Below is the `Singlestore` object created in this tutorial. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.6" + requests: + memory: "2Gi" + cpu: "0.6" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "0.6" + requests: + memory: "2Gi" + cpu: "0.6" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/clustering/singlestore-clustering/examples/sample-sdb.yaml +singlestore.kubedb.com/sample-sdb created +``` +Here, + +- `spec.version` is the name of the SinglestoreVersion CRD where the docker images are specified. In this tutorial, a SingleStore `8.7.10` database is going to be created. +- `spec.topology` specifies that it will be used as cluster mode. If this field is nil it will be work as standalone mode. +- `spec.topology.aggregator.replicas` or `spec.topology.leaf.replicas` specifies that the number replicas that will be used for aggregator or leaf. +- `spec.storageType` specifies the type of storage that will be used for SingleStore database. It can be `Durable` or `Ephemeral`. Default value of this field is `Durable`. If `Ephemeral` is used then KubeDB will create SingleStore database using `EmptyDir` volume. In this case, you don't have to specify `spec.storage` field. This is useful for testing purposes. +- `spec.topology.aggregator.storage` or `spec.topology.leaf.storage` specifies the StorageClass of PVC dynamically allocated to store data for this database. This storage spec will be passed to the PetSet created by KubeDB operator to run database pods. You can specify any StorageClass available in your cluster with appropriate resource requests. +- `spec.deletionPolicy` gives flexibility whether to `nullify`(reject) the delete operation of `Singlestore` crd or which resources KubeDB should keep or delete when you delete `Singlestore` crd. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. Learn details of all `DeletionPolicy` [here](/docs/guides/mysql/concepts/database/index.md#specdeletionpolicy) + +> Note: `spec.storage` section is used to create PVC for database pod. It will create PVC with storage size specified in `storage.resources.requests` field. Don't specify limits here. PVC does not get resized automatically. + +KubeDB operator watches for `Singlestore` objects using Kubernetes api. When a `Singlestore` object is created, KubeDB operator will create new PetSet and Service with the matching SingleStore object name. KubeDB operator will also create a governing service for PetSets, if one is not already present. + +```bash +$ kubectl get petset,pvc,pv,svc -n demo +NAME AGE +petset.apps.k8s.appscode.com/sample-sdb-aggregator 16m +petset.apps.k8s.appscode.com/sample-sdb-leaf 16m + +NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE +persistentvolumeclaim/data-sample-sdb-aggregator-0 Bound pvc-a6c9041cba69454a 10Gi RWO linode-block-storage-retain 16m +persistentvolumeclaim/data-sample-sdb-leaf-0 Bound pvc-674ba189a2f24383 10Gi RWO linode-block-storage-retain 16m +persistentvolumeclaim/data-sample-sdb-leaf-1 Bound pvc-16e4224adec54d96 10Gi RWO linode-block-storage-retain 16m + +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE +persistentvolume/pvc-16e4224adec54d96 10Gi RWO Retain Bound demo/data-sample-sdb-leaf-1 linode-block-storage-retain 16m +persistentvolume/pvc-674ba189a2f24383 10Gi RWO Retain Bound demo/data-sample-sdb-leaf-0 linode-block-storage-retain 16m +persistentvolume/pvc-a6c9041cba69454a 10Gi RWO Retain Bound demo/data-sample-sdb-aggregator-0 linode-block-storage-retain 16m + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/sample-sdb ClusterIP 10.128.15.230 3306/TCP,8081/TCP 16m +service/sample-sdb-pods ClusterIP None 3306/TCP 16m + + +``` + +KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified Singlestore object: + +```yaml +$ kubectl get sdb -n demo sample-sdb -oyaml +kind: Singlestore +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"kubedb.com/v1alpha2","kind":"Singlestore","metadata":{"annotations":{},"name":"sample-sdb","namespace":"demo"},"spec":{"deletionPolicy":"WipeOut","licenseSecret":{"name":"license-secret"},"storageType":"Durable","topology":{"aggregator":{"podTemplate":{"spec":{"containers":[{"name":"singlestore","resources":{"limits":{"cpu":"0.6","memory":"2Gi"},"requests":{"cpu":"0.6","memory":"2Gi"}}}]}},"replicas":1,"storage":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}},"leaf":{"podTemplate":{"spec":{"containers":[{"name":"singlestore","resources":{"limits":{"cpu":"0.6","memory":"2Gi"},"requests":{"cpu":"0.6","memory":"2Gi"}}}]}},"replicas":2,"storage":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}}}}},"version":"8.7.10"}} + creationTimestamp: "2024-10-01T09:39:36Z" + finalizers: + - kubedb.com + generation: 2 + name: sample-sdb + namespace: demo + resourceVersion: "117016" + uid: 22b254e0-d185-413c-888f-ca4c2524e909 +spec: + authSecret: + name: sample-sdb-root-cred + deletionPolicy: WipeOut + healthChecker: + failureThreshold: 1 + periodSeconds: 10 + timeoutSeconds: 10 + licenseSecret: + name: license-secret + storageType: Durable + topology: + aggregator: + podTemplate: + controller: {} + metadata: {} + spec: + containers: + - name: singlestore + resources: + limits: + cpu: 600m + memory: 2Gi + requests: + cpu: 600m + memory: 2Gi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + - name: singlestore-coordinator + resources: + limits: + memory: 256Mi + requests: + cpu: 200m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + initContainers: + - name: singlestore-init + resources: + limits: + memory: 512Mi + requests: + cpu: 200m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + podPlacementPolicy: + name: default + securityContext: + fsGroup: 999 + replicas: 1 + storage: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + podTemplate: + controller: {} + metadata: {} + spec: + containers: + - name: singlestore + resources: + limits: + cpu: 600m + memory: 2Gi + requests: + cpu: 600m + memory: 2Gi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + - name: singlestore-coordinator + resources: + limits: + memory: 256Mi + requests: + cpu: 200m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + initContainers: + - name: singlestore-init + resources: + limits: + memory: 512Mi + requests: + cpu: 200m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + podPlacementPolicy: + name: default + securityContext: + fsGroup: 999 + replicas: 2 + storage: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + version: 8.7.10 +status: + conditions: + - lastTransitionTime: "2024-10-01T09:39:36Z" + message: 'The KubeDB operator has started the provisioning of Singlestore: demo/sample-sdb' + observedGeneration: 1 + reason: DatabaseProvisioningStartedSuccessfully + status: "True" + type: ProvisioningStarted + - lastTransitionTime: "2024-10-01T09:57:51Z" + message: All leaf replicas are ready for Singlestore demo/sample-sdb + observedGeneration: 2 + reason: AllReplicasReady + status: "True" + type: ReplicaReady + - lastTransitionTime: "2024-10-01T09:41:04Z" + message: database demo/sample-sdb is accepting connection + observedGeneration: 2 + reason: AcceptingConnection + status: "True" + type: AcceptingConnection + - lastTransitionTime: "2024-10-01T09:41:04Z" + message: database demo/sample-sdb is ready + observedGeneration: 2 + reason: AllReplicasReady + status: "True" + type: Ready + - lastTransitionTime: "2024-10-01T09:41:05Z" + message: 'The Singlestore: demo/sample-sdb is successfully provisioned.' + observedGeneration: 2 + reason: DatabaseSuccessfullyProvisioned + status: "True" + type: Provisioned + phase: Ready + +``` + +## Connect with SingleStore database + +KubeDB operator has created a new Secret called `sample-sdb-root-cred` *(format: {singlestore-object-name}-root-cred)* for storing the password for `singlestore` superuser. This secret contains a `username` key which contains the *username* for SingleStore superuser and a `password` key which contains the *password* for SingleStore superuser. + +If you want to use an existing secret please specify that when creating the SingleStore object using `spec.authSecret.name`. While creating this secret manually, make sure the secret contains these two keys containing data `username` and `password` and also make sure of using `root` as value of `username`. For more details see [here](/docs/guides/mysql/concepts/database/index.md#specdatabasesecret). + +Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `sample-sdb-root-cred` secret holds username and password + +```bash +$ kubectl get pod -n demo sample-sdb-master-aggregator-0 -oyaml | grep podIP + podIP: 10.244.0.14 +$ kubectl get secrets -n demo sample-sdb-root-cred -o jsonpath='{.data.\username}' | base64 -d + root +$ kubectl get secrets -n demo sample-sdb-root-cred -o jsonpath='{.data.\password}' | base64 -d + J0h_BUdJB8mDO31u +``` +we will exec into the pod `sample-sdb-master-aggregator-0` and connect to the database using username and password + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulting container name to singlestore. +Use 'kubectl describe pod/sample-sdb-aggregator-0 -n demo' to see all of the containers in this pod. + +[memsql@sample-sdb-master-aggregator-0 /]$ memsql -uroot -p"J0h_BUdJB8mDO31u" +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 1114 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> show databases; ++--------------------+ +| Database | ++--------------------+ +| cluster | +| information_schema | +| memsql | +| singlestore_health | ++--------------------+ +4 rows in set (0.00 sec) + +singlestore> CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id)); +Query OK, 0 rows affected, 1 warning (0.27 sec) + +singlestore> SHOW TABLES IN playground; ++----------------------+ +| Tables_in_playground | ++----------------------+ +| equipment | ++----------------------+ +1 row in set (0.00 sec) + +singlestore> INSERT INTO playground.equipment (type, quant, color) VALUES ("slide", 2, "blue"); +Query OK, 1 row affected (1.15 sec) + +singlestore> SELECT * FROM playground.equipment; ++----+-------+-------+-------+ +| id | type | quant | color | ++----+-------+-------+-------+ +| 1 | slide | 2 | blue | ++----+-------+-------+-------+ +1 row in set (0.14 sec) + +singlestore> exit +Bye +``` +You can also connect with database management tools like [singlestore-studio](https://docs.singlestore.com/db/v8.5/reference/singlestore-tools-reference/singlestore-studio/) + +You can simply access to SingleStore studio by forwarding the Primary service port to any of your localhost port. Or, Accessing through ExternalP's 8081 port is also an option. + +```bash +$ kubectl port-forward -n demo service/sample-sdb 8081 +Forwarding from 127.0.0.1:8081 -> 8081 +Forwarding from [::1]:8081 -> 8081 +``` +Lets, open your browser and go to the http://localhost:8081 or with TLS https://localhost:8081 then click on `Add or Create Cluster` option. +Then choose `Add Existing Cluster` and click on `next` and you will get an interface like that below: + +

+  studio-1 +

+ +After giving the all information you can see like this below UI image. + +

+  studio-1 +

+ + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +kubectl patch -n demo singlestore/sample-sdb -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl delete -n demo singlestore/sample-sdb +kubectl delete ns demo +``` diff --git a/docs/guides/singlestore/concepts/_index.md b/docs/guides/singlestore/concepts/_index.md new file mode 100644 index 0000000000..1d9314c17b --- /dev/null +++ b/docs/guides/singlestore/concepts/_index.md @@ -0,0 +1,10 @@ +--- +title: SingleStore Concepts +menu: + docs_{{ .version }}: + identifier: sdb-concepts-singlestore + name: Concepts + parent: guides-singlestore + weight: 20 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/concepts/appbinding.md b/docs/guides/singlestore/concepts/appbinding.md new file mode 100644 index 0000000000..56aec98790 --- /dev/null +++ b/docs/guides/singlestore/concepts/appbinding.md @@ -0,0 +1,152 @@ +--- +title: AppBinding CRD +menu: + docs_{{ .version }}: + identifier: sdb-appbinding-concepts + name: AppBinding + parent: sdb-concepts-singlestore + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# AppBinding + +## What is AppBinding + +An `AppBinding` is a Kubernetes `CustomResourceDefinition`(CRD) which points to an application using either its URL (usually for a non-Kubernetes resident service instance) or a Kubernetes service object (if self-hosted in a Kubernetes cluster), some optional parameters and a credential secret. To learn more about AppBinding and the problems it solves, please read this blog post: [The case for AppBinding](https://appscode.com/blog/post/the-case-for-appbinding). + +If you deploy a database using [KubeDB](https://kubedb.com/docs/0.11.0/concepts/), `AppBinding` object will be created automatically for it. Otherwise, you have to create an `AppBinding` object manually pointing to your desired database. + +KubeDB uses [Stash](https://appscode.com/products/stash/) to perform backup/recovery of databases. Stash needs to know how to connect with a target database and the credentials necessary to access it. This is done via an `AppBinding`. + +## AppBinding CRD Specification + +Like any official Kubernetes resource, an `AppBinding` has `TypeMeta`, `ObjectMeta` and `Spec` sections. However, unlike other Kubernetes resources, it does not have a `Status` section. + +An `AppBinding` object created by `KubeDB` for SingleStore database is shown below, + +```yaml +apiVersion: appcatalog.appscode.com/v1alpha1 +kind: AppBinding +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"kubedb.com/v1alpha2","kind":"Singlestore","metadata":{"annotations":{},"name":"sdb","namespace":"demo"},"spec":{"deletionPolicy":"WipeOut","licenseSecret":{"name":"license-secret"},"storageType":"Durable","topology":{"aggregator":{"podTemplate":{"spec":{"containers":[{"name":"singlestore","resources":{"limits":{"cpu":"600m","memory":"2Gi"},"requests":{"cpu":"600m","memory":"2Gi"}}}]}},"replicas":2,"storage":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}},"leaf":{"podTemplate":{"spec":{"containers":[{"name":"singlestore","resources":{"limits":{"cpu":"600m","memory":"2Gi"},"requests":{"cpu":"600m","memory":"2Gi"}}}]}},"replicas":2,"storage":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}}}}},"version":"8.7.10"}} + creationTimestamp: "2024-08-15T09:04:57Z" + generation: 1 + labels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: sdb + app.kubernetes.io/managed-by: kubedb.com + app.kubernetes.io/name: singlestores.kubedb.com + name: sdb + namespace: demo + ownerReferences: + - apiVersion: kubedb.com/v1alpha2 + blockOwnerDeletion: true + controller: true + kind: Singlestore + name: sdb + uid: efeededa-7dc8-4e98-b4e4-0e0603adc32c + resourceVersion: "5633763" + uid: 77dc8123-52f6-4832-a6e2-478795e487b7 +spec: + appRef: + apiGroup: kubedb.com + kind: Singlestore + name: sdb + namespace: demo + clientConfig: + service: + name: sdb + path: / + port: 3306 + scheme: tcp + url: tcp(sdb.demo.svc:3306)/ + parameters: + apiVersion: config.kubedb.com/v1alpha1 + kind: SinglestoreConfiguration + masterAggregator: sdb-aggregator-0.sdb-pods.demo.svc + stash: + addon: + backupTask: + name: "" + restoreTask: + name: "" + secret: + name: sdb-root-cred + type: kubedb.com/singlestore + version: 8.7.10 +``` + +Here, we are going to describe the sections of an `AppBinding` crd. + +### AppBinding `Spec` + +An `AppBinding` object has the following fields in the `spec` section: + +#### spec.type + +`spec.type` is an optional field that indicates the type of the app that this `AppBinding` is pointing to. Stash uses this field to resolve the values of `TARGET_APP_TYPE`, `TARGET_APP_GROUP` and `TARGET_APP_RESOURCE` variables of [BackupBlueprint](https://appscode.com/products/stash/latest/concepts/crds/backupblueprint/) object. + +This field follows the following format: `/`. The above AppBinding is pointing to a `postgres` resource under `kubedb.com` group. + +Here, the variables are parsed as follows: + +| Variable | Usage | +| --------------------- |--------------------------------------------------------------------------------------------------------------------------------------| +| `TARGET_APP_GROUP` | Represents the application group where the respective app belongs (i.e: `kubedb.com`). | +| `TARGET_APP_RESOURCE` | Represents the resource under that application group that this appbinding represents (i.e: `singlestore`). | +| `TARGET_APP_TYPE` | Represents the complete type of the application. It's simply `TARGET_APP_GROUP/TARGET_APP_RESOURCE` (i.e: `kubedb.com/singlestore`). | + +#### spec.secret + +`spec.secret` specifies the name of the secret which contains the credentials that are required to access the database. This secret must be in the same namespace as the `AppBinding`. + +This secret must contain the following keys: + +SingleStore : + +| Key | Usage | +|------------|------------------------------------------------| +| `username` | Username of the target database. | +| `password` | Password for the user specified by `password`. | + +#### spec.appRef +appRef refers to the underlying application. It has 4 fields named `apiGroup`, `kind`, `name` & `namespace`. + +#### spec.clientConfig + +`spec.clientConfig` defines how to communicate with the target database. You can use either an URL or a Kubernetes service to connect with the database. You don't have to specify both of them. + +You can configure following fields in `spec.clientConfig` section: + +- **spec.clientConfig.url** + + `spec.clientConfig.url` gives the location of the database, in standard URL form (i.e. `[scheme://]host:port/[path]`). This is particularly useful when the target database is running outside of the Kubernetes cluster. If your database is running inside the cluster, use `spec.clientConfig.service` section instead. + +> Note that, attempting to use a user or basic auth (e.g. `user:password@host:port`) is not allowed. Stash will insert them automatically from the respective secret. Fragments ("#...") and query parameters ("?...") are not allowed either. + +- **spec.clientConfig.service** + + If you are running the database inside the Kubernetes cluster, you can use Kubernetes service to connect with the database. You have to specify the following fields in `spec.clientConfig.service` section if you manually create an `AppBinding` object. + + - **name :** `name` indicates the name of the service that connects with the target database. + - **scheme :** `scheme` specifies the scheme (i.e. http, https) to use to connect with the database. + - **port :** `port` specifies the port where the target database is running. + +- **spec.clientConfig.insecureSkipTLSVerify** + + `spec.clientConfig.insecureSkipTLSVerify` is used to disable TLS certificate verification while connecting with the database. We strongly discourage to disable TLS verification during backup. You should provide the respective CA bundle through `spec.clientConfig.caBundle` field instead. + +- **spec.clientConfig.caBundle** + + `spec.clientConfig.caBundle` is a PEM encoded CA bundle which will be used to validate the serving certificate of the database. + +## Next Steps + +- Learn how to use KubeDB to manage various databases [here](/docs/guides/README.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). \ No newline at end of file diff --git a/docs/guides/singlestore/concepts/autoscaler.md b/docs/guides/singlestore/concepts/autoscaler.md new file mode 100644 index 0000000000..7cdf268819 --- /dev/null +++ b/docs/guides/singlestore/concepts/autoscaler.md @@ -0,0 +1,152 @@ +--- +title: SingleStoreAutoscaler CRD +menu: + docs_{{ .version }}: + identifier: sdb-autoscaler-concepts + name: SingleStoreAutoscaler + parent: sdb-concepts-singlestore + weight: 26 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStoreAutoscaler + +## What is SingleStoreAutoscaler + +`SingleStoreAutoscaler` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative configuration for autoscaling [SingleStore](https://www.singlestore.com/) compute resources and storage of database components in a Kubernetes native way. + +## SingleStoreAutoscaler CRD Specifications + +Like any official Kubernetes resource, a `SingleStoreAutoscaler` has `TypeMeta`, `ObjectMeta`, `Spec` and `Status` sections. + +Here, some sample `SingleStoreAutoscaler` CROs for autoscaling different components of database is given below: + +**Sample `SingleStoreAutoscaler` for cluster database:** + +```yaml +apiVersion: autoscaling.kubedb.com/v1alpha1 +kind: SinglestoreAutoscaler +metadata: + name: sdb-as-cluster + namespace: demo +spec: + databaseRef: + name: sdb-sample + storage: + leaf: + trigger: "On" + usageThreshold: 30 + scalingThreshold: 50 + expansionMode: "Offline" + upperBound: "100Gi" + aggregator: + trigger: "On" + usageThreshold: 40 + scalingThreshold: 50 + expansionMode: "Offline" + upperBound: "100Gi" + compute: + aggregator: + trigger: "On" + podLifeTimeThreshold: 5m + minAllowed: + cpu: 900m + memory: 3000Mi + maxAllowed: + cpu: 2000m + memory: 6Gi + controlledResources: ["cpu", "memory"] + resourceDiffPercentage: 10 + leaf: + trigger: "On" + podLifeTimeThreshold: 5m + minAllowed: + cpu: 900m + memory: 3000Mi + maxAllowed: + cpu: 2000m + memory: 6Gi + controlledResources: ["cpu", "memory"] + resourceDiffPercentage: 10 +``` + +**Sample `SingleStoreAutoscaler` for standalone database:** + +```yaml +apiVersion: autoscaling.kubedb.com/v1alpha1 +kind: SinglestoreAutoscaler +metadata: + name: sdb-as-standalone + namespace: demo +spec: + databaseRef: + name: sdb-standalone + storage: + node: + trigger: "On" + usageThreshold: 40 + scalingThreshold: 50 + expansionMode: "Offline" + upperBound: "100Gi" + compute: + node: + trigger: "On" + podLifeTimeThreshold: 5m + minAllowed: + cpu: 900m + memory: 3000Mi + maxAllowed: + cpu: 2000m + memory: 6Gi + controlledResources: ["cpu", "memory"] + resourceDiffPercentage: 10 +``` + +Here, we are going to describe the various sections of a `SingleStoreAutoscaler` crd. + +A `SingleStoreAutoscaler` object has the following fields in the `spec` section. + +### spec.databaseRef + +`spec.databaseRef` is a required field that point to the [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) object for which the autoscaling will be performed. This field consists of the following sub-field: + +- **spec.databaseRef.name :** specifies the name of the [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) object. + +### spec.opsRequestOptions +These are the options to pass in the internally created opsRequest CRO. `opsRequestOptions` has three fields. They have been described in details [here](/docs/guides/singlestore/concepts/opsrequest.md#specreadinesscriteria). + +### spec.compute + +`spec.compute` specifies the autoscaling configuration for the compute resources i.e. cpu and memory of the database components. This field consists of the following sub-field: + +- `spec.compute.standalone` indicates the desired compute autoscaling configuration for a standalone SingleStore database. +- `spec.compute.aggregator` indicates the desired compute autoscaling configuration for aggregator node of cluster mode. +- `spec.compute.leaf` indicates the desired compute autoscaling configuration for the leaf node of cluster mode. + +All of them has the following sub-fields: + +- `trigger` indicates if compute autoscaling is enabled for this component of the database. If "On" then compute autoscaling is enabled. If "Off" then compute autoscaling is disabled. +- `minAllowed` specifies the minimal amount of resources that will be recommended, default is no minimum. +- `maxAllowed` specifies the maximum amount of resources that will be recommended, default is no maximum. +- `controlledResources` specifies which type of compute resources (cpu and memory) are allowed for autoscaling. Allowed values are "cpu" and "memory". +- `containerControlledValues` specifies which resource values should be controlled. Allowed values are "RequestsAndLimits" and "RequestsOnly". +- `resourceDiffPercentage` specifies the minimum resource difference between recommended value and the current value in percentage. If the difference percentage is greater than this value than autoscaling will be triggered. +- `podLifeTimeThreshold` specifies the minimum pod lifetime of at least one of the pods before triggering autoscaling. + +### spec.storage + +`spec.compute` specifies the autoscaling configuration for the storage resources of the database components. This field consists of the following sub-field: + +- `spec.compute.standalone` indicates the desired storage autoscaling configuration for a standalone SingleStore database. +- `spec.compute.leaf` indicates the desired storage autoscaling configuration for leaf node of cluster mode. +- `spec.compute.aggregator` indicates the desired storage autoscaling configuration for aggregator node of cluster mode. + +All of them has the following sub-fields: + +- `trigger` indicates if storage autoscaling is enabled for this component of the database. If "On" then storage autoscaling is enabled. If "Off" then storage autoscaling is disabled. +- `usageThreshold` indicates usage percentage threshold, if the current storage usage exceeds then storage autoscaling will be triggered. +- `scalingThreshold` indicates the percentage of the current storage that will be scaled. +- `expansionMode` indicates the volume expansion mode. diff --git a/docs/guides/singlestore/concepts/catalog.md b/docs/guides/singlestore/concepts/catalog.md new file mode 100644 index 0000000000..b9b143ff4e --- /dev/null +++ b/docs/guides/singlestore/concepts/catalog.md @@ -0,0 +1,105 @@ +--- +title: SingleStoreVersion CRD +menu: + docs_{{ .version }}: + identifier: sdb-catalog-concepts + name: SingleStoreVersion + parent: sdb-concepts-singlestore + weight: 15 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStoreVersion + +## What is SingleStoreVersion + +`SingleStoreVersion` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative configuration to specify the docker images to be used for [SingleStore](https://www.singlestore.com/) database deployed with KubeDB in a Kubernetes native way. + +When you install KubeDB, a `SingleStoreVersion` custom resource will be created automatically for every supported SingleStore versions. You have to specify the name of `SingleStoreVersion` crd in `spec.version` field of [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) crd. Then, KubeDB will use the docker images specified in the `SingleStoreVersion` crd to create your expected database. + +Using a separate crd for specifying respective docker images, and pod security policy names allow us to modify the images, and policies independent of KubeDB operator.This will also allow the users to use a custom image for the database. + +## SingleStoreVersion Spec + +As with all other Kubernetes objects, a SingleStoreVersion needs `apiVersion`, `kind`, and `metadata` fields. It also needs a `.spec` section. + +```yaml +apiVersion: catalog.kubedb.com/v1alpha1 +kind: SinglestoreVersion +metadata: + name: 8.7.10 +spec: + coordinator: + image: ghcr.io/kubedb/singlestore-coordinator:v0.3.0 + db: + image: ghcr.io/appscode-images/singlestore-node:alma-8.7.10-95e2357384 + initContainer: + image: ghcr.io/kubedb/singlestore-init:8.7.10-v1 + securityContext: + runAsGroup: 998 + runAsUser: 999 + standalone: + image: singlestore/cluster-in-a-box:alma-8.7.10-95e2357384-4.1.0-1.17.14 + updateConstraints: + allowlist: + - '> 8.7.10, <= 8.7.10' + version: 8.7.10 +``` + +### metadata.name + +`metadata.name` is a required field that specifies the name of the `SingleStoreVersion` crd. You have to specify this name in `spec.version` field of [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) crd. + +We follow this convention for naming SingleStoreVersion crd: + +- Name format: `{Original SingleStore image verion}-{modification tag}` + +We modify original SingleStore docker image to support SingleStore clustering and re-tag the image with v1, v2 etc. modification tag. An image with higher modification tag will have more features than the images with lower modification tag. Hence, it is recommended to use SingleStoreVersion crd with highest modification tag to enjoy the latest features. + +### spec.version + +`spec.version` is a required field that specifies the original version of SingleStore database that has been used to build the docker image specified in `spec.db.image` field. + +### spec.deprecated + +`spec.deprecated` is an optional field that specifies whether the docker images specified here is supported by the current KubeDB operator. + +The default value of this field is `false`. If `spec.deprecated` is set to `true`, KubeDB operator will skip processing this CRD object and will add a event to the CRD object specifying that the DB version is deprecated. + +### spec.db.image + +`spec.db.image` is a required field that specifies the docker image which will be used to create Petset by KubeDB operator to create expected SingleStore database. + +### spec.coordinator.image + +`spec.coordinator.image` is a required field that specifies the docker image which will be used to create Petset by KubeDB operator to create expected SingleStore database. + +### spec.initContainer.image + +`spec.initContainer.image` is a required field that specifies the image for init container. + +### spec.updateConstraints +updateConstraints specifies the constraints that need to be considered during version update. Here `allowList` contains the versions those are allowed for updating from the current version. +An empty list of AllowList indicates all the versions are accepted except the denyList. +On the other hand, `DenyList` contains all the rejected versions for the update request. An empty list indicates no version is rejected. + +### spec.podSecurityPolicies.databasePolicyName + +`spec.podSecurityPolicies.databasePolicyName` is a required field that specifies the name of the pod security policy required to get the database server pod(s) running. + +```bash +helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ + --namespace kubedb --create-namespace \ + --set additionalPodSecurityPolicies[0]=custom-db-policy \ + --set additionalPodSecurityPolicies[1]=custom-snapshotter-policy \ + --set-file global.license=/path/to/the/license.txt \ + --wait --burst-limit=10000 --debug +``` + +## Next Steps + +- Learn about SingleStore crd [here](/docs/guides/singlestore/concepts/singlestore.md). +- Deploy your first SingleStore database with KubeDB by following the guide [here](/docs/guides/singlestore/quickstart/quickstart.md). \ No newline at end of file diff --git a/docs/guides/singlestore/concepts/opsrequest.md b/docs/guides/singlestore/concepts/opsrequest.md new file mode 100644 index 0000000000..2a356704ea --- /dev/null +++ b/docs/guides/singlestore/concepts/opsrequest.md @@ -0,0 +1,475 @@ +--- +title: SingleStoreOpsRequests CRD +menu: + docs_{{ .version }}: + identifier: sdb-opsrequest-concepts + name: SingleStoreOpsRequest + parent: sdb-concepts-singlestore + weight: 25 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStoreOpsRequest + +## What is SingleStoreOpsRequest + +`SingleStoreOpsRequest` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative configuration for [SingleStore](https://www.singlestore.com/) administrative operations like database version updating, horizontal scaling, vertical scaling etc. in a Kubernetes native way. + +## SingleStoreOpsRequest CRD Specifications + +Like any official Kubernetes resource, a `SingleStoreOpsRequest` has `TypeMeta`, `ObjectMeta`, `Spec` and `Status` sections. + +Here, some sample `SingleStoreOpsRequest` CRs for different administrative operations is given below: + +**Sample `SingleStoreOpsRequest` for updating database:** + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-version-upd + namespace: demo +spec: + type: UpdateVersion + databaseRef: + name: sdb + updateVersion: + targetVersion: 8.7.10 + timeout: 5m + apply: IfReady +``` + +**Sample `SingleStoreOpsRequest` Objects for Horizontal Scaling of different component of the database:** + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-hscale + namespace: demo +spec: + type: HorizontalScaling + databaseRef: + name: sdb + horizontalScaling: + aggregator: 2 + leaf: 3 +``` + +**Sample `SingleStoreOpsRequest` Objects for Vertical Scaling of different component of the database:** + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-scale + namespace: demo +spec: + type: VerticalScaling + databaseRef: + name: sdb-sample + verticalScaling: + leaf: + resources: + requests: + memory: "2500Mi" + cpu: "0.7" + limits: + memory: "2500Mi" + cpu: "0.7" + coordinator: + resources: + requests: + memory: "2500Mi" + cpu: "0.7" + limits: + memory: "2500Mi" + cpu: "0.7" + node: + resources: + requests: + memory: "2500Mi" + cpu: "0.7" + limits: + memory: "2500Mi" + cpu: "0.7" +``` + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-scale + namespace: demo +spec: + type: VerticalScaling + databaseRef: + name: sdb-standalone + verticalScaling: + node: + resources: + requests: + memory: "2500Mi" + cpu: "0.7" + limits: + memory: "2500Mi" + cpu: "0.7" +``` + +**Sample `SingleStoreOpsRequest` Objects for Reconfiguring different database components:** + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-config + namespace: demo +spec: + type: Configuration + databaseRef: + name: sdb-sample + configuration: + aggregator: + applyConfig: + sdb-apply.cnf: |- + max_connections = 550 + leaf: + applyConfig: + sdb-apply.cnf: |- + max_connections = 550 +``` + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-config + namespace: demo +spec: + type: Configuration + databaseRef: + name: sdb-standalone + configuration: + node: + applyConfig: + sdb-apply.cnf: |- + max_connections = 550 +``` + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-config + namespace: demo +spec: + type: Configuration + databaseRef: + name: sdb-sample + configuration: + aggregator: + configSecret: + name: sdb-new-custom-config + leaf: + configSecret: + name: sdb-new-custom-config +``` + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-config + namespace: demo +spec: + type: Configuration + databaseRef: + name: sdb-standalone + configuration: + node: + configSecret: + name: sdb-new-custom-config +``` + +**Sample `SingleStoreOpsRequest` Objects for Volume Expansion of different database components:** + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-volume-ops + namespace: demo +spec: + type: VolumeExpansion + databaseRef: + name: sdb-sample + volumeExpansion: + mode: "Offline" + aggregator: 10Gi + leaf: 20Gi +``` + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-volume-ops + namespace: demo +spec: + type: VolumeExpansion + databaseRef: + name: sdb-standalone + volumeExpansion: + mode: "Online" + node: 20Gi +``` + +**Sample `SingleStoreOpsRequest` Objects for Reconfiguring TLS of the database:** + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-tls-reconfigure + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sdb-sample + tls: + issuerRef: + name: sdb-issuer + kind: Issuer + apiGroup: "cert-manager.io" + certificates: + - alias: client + subject: + organizations: + - singlestore + organizationalUnits: + - client +``` + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-tls-reconfigure + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sdb-sample + tls: + rotateCertificates: true +``` + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-tls-reconfigure + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sdb-sample + tls: + remove: true +``` + +Here, we are going to describe the various sections of a `SingleStoreOpsRequest` crd. + +A `SingleStoreOpsRequest` object has the following fields in the `spec` section. + +### spec.databaseRef + +`spec.databaseRef` is a required field that point to the [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) object for which the administrative operations will be performed. This field consists of the following sub-field: + +- **spec.databaseRef.name :** specifies the name of the [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) object. + +### spec.type + +`spec.type` specifies the kind of operation that will be applied to the database. Currently, the following types of operations are allowed in `SingleStoreOpsRequest`. + +- `Upgrade` / `UpdateVersion` +- `HorizontalScaling` +- `VerticalScaling` +- `VolumeExpansion` +- `Reconfigure` +- `ReconfigureTLS` +- `Restart` + +> You can perform only one type of operation on a single `SingleStoreOpsRequest` CR. For example, if you want to update your database and scale up its replica then you have to create two separate `SingleStoreOpsRequest`. At first, you have to create a `SingleStoreOpsRequest` for updating. Once it is completed, then you can create another `SingleStoreOpsRequest` for scaling. + +> Note: There is an exception to the above statement. It is possible to specify both `spec.configuration` & `spec.verticalScaling` in a OpsRequest of type `VerticalScaling`. + +### spec.updateVersion + +If you want to update you SingleStore version, you have to specify the `spec.updateVersion` section that specifies the desired version information. This field consists of the following sub-field: + +- `spec.updateVersion.targetVersion` refers to a [SingleStoreVersion](/docs/guides/singlestore/concepts/catalog.md) CR that contains the SingleStore version information where you want to update. + +Have a look on the [`updateConstraints`](/docs/guides/singlestore/concepts/catalog.md#specupdateconstraints) of the singlestoreVersion spec to know which versions are supported for updating from the current version. +```yaml +kubectl get sdbversion -o=jsonpath='{.spec.updateConstraints}' | jq +``` + +> You can only update between SingleStore versions. KubeDB does not support downgrade for SingleStore. + +### spec.horizontalScaling + +If you want to scale-up or scale-down your SingleStore cluster or different components of it, you have to specify `spec.horizontalScaling` section. This field consists of the following sub-field: + +- `spec.horizontalScaling.aggregator.replicas` indicates the desired number of aggregator nodes for cluster mode after scaling. +- `spec.horizontalScaling.leaf.replicas` indicates the desired number of leaf nodes for cluster mode after scaling. + +### spec.verticalScaling + +`spec.verticalScaling` is a required field specifying the information of `SingleStore` resources like `cpu`, `memory` etc that will be scaled. This field consists of the following sub-fields: + +- `spec.verticalScaling.node` indicates the desired resources for standalone SingleStore database after scaling. +- `spec.verticalScaling.aggregator` indicates the desired resources for aggregator node of SingleStore cluster after scaling. +- `spec.verticalScaling.leaf` indicates the desired resources for leaf nodes of SingleStore cluster after scaling. +- `spec.verticalScaling.coordinator` indicates the desired resources for the coordinator container. + +All of them has the below structure: + +```yaml +requests: + memory: "2000Mi" + cpu: "0.7" +limits: + memory: "3000Mi" + cpu: "0.9" +``` + +Here, when you specify the resource request, the scheduler uses this information to decide which node to place the container of the Pod on and when you specify a resource limit for the container, the `kubelet` enforces those limits so that the running container is not allowed to use more of that resource than the limit you set. You can found more details from [here](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +### spec.volumeExpansion + +> To use the volume expansion feature the storage class must support volume expansion + +If you want to expand the volume of your SingleStore cluster or different components of it, you have to specify `spec.volumeExpansion` section. This field consists of the following sub-field: + +- `spec.mode` specifies the volume expansion mode. Supported values are `Online` & `Offline`. The default is `Online`. +- `spec.volumeExpansion.node` indicates the desired size for the persistent volume of a standalone SingleStore database. +- `spec.volumeExpansion.aggregator` indicates the desired size for the persistent volume of aggregator node of cluster. +- `spec.volumeExpansion.leaf` indicates the desired size for the persistent volume of leaf node of cluster. + +All of them refer to [Quantity](https://v1-22.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#quantity-resource-core) types of Kubernetes. + +Example usage of this field is given below: + +```yaml +spec: + volumeExpansion: + aggregator: "20Gi" +``` + +This will expand the volume size of all the shard nodes to 20 GB. + +### spec.configuration + +If you want to reconfigure your Running SingleStore cluster or different components of it with new custom configuration, you have to specify `spec.configuration` section. This field consists of the following sub-field: + +- `spec.configuration.standalone` indicates the desired new custom configuration for a standalone SingleStore database. +- `spec.configuration.aggregator` indicates the desired new custom configuration for aggregator node of cluster mode. +- `spec.configuration.leaf` indicates the desired new custom configuration for leaf node of cluster mode. + +All of them has the following sub-fields: + +- `configSecret` points to a secret in the same namespace of a SingleStore resource, which contains the new custom configurations. If there are any configSecret set before in the database, this secret will replace it. +- `applyConfig` contains the new custom config as a string which will be merged with the previous configuration. + +- `applyConfig` is a map where key supports values, namely `sdb-apply.cnf`. And value represents the corresponding configurations. +KubeDB provisioner operator applies these two directly while reconciling. + +```yaml + applyConfig: + sdb-apply.cnf: |- + max_connections = 550 +``` + +- `removeCustomConfig` is a boolean field. Specify this field to true if you want to remove all the custom configuration from the deployed singlestore server. + +### spec.tls + +If you want to reconfigure the TLS configuration of your database i.e. add TLS, remove TLS, update issuer/cluster issuer or Certificates and rotate the certificates, you have to specify `spec.tls` section. This field consists of the following sub-field: + +- `spec.tls.issuerRef` specifies the issuer name, kind and api group. +- `spec.tls.certificates` specifies the certificates. You can learn more about this field from [here](/docs/guides/singlestore/concepts/singlestore.md#spectls). +- `spec.tls.rotateCertificates` specifies that we want to rotate the certificate of this database. +- `spec.tls.remove` specifies that we want to remove tls from this database. + + +### spec.timeout +As we internally retry the ops request steps multiple times, This `timeout` field helps the users to specify the timeout for those steps of the ops request (in second). +If a step doesn't finish within the specified timeout, the ops request will result in failure. + +### spec.apply +This field controls the execution of obsRequest depending on the database state. It has two supported values: `Always` & `IfReady`. +Use IfReady, if you want to process the opsRequest only when the database is Ready. And use Always, if you want to process the execution of opsReq irrespective of the Database state. + + +### SingleStoreOpsRequest `Status` + +`.status` describes the current state and progress of a `SingleStoreOpsRequest` operation. It has the following fields: + +### status.phase + +`status.phase` indicates the overall phase of the operation for this `SingleStoreOpsRequest`. It can have the following three values: + +| Phase | Meaning | +|-------------|----------------------------------------------------------------------------------------| +| Successful | KubeDB has successfully performed the operation requested in the SingleStoreOpsRequest | +| Progressing | KubeDB has started the execution of the applied SingleStoreOpsRequest | +| Failed | KubeDB has failed the operation requested in the SingleStoreOpsRequest | +| Denied | KubeDB has denied the operation requested in the SingleStoreOpsRequest | +| Skipped | KubeDB has skipped the operation requested in the SingleStoreOpsRequest | + +Important: Ops-manager Operator can skip an opsRequest, only if its execution has not been started yet & there is a newer opsRequest applied in the cluster. `spec.type` has to be same as the skipped one, in this case. + +### status.observedGeneration + +`status.observedGeneration` shows the most recent generation observed by the `SingleStoreOpsRequest` controller. + +### status.conditions + +`status.conditions` is an array that specifies the conditions of different steps of `SingleStoreOpsRequest` processing. Each condition entry has the following fields: + +- `types` specifies the type of the condition. SingleStoreOpsRequest has the following types of conditions: + +| Type | Meaning | +|-----------------------------|----------------------------------------------------------------------------| +| `Progressing` | Specifies that the operation is now in the progressing state | +| `Successful` | Specifies such a state that the operation on the database was successful. | +| `HaltDatabase` | Specifies such a state that the database is halted by the operator | +| `ResumeDatabase` | Specifies such a state that the database is resumed by the operator | +| `Failed` | Specifies such a state that the operation on the database failed. | +| `StartingBalancer` | Specifies such a state that the balancer has successfully started | +| `StoppingBalancer` | Specifies such a state that the balancer has successfully stopped | +| `UpdatePetSetResources` | Specifies such a state that the PetSet resources has been updated | +| `UpdateAggregatorResources` | Specifies such a state that the Aggregator resources has been updated | +| `UpdateLeafResources` | Specifies such a state that the Leaf resources has been updated | +| `UpdateNodeResources` | Specifies such a state that the node has been updated | +| `ScaleDownAggregator` | Specifies such a state that the scale down operation of aggregator | +| `ScaleUpAggregator` | Specifies such a state that the scale up operation of aggregator | +| `ScaleUpLeaf` | Specifies such a state that the scale up operation of leaf | +| `ScaleDownleaf` | Specifies such a state that the scale down operation of leaf | +| `VolumeExpansion` | Specifies such a state that the volume expansion operation of the database | +| `ReconfigureAggregator` | Specifies such a state that the reconfiguration of aggregator nodes | +| `ReconfigureLeaf` | Specifies such a state that the reconfiguration of leaf nodes | +| `ReconfigureNode` | Specifies such a state that the reconfiguration of standalone nodes | + +- The `status` field is a string, with possible values `True`, `False`, and `Unknown`. + - `status` will be `True` if the current transition succeeded. + - `status` will be `False` if the current transition failed. + - `status` will be `Unknown` if the current transition was denied. +- The `message` field is a human-readable message indicating details about the condition. +- The `reason` field is a unique, one-word, CamelCase reason for the condition's last transition. +- The `lastTransitionTime` field provides a timestamp for when the operation last transitioned from one state to another. +- The `observedGeneration` shows the most recent condition transition generation observed by the controller. \ No newline at end of file diff --git a/docs/guides/singlestore/concepts/singlestore.md b/docs/guides/singlestore/concepts/singlestore.md new file mode 100644 index 0000000000..3d1b2fb66a --- /dev/null +++ b/docs/guides/singlestore/concepts/singlestore.md @@ -0,0 +1,322 @@ +--- +title: SingleStore CRD +menu: + docs_{{ .version }}: + identifier: sdb-singlestore-concepts + name: SingleStore + parent: sdb-concepts-singlestore + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- +# SingleStore + +## What is SingleStore + +`SingleStore` is a Kubernetes `Custom Resource Definitions` (CRD). It provides declarative configuration for [SingleStore](https://www.singlestore.com/) in a Kubernetes native way. You only need to describe the desired database configuration in a SingleStore object, and the KubeDB operator will create Kubernetes objects in the desired state for you. + +## SingleStore Spec + +As with all other Kubernetes objects, a SingleStore needs `apiVersion`, `kind`, and `metadata` fields. It also needs a `.spec` section. Below is an example SingleStore object. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "4Gi" + cpu: "1000m" + requests: + memory: "2Gi" + cpu: "500m" + storage: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 3 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "5Gi" + cpu: "1100m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 40Gi + storageType: Durable + licenseSecret: + name: license-secret + authSecret: + name: given-secret + init: + script: + configMap: + name: sdb-init-script + monitor: + agent: prometheus.io/operator + prometheus: + exporter: + port: 9104 + serviceMonitor: + labels: + release: prometheus + interval: 10s + deletionPolicy: WipeOut + tls: + issuerRef: + apiGroup: cert-manager.io + kind: Issuer + name: sdb-issuer + certificates: + - alias: server + subject: + organizations: + - kubedb:server + dnsNames: + - localhost + ipAddresses: + - "127.0.0.1" + serviceTemplates: + - alias: primary + metadata: + annotations: + passMe: ToService + spec: + type: NodePort + ports: + - name: http + port: 9200 +``` + +### spec.version + +`spec.version` is a required field specifying the name of the [SinglestoreVersion](/docs/guides/singlestore/concepts/catalog.md) crd where the docker images are specified. Currently, when you install KubeDB, it creates the following `SinglestoreVersion` resources, + +- `8.1.32` +- `8.5.7`, `8.5.30` +- `8.7.10` + +### spec.topology + +`spec.topology` is an optional field that enables you to specify the clustering mode. + +- `aggregator` or `leaf` are optional field that configure cluster mode that contains the following fields: + - `replicas` the number of nodes of `aggregator` and `leaf` in cluster mode. + - `configSecret` is an optional field that points to a Secret used to hold custom SingleStore configuration. + - `podTemplate` providing a template for database. KubeDB operator will pass the information provided in `podTemplate` to the PetSet created for the SingleStore database. KubeDB accepts the following fields to set in `podTemplate:` + - metadata: + - annotations (pod's annotation) + - controller: + - annotations (petset's annotation) + - spec: + - initContainers + - imagePullSecrets + - resources + - containers + - nodeSelector + - serviceAccountName + - securityContext + - tolerations + - imagePullSecrets + - podPlacementPolicy + - volumes + - If you set `spec.storageType` to `Durable`, then `storage` is a required field that specifies the StorageClass of PVCs dynamically allocated to store data for the database. This storage spec will be passed to the PetSet created by KubeDB operator to run database pods. You can specify any StorageClass available in your cluster with appropriate resource requests. + - `storage.storageClassName` is the name of the StorageClass used to provision PVCs. PVCs don’t necessarily have to request a class. A PVC with its storageClassName set equal to "" is always interpreted to be requesting a PV with no class, so it can only be bound to PVs with no class (no annotation or one set equal to ""). A PVC with no storageClassName is not quite the same and is treated differently by the cluster depending on whether the DefaultStorageClass admission plugin is turned on. + - `storage.accessModes` uses the same conventions as Kubernetes PVCs when requesting storage with specific access modes. + - `storage.resources` can be used to request specific quantities of storage. This follows the same resource model used by PVCs. + To learn how to configure `storage`, please visit the links below: + - https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims + +### spec.storageType + +`spec.storageType` is an optional field that specifies the type of storage to use for database. It can be either `Durable` or `Ephemeral`. The default value of this field is `Durable`. If `Ephemeral` is used then KubeDB will create Kafka cluster using [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) volume. + +### spec.licenseSecret + +`spec.licenseSecret` is a mandatory fields points to a secret used to pass SingleStore license. + +### spec.authSecret + +`spec.authSecret` is an optional field that points to a Secret used to hold credentials for `singlestore` root user. If not set, the KubeDB operator creates a new Secret `{singlestore-object-name}-cred` for storing the password for `singlestore` root user for each SingleStore object. If you want to use an existing secret please specify that when creating the SingleStore object using `spec.authSecret.name`. + +This secret contains a `user` key and a `password` key which contains the `username` and `password` respectively for `singlestore` root user. Here, the value of `user` key is fixed to be `root`. + +Secrets provided by users are not managed by KubeDB, and therefore, won't be modified or garbage collected by the KubeDB operator (version 0.13.0 and higher). + +Example: + +```bash +$ kubectl create secret generic sdb-cred -n demo \ +--from-literal=user=root \ +--from-literal=password=6q8u_2jMOW-OOZXk +secret "sdb-cred" created +``` + +```yaml +apiVersion: v1 +data: + password: NnE4dV8yak1PVy1PT1pYaw== + user: cm9vdA== +kind: Secret +metadata: + name: sdb-cred + namespace: demo +type: Opaque +``` + +#### Initialize via Script + +To initialize a SingleStore database using a script (shell script, sql script, etc.), set the `spec.init.script` section when creating a SingleStore object. It will execute files alphabetically with extensions `.sh` , `.sql` and `.sql.gz` that is found in the repository. The scripts inside child folders will be skipped. script must have the following information: + +- [VolumeSource](https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes): Where your script is loaded from. + +Below is an example showing how a script from a configMap can be used to initialize a SingleStore database. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb + namespace: demo +spec: + version: 8.7.10 + init: + script: + configMap: + name: sdb-init-script + licenseSecret: + name: license-secret +``` + +In the above example, KubeDB operator will launch a Job to execute all js script of `sdb-init-script` in alphabetical order once PetSet pods are running. For more details tutorial on how to initialize from script, please visit [here](/docs/guides/mysql/initialization/index.md). + +### spec.monitor + +SingleStore managed by KubeDB can be monitored with builtin-Prometheus and Prometheus operator. To learn more, + +- [Monitor SingleStore with builtin Prometheus](/docs/guides/singlestore/monitoring/builtin-prometheus/index.md) +- [Monitor SingleStore with Prometheus operator](/docs/guides/singlestore/monitoring/prometheus-operator/index.md) + +### spec.tls + +`spec.tls` specifies the TLS/SSL configurations for the SingleStore. + +The following fields are configurable in the `spec.tls` section: + +- `issuerRef` is a reference to the `Issuer` or `ClusterIssuer` CR of [cert-manager](https://cert-manager.io/docs/concepts/issuer/) that will be used by `KubeDB` to generate necessary certificates. + + - `apiGroup` is the group name of the resource being referenced. The value for `Issuer` or `ClusterIssuer` is "cert-manager.io" (cert-manager v0.12.0 and later). + - `kind` is the type of resource being referenced. KubeDB supports both `Issuer` and `ClusterIssuer` as values for this field. + - `name` is the name of the resource (`Issuer` or `ClusterIssuer`) being referenced. + +- `certificates` (optional) are a list of certificates used to configure the server and/or client certificate. It has the following fields: + + - `alias` represents the identifier of the certificate. It has the following possible value: + - `server` is used for server certificate identification. + - `client` is used for client certificate identification. + - `metrics-exporter` is used for metrics exporter certificate identification. + - `secretName` (optional) specifies the k8s secret name that holds the certificates. + >This field is optional. If the user does not specify this field, the default secret name will be created in the following format: `--cert`. + - `subject` (optional) specifies an `X.509` distinguished name. It has the following possible field, + - `organizations` (optional) are the list of different organization names to be used on the Certificate. + - `organizationalUnits` (optional) are the list of different organization unit name to be used on the Certificate. + - `countries` (optional) are the list of country names to be used on the Certificate. + - `localities` (optional) are the list of locality names to be used on the Certificate. + - `provinces` (optional) are the list of province names to be used on the Certificate. + - `streetAddresses` (optional) are the list of a street address to be used on the Certificate. + - `postalCodes` (optional) are the list of postal code to be used on the Certificate. + - `serialNumber` (optional) is a serial number to be used on the Certificate. + You can found more details from [Here](https://golang.org/pkg/crypto/x509/pkix/#Name) + + - `duration` (optional) is the period during which the certificate is valid. + - `renewBefore` (optional) is a specifiable time before expiration duration. + - `dnsNames` (optional) is a list of subject alt names to be used in the Certificate. + - `ipAddresses` (optional) is a list of IP addresses to be used in the Certificate. + - `uriSANs` (optional) is a list of URI Subject Alternative Names to be set in the Certificate. + - `emailSANs` (optional) is a list of email Subject Alternative Names to be set in the Certificate. + +### spec.serviceTemplates + +You can also provide template for the services created by KubeDB operator for Kafka cluster through `spec.serviceTemplates`. This will allow you to set the type and other properties of the services. + +KubeDB allows following fields to set in `spec.serviceTemplates`: +- `alias` represents the identifier of the service. It has the following possible value: + - `stats` is used for the exporter service identification. +- metadata: + - labels + - annotations +- spec: + - type + - ports + - clusterIP + - externalIPs + - loadBalancerIP + - loadBalancerSourceRanges + - externalTrafficPolicy + - healthCheckNodePort + - sessionAffinityConfig + +See [here](https://github.com/kmodules/offshoot-api/blob/kubernetes-1.21.1/api/v1/types.go#L237) to understand these fields in detail. + +### spec.deletionPolicy + +`deletionPolicy` gives flexibility whether to `nullify`(reject) the delete operation of `singlestore` crd or which resources KubeDB should keep or delete when you delete `singlestore` crd. KubeDB provides following four deletion policies: + +- DoNotTerminate +- WipeOut +- Halt +- Delete + +When `deletionPolicy` is `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, `DoNotTerminate` prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. + +Following table show what KubeDB does when you delete MySQL crd for different termination policies, + +| Behavior | DoNotTerminate | Halt | Delete | WipeOut | +|---------------------------| :------------: | :------: | :------: | :------: | +| 1. Block Delete operation | ✓ | ✗ | ✗ | ✗ | +| 2. Delete PetSet | ✗ | ✓ | ✓ | ✓ | +| 3. Delete Services | ✗ | ✓ | ✓ | ✓ | +| 4. Delete PVCs | ✗ | ✗ | ✓ | ✓ | +| 5. Delete Secrets | ✗ | ✗ | ✗ | ✓ | +| 6. Delete Snapshots | ✗ | ✗ | ✗ | ✓ | + +If you don't specify `spec.deletionPolicy` KubeDB uses `Delete` termination policy by default. + +## spec.healthChecker +It defines the attributes for the health checker. +- `spec.healthChecker.periodSeconds` specifies how often to perform the health check. +- `spec.healthChecker.timeoutSeconds` specifies the number of seconds after which the probe times out. +- `spec.healthChecker.failureThreshold` specifies minimum consecutive failures for the healthChecker to be considered failed. +- `spec.healthChecker.disableWriteCheck` specifies whether to disable the writeCheck or not. + +## Next Steps + +- Learn how to use KubeDB to run a SingleStore database [here](/docs/guides/singlestore/README.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). \ No newline at end of file diff --git a/docs/guides/singlestore/configuration/_index.md b/docs/guides/singlestore/configuration/_index.md new file mode 100755 index 0000000000..6580eb5067 --- /dev/null +++ b/docs/guides/singlestore/configuration/_index.md @@ -0,0 +1,10 @@ +--- +title: Run SingleStore with Custom Configuration +menu: + docs_{{ .version }}: + identifier: guides-sdb-configuration + name: Custom Configuration + parent: guides-singlestore + weight: 30 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/configuration/config-file/index.md b/docs/guides/singlestore/configuration/config-file/index.md new file mode 100644 index 0000000000..6106d9ef4c --- /dev/null +++ b/docs/guides/singlestore/configuration/config-file/index.md @@ -0,0 +1,247 @@ +--- +title: Run SingleStore with Custom Configuration +menu: + docs_{{ .version }}: + identifier: guides-sdb-configuration-using-config-file + name: Config File + parent: guides-sdb-configuration + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Using Custom Configuration File + +KubeDB supports providing custom configuration for SingleStore. This tutorial will show you how to use KubeDB to run a SingleStore database with custom configuration. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + + $ kubectl get ns demo + NAME STATUS AGE + demo Active 5s + ``` + +> Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/configuration/config-file/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/configuration/config-file/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Overview + +SingleStore allows to configure database via configuration file. The default configuration for SingleStore can be found in `/var/lib/memsql/instance/memsql.cnf` file. When SingleStore starts, it will look for custom configuration file in `/etc/memsql/conf.d` directory. If configuration file exist, SingleStore instance will use combined startup setting from both `/var/lib/memsql/instance/memsql.cnf` and `*.cnf` files in `/etc/memsql/conf.d` directory. This custom configuration will overwrite the existing default one. To know more about configuring SingleStore see [here](https://docs.singlestore.com/db/v8.7/reference/configuration-reference/cluster-config-files/singlestore-server-config-files/). + +At first, you have to create a config file with `.cnf` extension with your desired configuration. Then you have to put this file into a [volume](https://kubernetes.io/docs/concepts/storage/volumes/). You need to specify this volume in the `spec.configSecret` section when creating the SingleStore CRD for `Standalone` mode. Additionally, you can modify your `aggregator` and `leaf` nodes separately by providing separate configSecrets, or use the same one in the `spec.topology.aggregator.configSecret` and `spec.topology.leaf.configSecret` sections when creating the SingleStore CRD for `Cluster` mode. KubeDB will mount this volume into `/etc/memsql/conf.d` directory of the database pod. + +In this tutorial, we will configure [max_connections](https://docs.singlestore.com/db/v8.7/reference/configuration-reference/engine-variables/list-of-engine-variables/#in-depth-variable-definitions) and [read_buffer_size](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_read_buffer_size) via a custom config file. We will use configMap as volume source. + +## Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +## Custom Configuration + +At first, let's create `sdb-config.cnf` file setting `max_connections` and `read_buffer_size` parameters. + +```bash +cat < sdb-config.cnf +[server] +max_connections = 250 +read_buffer_size = 1048576 +EOF + +$ cat sdb-config.cnf +[server] +max_connections = 250 +read_buffer_size = 122880 +``` + +Now, create a secret with this configuration file. + +```bash +$ kubectl create secret generic -n demo sdb-configuration --from-file=./sdb-config.cnf +configmap/sdb-configuration created +``` + +Verify the secret has the configuration file. + +```yaml +$ kubectl get secret -n demo sdb-configuration -o yaml +apiVersion: v1 +data: + sdb-config.cnf: W3NlcnZlcl0KbWF4X2Nvbm5lY3Rpb25zID0gMjUwCnJlYWRfYnVmZmVyX3NpemUgPSAxMjI4ODAK +kind: Secret +metadata: + creationTimestamp: "2024-10-02T12:54:35Z" + name: sdb-configuration + namespace: demo + resourceVersion: "99627" + uid: c2621d8e-ebca-4300-af05-0180512ce031 +type: Opaque + + +``` + +Now, create SingleStore crd specifying `spec.topology.aggregator.configSecret` and `spec.topology.leaf.configSecret` field. + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/config-file/yamls/sdb-custom.yaml +singlestore.kubedb.com/custom-sdb created +``` + +Below is the YAML for the SingleStore crd we just created. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: custom-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. + +Check that the petset's pod is running + +```bash +$ kubectl get pod -n demo +NAME READY STATUS RESTARTS AGE +custom-sdb-aggregator-0 2/2 Running 0 94s +custom-sdb-aggregator-1 2/2 Running 0 88s +custom-sdb-leaf-0 2/2 Running 0 91s +custom-sdb-leaf-1 2/2 Running 0 86s + +$ kubectl get sdb -n demo +NAME TYPE VERSION STATUS AGE +custom-sdb kubedb.com/v1alpha2 8.7.10 Ready 4m29s + +``` + +We can see the database is in ready phase so it can accept conncetion. + +Now, we will check if the database has started with the custom configuration we have provided. + +> Read the comment written for the following commands. They contain the instructions and explanations of the commands. + +```bash +# Connceting to the database +$ kubectl exec -it -n demo custom-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@custom-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 208 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +# value of `max_conncetions` is same as provided +singlestore> show variables like 'max_connections'; ++-----------------+-------+ +| Variable_name | Value | ++-----------------+-------+ +| max_connections | 250 | ++-----------------+-------+ +1 row in set (0.00 sec) + +# value of `read_buffer_size` is same as provided +singlestore> show variables like 'read_buffer_size'; ++------------------+--------+ +| Variable_name | Value | ++------------------+--------+ +| read_buffer_size | 122880 | ++------------------+--------+ +1 row in set (0.00 sec) + +singlestore> exit +Bye + +``` +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +kubectl patch -n demo my/custom-sdb -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl delete -n demo my/custom-sdb +kubectl delete ns demo +``` + +If you would like to uninstall KubeDB operator, please follow the steps [here](/docs/setup/README.md). + +## Next Steps +- [Quickstart SingleStore](/docs/guides/singlestore/quickstart/quickstart.md) with KubeDB Operator. +- Detail concepts of [singlestore object](/docs/guides/singlestore/concepts/singlestore.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/singlestore/configuration/config-file/yamls/sdb-config.cnf b/docs/guides/singlestore/configuration/config-file/yamls/sdb-config.cnf new file mode 100644 index 0000000000..f2adc327aa --- /dev/null +++ b/docs/guides/singlestore/configuration/config-file/yamls/sdb-config.cnf @@ -0,0 +1,3 @@ +[server] +max_connections = 250 +read_buffer_size = 122880 diff --git a/docs/guides/singlestore/configuration/config-file/yamls/sdb-custom.yaml b/docs/guides/singlestore/configuration/config-file/yamls/sdb-custom.yaml new file mode 100644 index 0000000000..dee95b8ba4 --- /dev/null +++ b/docs/guides/singlestore/configuration/config-file/yamls/sdb-custom.yaml @@ -0,0 +1,57 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: custom-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + diff --git a/docs/guides/singlestore/configuration/podtemplating/index.md b/docs/guides/singlestore/configuration/podtemplating/index.md new file mode 100644 index 0000000000..66fd5c8111 --- /dev/null +++ b/docs/guides/singlestore/configuration/podtemplating/index.md @@ -0,0 +1,712 @@ +--- +title: Run SingleStore with Custom PodTemplate +menu: + docs_{{ .version }}: + identifier: guides-sdb-configuration-using-podtemplate + name: Customize PodTemplate + parent: guides-sdb-configuration + weight: 15 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Run SingleStore with Custom PodTemplate + +KubeDB supports providing custom configuration for SingleStore via [PodTemplate](/docs/guides/singlestore/concepts/singlestore.md#spec.topology). This tutorial will show you how to use KubeDB to run a SingleStore database with custom configuration using PodTemplate. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/configuration/podtemplating/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Overview + +KubeDB allows providing a template for `leaf` and `aggregator` pod through `spec.topology.aggregator.podTemplate` and `spec.topology.leaf.podTemplate`. KubeDB operator will pass the information provided in `spec.topology.aggregator.podTemplate` and `spec.topology.leaf.podTemplate` to the `aggregator` and `leaf` PetSet created for SingleStore database. + +KubeDB accept following fields to set in `spec.podTemplate:` + +- metadata: + - annotations (pod's annotation) + - labels (pod's labels) +- controller: + - annotations (statefulset's annotation) + - labels (statefulset's labels) +- spec: + - volumes + - initContainers + - containers + - imagePullSecrets + - nodeSelector + - affinity + - serviceAccountName + - schedulerName + - tolerations + - priorityClassName + - priority + - securityContext + - livenessProbe + - readinessProbe + - lifecycle + +Read about the fields in details in [PodTemplate concept](/docs/guides/singlestore/concepts/singlestore.md#spectopology), + +## Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +## CRD Configuration + +Below is the YAML for the SingleStore created in this example. Here, [`spec.topology.aggregator/leaf.podTemplate.spec.args`](/docs/guides/mysql/concepts/database/index.md#specpodtemplatespecargs) provides extra arguments. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-misc-config + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + args: + - --character-set-server=utf8mb4 + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + args: + - --character-set-server=utf8mb4 + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-misc-config.yaml +singlestore.kubedb.com/sdb-misc-config created +``` + +Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `sdb-misc-config-aggregator-0` has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pod -n demo +NAME READY STATUS RESTARTS AGE +sdb-misc-config-aggregator-0 2/2 Running 0 4m51s +sdb-misc-config-leaf-0 2/2 Running 0 4m48s +sdb-misc-config-leaf-1 2/2 Running 0 4m30s +``` + +Now, we will check if the database has started with the custom configuration we have provided. + +```bash +$ kubectl exec -it -n demo sdb-misc-config-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sdb-misc-config-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 311 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> SHOW VARIABLES LIKE 'char%'; ++--------------------------+------------------------------------------------------+ +| Variable_name | Value | ++--------------------------+------------------------------------------------------+ +| character_set_client | utf8mb4 | +| character_set_connection | utf8mb4 | +| character_set_database | utf8mb4 | +| character_set_filesystem | binary | +| character_set_results | utf8mb4 | +| character_set_server | utf8mb4 | +| character_set_system | utf8 | +| character_sets_dir | /opt/memsql-server-8.7.10-95e2357384/share/charsets/ | ++--------------------------+------------------------------------------------------+ +8 rows in set (0.00 sec) + +singlestore> exit +Bye + +``` + +Here we can see the character_set_server value is utf8mb4. + +## Custom Sidecar Containers + +Here in this example we will add an extra sidecar container with our SingleStore cluster. This below example configuration allows you to run a SingleStore instance alongside a simple Nginx sidecar container, which can be used for HTTP requests, logging, or as a reverse proxy. Adjust the configuration as needed to fit your application's architecture. + +Firstly, we are going to create a sample configmap for the nginx configuration. Here is the yaml of ConfigMap + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config-map + namespace: demo +data: + default.conf: | + server { + listen 80; + location / { + proxy_pass http://localhost:9000; + } + } +``` + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/nginx-config-map.yaml +configmap/nginx-config-map created +``` + +Now we will deploy our singlestore with custom sidecar container. Here is the yaml of singlestore, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-custom-sidecar + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + - name: sidecar + image: nginx:alpine + ports: + - containerPort: 80 + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d + volumes: + - name: nginx-config + configMap: + name: nginx-config-map + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +Here, + +- Primary Container: The main singlestore container runs the SingleStore database, configured with specific resource limits and requests. + +- Sidecar Container: The sidecar container runs Nginx, a lightweight web server. It's configured to listen on port 80 and is intended to proxy requests to the SingleStore database. + +- Volume Mounts: The sidecar container mounts a volume for Nginx configuration from a ConfigMap, which allows you to customize Nginx's behavior. + +- Volumes: A volume is defined to link the ConfigMap nginx-config-map to the Nginx configuration directory. + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-custom-sidecar.yaml +singlestore.kubedb.com/sdb-custom-sidecar created +``` + +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see the pods has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pods -n demo +NAME READY STATUS RESTARTS AGE +sdb-custom-sidecar-aggregator-0 3/3 Running 0 3m17s +sdb-custom-sidecar-leaf-0 2/2 Running 0 3m14s +sdb-custom-sidecar-leaf-1 2/2 Running 0 2m59s +``` + +Now check the logs of sidecar container, + +```bash +$ kubectl logs -f -n demo sdb-custom-sidecar-aggregator-0 -c sidecar +/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration +/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ +/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh +10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?) +/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh +/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh +/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh +/docker-entrypoint.sh: Configuration complete; ready for start up +2024/10/29 07:43:11 [notice] 1#1: using the "epoll" event method +2024/10/29 07:43:11 [notice] 1#1: nginx/1.27.2 +2024/10/29 07:43:11 [notice] 1#1: built by gcc 13.2.1 20240309 (Alpine 13.2.1_git20240309) +2024/10/29 07:43:11 [notice] 1#1: OS: Linux 6.8.0-47-generic +2024/10/29 07:43:11 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 +2024/10/29 07:43:11 [notice] 1#1: start worker processes +2024/10/29 07:43:11 [notice] 1#1: start worker process 21 +2024/10/29 07:43:11 [notice] 1#1: start worker process 22 +2024/10/29 07:43:11 [notice] 1#1: start worker process 23 +2024/10/29 07:43:11 [notice] 1#1: start worker process 24 +2024/10/29 07:43:11 [notice] 1#1: start worker process 25 +2024/10/29 07:43:11 [notice] 1#1: start worker process 26 +2024/10/29 07:43:11 [notice] 1#1: start worker process 27 +2024/10/29 07:43:11 [notice] 1#1: start worker process 28 +2024/10/29 07:43:11 [notice] 1#1: start worker process 29 +2024/10/29 07:43:11 [notice] 1#1: start worker process 30 +2024/10/29 07:43:11 [notice] 1#1: start worker process 31 +2024/10/29 07:43:11 [notice] 1#1: start worker process 32 +``` +So, we have successfully deploy sidecar container in KubeDB manage SingleStore. + +## Using Node Selector + +Here in this example we will use [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) to schedule our singlestore pod to a specific node. Applying nodeSelector to the Pod involves several steps. We first need to assign a label to some node that will be later used by the `nodeSelector` . Let’s find what nodes exist in your cluster. To get the name of these nodes, you can run: + +```bash +$ kubectl get nodes --show-labels +NAME STATUS ROLES AGE VERSION LABELS +lke212553-307295-339173d10000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-339173d10000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=618158120a299c6fd37f00d01d355ca18794c467,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5541798e0000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5541798e0000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5b53c5520000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5b53c5520000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=792bac078d7ce0e548163b9423416d7d8c88b08f,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +``` +As you see, we have three nodes in the cluster: lke212553-307295-339173d10000, lke212553-307295-5541798e0000, and lke212553-307295-5b53c5520000. + +Next, select a node to which you want to add a label. For example, let’s say we want to add a new label with the key `disktype` and value ssd to the `lke212553-307295-5541798e0000` node, which is a node with the SSD storage. To do so, run: +```bash +$ kubectl label nodes lke212553-307295-5541798e0000 disktype=ssd +node/lke212553-307295-5541798e0000 labeled +``` +As you noticed, the command above follows the format `kubectl label nodes =` . +Finally, let’s verify that the new label was added by running: +```bash + $ kubectl get nodes --show-labels +NAME STATUS ROLES AGE VERSION LABELS +lke212553-307295-339173d10000 Ready 41m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-339173d10000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=618158120a299c6fd37f00d01d355ca18794c467,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5541798e0000 Ready 41m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,disktype=ssd,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5541798e0000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5b53c5520000 Ready 41m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5b53c5520000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=792bac078d7ce0e548163b9423416d7d8c88b08f,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +``` +As you see, the lke212553-307295-5541798e0000 now has a new label disktype=ssd. To see all labels attached to the node, you can also run: +```bash +$ kubectl describe node "lke212553-307295-5541798e0000" +Name: lke212553-307295-5541798e0000 +Roles: +Labels: beta.kubernetes.io/arch=amd64 + beta.kubernetes.io/instance-type=g6-dedicated-4 + beta.kubernetes.io/os=linux + disktype=ssd + failure-domain.beta.kubernetes.io/region=ap-south + kubernetes.io/arch=amd64 + kubernetes.io/hostname=lke212553-307295-5541798e0000 + kubernetes.io/os=linux + lke.linode.com/pool-id=307295 + node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5 + node.kubernetes.io/instance-type=g6-dedicated-4 + topology.kubernetes.io/region=ap-south + topology.linode.com/region=ap-south +``` +Along with the `disktype=ssd` label we’ve just added, you can see other labels such as `beta.kubernetes.io/arch` or `kubernetes.io/hostname`. These are all default labels attached to Kubernetes nodes. + +Now let's create a singlestore with this new label as nodeSelector. Below is the yaml we are going to apply: +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-node-selector + namespace: demo +spec: + version: "8.7.10" + podTemplate: + spec: + nodeSelector: + disktype: ssd + deletionPolicy: WipeOut + licenseSecret: + name: license-secret + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageType: Durable +``` +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-node-selector.yaml +singlestore.kubedb.com/sdb-node-selector created +``` +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `sdb-node-selector-0` has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pods -n demo +NAME READY STATUS RESTARTS AGE +sdb-node-selector-0 1/1 Running 0 60s +``` +As we see the pod is running, you can verify that by running `kubectl get pods -n demo sdb-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. +```bash +$ kubectl get pods -n demo sdb-node-selector-0 -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +sdb-node-selector-0 1/1 Running 0 3m19s 10.2.1.7 lke212553-307295-5541798e0000 +``` +We can successfully verify that our pod was scheduled to our desired node. + +## Using Taints and Tolerations + +Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our singlestore pod to a specific node and also prevent from scheduling to nodes. Applying taints and tolerations to the Pod involves several steps. Let’s find what nodes exist in your cluster. To get the name of these nodes, you can run: + +```bash +$ kubectl get nodes --show-labels +NAME STATUS ROLES AGE VERSION LABELS +lke212553-307295-339173d10000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-339173d10000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=618158120a299c6fd37f00d01d355ca18794c467,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5541798e0000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5541798e0000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5b53c5520000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5b53c5520000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=792bac078d7ce0e548163b9423416d7d8c88b08f,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +``` +As you see, we have three nodes in the cluster: lke212553-307295-339173d10000, lke212553-307295-5541798e0000, and lke212553-307295-5b53c5520000. + +Next, we are going to taint these nodes. +```bash +$ kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +node/lke212553-307295-339173d10000 tainted + +$ kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +node/lke212553-307295-5541798e0000 tainted + +$ kubectl taint nodes lke212553-307295-5b53c5520000 key1=node3:NoSchedule +node/lke212553-307295-5b53c5520000 tainted +``` +Let's see our tainted nodes here, +```bash +$ kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +lke212553-307295-339173d10000 +[ + { + "effect": "NoSchedule", + "key": "key1", + "value": "node1" + } +] +lke212553-307295-5541798e0000 +[ + { + "effect": "NoSchedule", + "key": "key1", + "value": "node2" + } +] +lke212553-307295-5b53c5520000 +[ + { + "effect": "NoSchedule", + "key": "key1", + "value": "node3" + } +] +``` +We can see that our taints were successfully assigned. Now let's try to create a singlestore without proper tolerations. Here is the yaml of singlestore we are going to createc +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-without-tolerations + namespace: demo +spec: + deletionPolicy: WipeOut + licenseSecret: + name: license-secret + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageType: Durable + version: 8.7.10 +``` +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-without-tolerations.yaml +singlestore.kubedb.com/sdb-without-tolerations created +``` +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `sdb-without-tolerations-0` has been created and running. + +Check that the petset's pod is running or not, +```bash +$ kubectl get pods -n demo +NAME READY STATUS RESTARTS AGE +sdb-without-tolerations-0 0/1 Pending 0 3m35s +``` +Here we can see that the pod is not running. So let's describe the pod, +```bash +$ kubectl describe pods -n demo sdb-without-tolerations-0 +Name: sdb-without-tolerations-0 +Namespace: demo +Priority: 0 +Service Account: sdb-without-tolerations +Node: ashraful/192.168.0.227 +Start Time: Tue, 29 Oct 2024 15:44:22 +0600 +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=sdb-without-tolerations + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=singlestores.kubedb.com + apps.kubernetes.io/pod-index=0 + controller-revision-hash=sdb-without-tolerations-6449dc959b + kubedb.com/petset=standalone + statefulset.kubernetes.io/pod-name=sdb-without-tolerations-0 +Annotations: +Status: Running +IP: 10.42.0.122 +IPs: + IP: 10.42.0.122 +Controlled By: PetSet/sdb-without-tolerations +Init Containers: + singlestore-init: + Container ID: containerd://382a8cca4103e609c0a763f65db11e89ca38fe4b982dd6f03c18eb33c083998c + Image: ghcr.io/kubedb/singlestore-init:8.7.10-v1@sha256:7f8a60b45c9a402c5a3de56a266e06a70db1feeff1c28a506e485e60afc7f5fa + Image ID: ghcr.io/kubedb/singlestore-init@sha256:7f8a60b45c9a402c5a3de56a266e06a70db1feeff1c28a506e485e60afc7f5fa + Port: + Host Port: + SeccompProfile: RuntimeDefault + State: Terminated + Reason: Completed + Exit Code: 0 + Started: Tue, 29 Oct 2024 15:44:31 +0600 + Finished: Tue, 29 Oct 2024 15:44:31 +0600 + Ready: True + Restart Count: 0 + Limits: + memory: 512Mi + Requests: + cpu: 200m + memory: 512Mi + Environment: + Mounts: + /scripts from init-scripts (rw) + /var/lib/memsql from data (rw) + /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-htm2z (ro) +Containers: + singlestore: + Container ID: containerd://b52ae6c34300ea23b60ce91fbbc6a01a1fd71bb7a3de6fea97d9a726ca280e55 + Image: singlestore/cluster-in-a-box:alma-8.7.10-95e2357384-4.1.0-1.17.14@sha256:6b1b66b57e11814815a43114ab28db407428662af4c7d1c666c14a3f53c5289f + Image ID: docker.io/singlestore/cluster-in-a-box@sha256:6b1b66b57e11814815a43114ab28db407428662af4c7d1c666c14a3f53c5289f + Ports: 3306/TCP, 8081/TCP + Host Ports: 0/TCP, 0/TCP + SeccompProfile: RuntimeDefault + Args: + /scripts/standalone-run.sh + State: Running + Started: Tue, 29 Oct 2024 15:44:32 +0600 + Ready: True + Restart Count: 0 + Limits: + memory: 2Gi + Requests: + cpu: 500m + memory: 2Gi + Environment: + ROOT_USERNAME: Optional: false + ROOT_PASSWORD: Optional: false + SINGLESTORE_LICENSE: Optional: false + LICENSE_KEY: Optional: false + HOST_IP: (v1:status.hostIP) + Mounts: + /scripts from init-scripts (rw) + /var/lib/memsql from data (rw) + /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-htm2z (ro) +Conditions: + Type Status + PodReadyToStartContainers True + Initialized True + Ready True + ContainersReady True + PodScheduled True +Volumes: + data: + Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) + ClaimName: data-sdb-without-tolerations-0 + ReadOnly: false + init-scripts: + Type: EmptyDir (a temporary directory that shares a pod's lifetime) + Medium: + SizeLimit: + kube-api-access-htm2z: + Type: Projected (a volume that contains injected data from multiple sources) + TokenExpirationSeconds: 3607 + ConfigMapName: kube-root-ca.crt + ConfigMapOptional: + DownwardAPI: true +QoS Class: Burstable +Node-Selectors: +Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s + node.kubernetes.io/unreachable:NoExecute op=Exists for 300s +Topology Spread Constraints: kubernetes.io/hostname:ScheduleAnyway when max skew 1 is exceeded for selector app.kubernetes.io/component=database,app.kubernetes.io/instance=sdb-without-tolerations,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=singlestores.kubedb.com,kubedb.com/petset=standalone + topology.kubernetes.io/zone:ScheduleAnyway when max skew 1 is exceeded for selector app.kubernetes.io/component=database,app.kubernetes.io/instance=sdb-without-tolerations,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=singlestores.kubedb.com,kubedb.com/petset=standalone +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning FailedScheduling 5m20s default-scheduler 0/3 nodes are available: 1 node(s) had untolerated taint {key1: node1}, 1 node(s) had untolerated taint {key1: node2}, 1 node(s) had untolerated taint {key1: node3}. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling. + Warning FailedScheduling 11s default-scheduler 0/3 nodes are available: 1 node(s) had untolerated taint {key1: node1}, 1 node(s) had untolerated taint {key1: node2}, 1 node(s) had untolerated taint {key1: node3}. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling. + Normal NotTriggerScaleUp 13s (x31 over 5m15s) cluster-autoscaler pod didn't trigger scale-up: +``` +Here we can see that the pod has no tolerations for the tainted nodes and because of that the pod is not able to scheduled. + +So, let's add proper tolerations and create another singlestore. Here is the yaml we are going to apply, +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-with-tolerations + namespace: demo +spec: + podTemplate: + spec: + tolerations: + - key: "key1" + operator: "Equal" + value: "node1" + effect: "NoSchedule" + deletionPolicy: WipeOut + licenseSecret: + name: license-secret + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageType: Durable + version: 8.7.10 +``` + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-with-tolerations.yaml +singlestore.kubedb.com/sdb-with-tolerations created +``` +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `sdb-with-tolerations-0` has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pods -n demo +NAME READY STATUS RESTARTS AGE +sdb-with-tolerations-0 1/1 Running 0 2m +``` +As we see the pod is running, you can verify that by running `kubectl get pods -n demo sdb-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. +```bash +$ kubectl get pods -n demo sdb-with-tolerations-0 -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +sdb-with-tolerations-0 1/1 Running 0 3m49s 10.2.0.8 lke212553-307295-339173d10000 +``` +We can successfully verify that our pod was scheduled to the node which it has tolerations. + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete singlestore -n demo sdb-misc-config + +kubectl delete ns demo +``` + +If you would like to uninstall KubeDB operator, please follow the steps [here](/docs/setup/README.md). + +## Next Steps + +- [Quickstart SingleStore](/docs/guides/singlestore/quickstart/quickstart.md) with KubeDB Operator. +- Initialize [SingleStore with Script](/docs/guides/singlestore/initialization). +- Detail concepts of [SingleStore object](/docs/guides/singlestore/concepts/singlestore.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/singlestore/configuration/podtemplating/yamls/nginx-config-map.yaml b/docs/guides/singlestore/configuration/podtemplating/yamls/nginx-config-map.yaml new file mode 100644 index 0000000000..aa854d0815 --- /dev/null +++ b/docs/guides/singlestore/configuration/podtemplating/yamls/nginx-config-map.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config-map + namespace: demo +data: + default.conf: | + server { + listen 80; + location / { + proxy_pass http://localhost:9000; + } + } \ No newline at end of file diff --git a/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-custom-sidecar.yaml b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-custom-sidecar.yaml new file mode 100644 index 0000000000..ea3ee78e0e --- /dev/null +++ b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-custom-sidecar.yaml @@ -0,0 +1,63 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-custom-sidecar + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + - name: sidecar + image: nginx:alpine + ports: + - containerPort: 80 + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d + volumes: + - name: nginx-config + configMap: + name: nginx-config-map + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-misc-config.yaml b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-misc-config.yaml new file mode 100644 index 0000000000..afbe5678ca --- /dev/null +++ b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-misc-config.yaml @@ -0,0 +1,57 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-misc-config + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + args: + - --character-set-server=utf8mb4 + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + args: + - --character-set-server=utf8mb4 + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + diff --git a/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-node-selector.yaml b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-node-selector.yaml new file mode 100644 index 0000000000..27c460006e --- /dev/null +++ b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-node-selector.yaml @@ -0,0 +1,22 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-node-selector + namespace: demo +spec: + version: "8.7.10" + podTemplate: + spec: + nodeSelector: + disktype: ssd + deletionPolicy: WipeOut + licenseSecret: + name: license-secret + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageType: Durable \ No newline at end of file diff --git a/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-with-tolerations.yaml b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-with-tolerations.yaml new file mode 100644 index 0000000000..2e5fac4866 --- /dev/null +++ b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-with-tolerations.yaml @@ -0,0 +1,25 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-with-tolerations + namespace: demo +spec: + podTemplate: + spec: + tolerations: + - key: "key1" + operator: "Equal" + value: "node1" + effect: "NoSchedule" + deletionPolicy: WipeOut + licenseSecret: + name: license-secret + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageType: Durable + version: 8.7.10 \ No newline at end of file diff --git a/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-without-tolerations.yaml b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-without-tolerations.yaml new file mode 100644 index 0000000000..3e55318404 --- /dev/null +++ b/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-without-tolerations.yaml @@ -0,0 +1,18 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-without-tolerations + namespace: demo +spec: + deletionPolicy: WipeOut + licenseSecret: + name: license-secret + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageType: Durable + version: 8.7.10 \ No newline at end of file diff --git a/docs/guides/singlestore/initialization/_index.md b/docs/guides/singlestore/initialization/_index.md new file mode 100755 index 0000000000..6d2bb64fa7 --- /dev/null +++ b/docs/guides/singlestore/initialization/_index.md @@ -0,0 +1,10 @@ +--- +title: SingleStore Initialization +menu: + docs_{{ .version }}: + identifier: guides-sdb-initialization + name: Initialization + parent: guides-singlestore + weight: 41 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/initialization/using-script/example/demo-1.yaml b/docs/guides/singlestore/initialization/using-script/example/demo-1.yaml new file mode 100644 index 0000000000..cce1b506ae --- /dev/null +++ b/docs/guides/singlestore/initialization/using-script/example/demo-1.yaml @@ -0,0 +1,56 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: "8.7.10" + init: + script: + configMap: + name: sdb-init-script + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/initialization/using-script/index.md b/docs/guides/singlestore/initialization/using-script/index.md new file mode 100644 index 0000000000..b5bef8142b --- /dev/null +++ b/docs/guides/singlestore/initialization/using-script/index.md @@ -0,0 +1,406 @@ +--- +title: Initialize SingleStore using Script +menu: + docs_{{ .version }}: + identifier: guides-sdb-initialization-usingscript + name: Using Script + parent: guides-sdb-initialization + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Initialize SingleStore using Script + +This tutorial will show you how to use KubeDB to initialize a SingleStore database with \*.sql, \*.sh and/or \*.sql.gz script. +In this tutorial we will use .sql script stored in GitHub repository [kubedb/singlestore-init-scripts](https://github.com/kubedb/singlestore-init-scripts). + +> Note: The yaml files that are used in this tutorial are stored [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/initialization/using-script/example) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs) + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +## Prepare Initialization Scripts + +SingleStore supports initialization with `.sh`, `.sql` and `.sql.gz` files. In this tutorial, we will use `init.sql` script from [singlestore-init-scripts](https://github.com/kubedb/singlestore-init-scripts) git repository to create a TABLE `kubedb_write_check` in `kubedb_test` database. + +We will use a ConfigMap as script source. You can use any Kubernetes supported [volume](https://kubernetes.io/docs/concepts/storage/volumes) as script source. + +At first, we will create a ConfigMap from `init.sql` file. Then, we will provide this ConfigMap as script source in `init.script` of SingleStore crd spec. + +Let's create a ConfigMap with initialization script, + +```bash +$ kubectl create configmap -n demo sdb-init-script \ +--from-literal=init.sql="$(curl -fsSL https://github.com/kubedb/singlestore-init-scripts/raw/master/init.sql)" +configmap/sdb-init-script created +``` + +## Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +## Create a SingleStore database with Init-Script + +Below is the `SingleStore` object created in this tutorial. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: "8.7.10" + init: + script: + configMap: + name: sdb-init-script + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/Initialization/demo-1.yaml +singlestore.kubedb.com/singlestore-init-script created +``` + +Here, + +- `spec.init.script` specifies a script source used to initialize the database before database server starts. The scripts will be executed alphabatically. In this tutorial, a sample .sql script from the git repository `https://github.com/kubedb/singlestore-init-scripts.git` is used to create a test database. You can use other [volume sources](https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes) instead of `ConfigMap`. The \*.sql, \*sql.gz and/or \*.sh sripts that are stored inside the root folder will be executed alphabatically. The scripts inside child folders will be skipped. + +KubeDB operator watches for `SingleStore` objects using Kubernetes api. When a `SingleStore` object is created, KubeDB operator will create a new PetSet and a Service with the matching `SingleStore` object name. KubeDB operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. No SingleStore specific RBAC roles are required for [RBAC enabled clusters](/docs/setup/README.md#using-yaml). + +```yaml +$ kubectl get sdb -n demo sdb-sample -oyaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"kubedb.com/v1alpha2","kind":"Singlestore","metadata":{"annotations":{},"name":"sdb-sample","namespace":"demo"},"spec":{"deletionPolicy":"WipeOut","init":{"script":{"configMap":{"name":"sdb-init-script"}}},"licenseSecret":{"name":"license-secret"},"storageType":"Durable","topology":{"aggregator":{"podTemplate":{"spec":{"containers":[{"name":"singlestore","resources":{"limits":{"cpu":"600m","memory":"2Gi"},"requests":{"cpu":"600m","memory":"2Gi"}}}]}},"replicas":2,"storage":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}},"storageClassName":"standard"}},"leaf":{"podTemplate":{"spec":{"containers":[{"name":"singlestore","resources":{"limits":{"cpu":"600m","memory":"2Gi"},"requests":{"cpu":"600m","memory":"2Gi"}}}]}},"replicas":2,"storage":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}},"storageClassName":"standard"}}},"version":"8.7.10"}} + creationTimestamp: "2024-10-03T07:00:56Z" + finalizers: + - kubedb.com + generation: 3 + name: sdb-sample + namespace: demo + resourceVersion: "124012" + uid: ccfe9d0e-6f13-4187-b652-4e157a21568e +spec: + authSecret: + name: sdb-sample-root-cred + deletionPolicy: WipeOut + healthChecker: + failureThreshold: 1 + periodSeconds: 10 + timeoutSeconds: 10 + init: + script: + configMap: + name: sdb-init-script + licenseSecret: + name: license-secret + storageType: Durable + topology: + aggregator: + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + cpu: 600m + memory: 2Gi + requests: + cpu: 600m + memory: 2Gi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + - name: singlestore-coordinator + resources: + limits: + memory: 256Mi + requests: + cpu: 200m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + initContainers: + - name: singlestore-init + resources: + limits: + memory: 512Mi + requests: + cpu: 200m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + podPlacementPolicy: + name: default + securityContext: + fsGroup: 999 + replicas: 2 + storage: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: standard + leaf: + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + cpu: 600m + memory: 2Gi + requests: + cpu: 600m + memory: 2Gi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + - name: singlestore-coordinator + resources: + limits: + memory: 256Mi + requests: + cpu: 200m + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + initContainers: + - name: singlestore-init + resources: + limits: + memory: 512Mi + requests: + cpu: 200m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 998 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + podPlacementPolicy: + name: default + securityContext: + fsGroup: 999 + replicas: 2 + storage: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: standard + version: 8.7.10 +status: + conditions: + - lastTransitionTime: "2024-10-03T07:01:02Z" + message: 'The KubeDB operator has started the provisioning of Singlestore: demo/sdb-sample' + observedGeneration: 3 + reason: DatabaseProvisioningStartedSuccessfully + status: "True" + type: ProvisioningStarted + - lastTransitionTime: "2024-10-03T07:11:23Z" + message: All leaf replicas are ready for Singlestore demo/sdb-sample + observedGeneration: 3 + reason: AllReplicasReady + status: "True" + type: ReplicaReady + - lastTransitionTime: "2024-10-03T07:02:13Z" + message: database demo/sdb-sample is accepting connection + observedGeneration: 3 + reason: AcceptingConnection + status: "True" + type: AcceptingConnection + - lastTransitionTime: "2024-10-03T07:02:13Z" + message: database demo/sdb-sample is ready + observedGeneration: 3 + reason: AllReplicasReady + status: "True" + type: Ready + - lastTransitionTime: "2024-10-03T07:02:14Z" + message: 'The Singlestore: demo/sdb-sample is successfully provisioned.' + observedGeneration: 3 + reason: DatabaseSuccessfullyProvisioned + status: "True" + type: Provisioned + phase: Ready +``` + +KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. + +Now, we will connect to this database and check the data inserted by the initlization script. + +```bash +# Connecting to the database +$ kubectl exec -it -n demo sdb-sample-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sdb-sample-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 144 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> show databases; ++--------------------+ +| Database | ++--------------------+ +| cluster | +| information_schema | +| kubedb_test | +| memsql | +| singlestore_health | ++--------------------+ +5 rows in set (0.00 sec) + +singlestore> use kubedb_test; +Reading table information for completion of table and column names +You can turn off this feature to get a quicker startup with -A + +Database changed + +# Showing the inserted `kubedb_write_check` +singlestore> select * from kubedb_write_check; ++----+-------+ +| id | name | ++----+-------+ +| 3 | name3 | +| 1 | name1 | +| 2 | name2 | ++----+-------+ +3 rows in set (0.02 sec) + +singlestore> exit +Bye + + +``` + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete sdb -n demo sdb-sample +singlestore.kubedb.com "sdb-sample" deleted +$ kubectl delete ns demo +namespace "demo" deleted +``` diff --git a/docs/guides/singlestore/monitoring/_index.md b/docs/guides/singlestore/monitoring/_index.md new file mode 100644 index 0000000000..1053b439d3 --- /dev/null +++ b/docs/guides/singlestore/monitoring/_index.md @@ -0,0 +1,10 @@ +--- +title: SingleStore Monitoring +menu: + docs_{{ .version }}: + identifier: guides-sdb-monitoring + name: Monitoring + parent: guides-singlestore + weight: 50 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/monitoring/builtin-prometheus/images/sdb-builtin-prom-target.png b/docs/guides/singlestore/monitoring/builtin-prometheus/images/sdb-builtin-prom-target.png new file mode 100644 index 0000000000..d574dd37aa Binary files /dev/null and b/docs/guides/singlestore/monitoring/builtin-prometheus/images/sdb-builtin-prom-target.png differ diff --git a/docs/guides/singlestore/monitoring/builtin-prometheus/index.md b/docs/guides/singlestore/monitoring/builtin-prometheus/index.md new file mode 100644 index 0000000000..da5a7440fa --- /dev/null +++ b/docs/guides/singlestore/monitoring/builtin-prometheus/index.md @@ -0,0 +1,402 @@ +--- +title: Monitor SingleStore using Builtin Prometheus Discovery +menu: + docs_{{ .version }}: + identifier: guides-sdb-monitoring-builtin-prometheus + name: Builtin Prometheus + parent: guides-sdb-monitoring + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Monitoring SingleStore with builtin Prometheus + +This tutorial will show you how to monitor SingleStore database using builtin [Prometheus](https://github.com/prometheus/prometheus) scraper. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- If you are not familiar with how to configure Prometheus to scrape metrics from various Kubernetes resources, please read the tutorial from [here](https://github.com/appscode/third-party-tools/tree/master/monitoring/prometheus/builtin). + +- To learn how Prometheus monitoring works with KubeDB in general, please visit [here](/docs/guides/singlestore/monitoring/overview/index.md). + +- To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. + + ```bash + $ kubectl create ns monitoring + namespace/monitoring created + + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/monitoring/builtin-prometheus/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Deploy SingleStore with Monitoring Enabled + +At first, let's deploy an SingleStore database with monitoring enabled. Below is the SingleStore object that we are going to create. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: builtin-prom-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + monitor: + agent: prometheus.io/builtin +``` + +Here, + +- `spec.monitor.agent: prometheus.io/builtin` specifies that we are going to monitor this server using builtin Prometheus scraper. + +Let's create the SingleStore crd we have shown above. + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/builtin-prom-singlestore.yaml +singlestore.kubedb.com/builtin-prom-sdb created +``` + +Now, wait for the database to go into `Running` state. + +```bash +$ watch -n 3 kubectl get singlestore -n demo builtin-prom-sdb + +NAME TYPE VERSION STATUS AGE +builtin-prom-sdb kubedb.com/v1alpha2 8.7.10 Ready 9m5s + +``` + +KubeDB will create a separate stats service with name `{SingleStore crd name}-stats` for monitoring purpose. + +```bash +$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-sdb" +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +builtin-prom-sdb ClusterIP 10.128.102.243 3306/TCP,8081/TCP 14m +builtin-prom-sdb-pods ClusterIP None 3306/TCP 14m +builtin-prom-sdb-stats ClusterIP 10.128.218.225 9104/TCP 14m + +``` + +Here, `builtin-prom-sdb-stats` service has been created for monitoring purpose. Let's describe the service. + +```bash +$ kubectl describe svc -n demo builtin-prom-sdb-stats +Name: builtin-prom-sdb-stats +Namespace: demo +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=builtin-prom-sdb + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=singlestores.kubedb.com + kubedb.com/role=stats +Annotations: monitoring.appscode.com/agent: prometheus.io/builtin + prometheus.io/path: /metrics + prometheus.io/port: 9104 + prometheus.io/scrape: true +Selector: app.kubernetes.io/instance=builtin-prom-sdb,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=singlestores.kubedb.com +Type: ClusterIP +IP Family Policy: SingleStack +IP Families: IPv4 +IP: 10.128.218.225 +IPs: 10.128.218.225 +Port: metrics 9104/TCP +TargetPort: metrics/TCP +Endpoints: 10.2.1.142:9104,10.2.1.143:9104 +Session Affinity: None +Events: +``` + +You can see that the service contains following annotations. + +```bash +prometheus.io/path: /metrics +prometheus.io/port: 56790 +prometheus.io/scrape: true +``` + +The Prometheus server will discover the service endpoint using these specifications and will scrape metrics from the exporter. + +## Configure Prometheus Server + +Now, we have to configure a Prometheus scraping job to scrape the metrics using this service. We are going to configure scraping job similar to this [kubernetes-service-endpoints](https://github.com/appscode/third-party-tools/tree/master/monitoring/prometheus/builtin#kubernetes-service-endpoints) job that scrapes metrics from endpoints of a service. + +Let's configure a Prometheus scraping job to collect metrics from this service. + +```yaml +- job_name: 'kubedb-databases' + honor_labels: true + scheme: http + kubernetes_sd_configs: + - role: endpoints + # by default Prometheus server select all Kubernetes services as possible target. + # relabel_config is used to filter only desired endpoints + relabel_configs: + # keep only those services that has "prometheus.io/scrape","prometheus.io/path" and "prometheus.io/port" annotations + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape, __meta_kubernetes_service_annotation_prometheus_io_port] + separator: ; + regex: true;(.*) + action: keep + # currently KubeDB supported databases uses only "http" scheme to export metrics. so, drop any service that uses "https" scheme. + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: drop + regex: https + # only keep the stats services created by KubeDB for monitoring purpose which has "-stats" suffix + - source_labels: [__meta_kubernetes_service_name] + separator: ; + regex: (.*-stats) + action: keep + # service created by KubeDB will have "app.kubernetes.io/name" and "app.kubernetes.io/instance" annotations. keep only those services that have these annotations. + - source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name] + separator: ; + regex: (.*) + action: keep + # read the metric path from "prometheus.io/path: " annotation + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + # read the port from "prometheus.io/port: " annotation and update scraping address accordingly + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + # add service namespace as label to the scraped metrics + - source_labels: [__meta_kubernetes_namespace] + separator: ; + regex: (.*) + target_label: namespace + replacement: $1 + action: replace + # add service name as a label to the scraped metrics + - source_labels: [__meta_kubernetes_service_name] + separator: ; + regex: (.*) + target_label: service + replacement: $1 + action: replace + # add stats service's labels to the scraped metrics + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) +``` + +### Configure Existing Prometheus Server + +If you already have a Prometheus server running, you have to add above scraping job in the `ConfigMap` used to configure the Prometheus server. Then, you have to restart it for the updated configuration to take effect. + +>If you don't use a persistent volume for Prometheus storage, you will lose your previously scraped data on restart. + +### Deploy New Prometheus Server + +If you don't have any existing Prometheus server running, you have to deploy one. In this section, we are going to deploy a Prometheus server in `monitoring` namespace to collect metrics using this stats service. + +**Create ConfigMap:** + +At first, create a ConfigMap with the scraping configuration. Bellow, the YAML of ConfigMap that we are going to create in this tutorial. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-config + labels: + app: prometheus-demo + namespace: monitoring +data: + prometheus.yml: |- + global: + scrape_interval: 5s + evaluation_interval: 5s + scrape_configs: + - job_name: 'kubedb-databases' + honor_labels: true + scheme: http + kubernetes_sd_configs: + - role: endpoints + # by default Prometheus server select all Kubernetes services as possible target. + # relabel_config is used to filter only desired endpoints + relabel_configs: + # keep only those services that has "prometheus.io/scrape","prometheus.io/path" and "prometheus.io/port" anootations + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape, __meta_kubernetes_service_annotation_prometheus_io_port] + separator: ; + regex: true;(.*) + action: keep + # currently KubeDB supported databases uses only "http" scheme to export metrics. so, drop any service that uses "https" scheme. + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: drop + regex: https + # only keep the stats services created by KubeDB for monitoring purpose which has "-stats" suffix + - source_labels: [__meta_kubernetes_service_name] + separator: ; + regex: (.*-stats) + action: keep + # service created by KubeDB will have "app.kubernetes.io/name" and "app.kubernetes.io/instance" annotations. keep only those services that have these annotations. + - source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name] + separator: ; + regex: (.*) + action: keep + # read the metric path from "prometheus.io/path: " annotation + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + # read the port from "prometheus.io/port: " annotation and update scraping address accordingly + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + # add service namespace as label to the scraped metrics + - source_labels: [__meta_kubernetes_namespace] + separator: ; + regex: (.*) + target_label: namespace + replacement: $1 + action: replace + # add service name as a label to the scraped metrics + - source_labels: [__meta_kubernetes_service_name] + separator: ; + regex: (.*) + target_label: service + replacement: $1 + action: replace + # add stats service's labels to the scraped metrics + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) +``` + +Let's create above `ConfigMap`, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/prom-config.yaml +configmap/prometheus-config created +``` + +**Create RBAC:** + +If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, + +```bash +$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +clusterrole.rbac.authorization.k8s.io/prometheus created +serviceaccount/prometheus created +clusterrolebinding.rbac.authorization.k8s.io/prometheus created +``` + +>YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). + +**Deploy Prometheus:** + +Now, we are ready to deploy Prometheus server. We are going to use following [deployment](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/deployment.yaml) to deploy Prometheus server. + +Let's deploy the Prometheus server. + +```bash +$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml +deployment.apps/prometheus created +``` + +### Verify Monitoring Metrics + +Prometheus server is listening to port `9090`. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. + +At first, let's check if the Prometheus pod is in `Running` state. + +```bash +$ kubectl get pod -n monitoring -l=app=prometheus +NAME READY STATUS RESTARTS AGE +prometheus-8568c86d86-95zhn 1/1 Running 0 77s +``` + +Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, + +```bash +$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +Forwarding from 127.0.0.1:9090 -> 9090 +Forwarding from [::1]:9090 -> 9090 +``` + +Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-sdb-stats` service as one of the targets. + +

+  Prometheus Target +

+ +Check the labels marked with red rectangle. These labels confirm that the metrics are coming from `SingleStore` database `builtin-prom-sdb` through stats service `builtin-prom-sdb-stats`. + +Now, you can view the collected metrics and create a graph from homepage of this Prometheus dashboard. You can also use this Prometheus server as data source for [Grafana](https://grafana.com/) and create beautiful dashboard with collected metrics. + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run following commands + +```bash +kubectl delete -n demo my/builtin-prom-sdb + +kubectl delete -n monitoring deployment.apps/prometheus + +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +kubectl delete -n monitoring serviceaccount/prometheus +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus + +kubectl delete ns demo +kubectl delete ns monitoring +``` + +## Next Steps + +- Monitor your SingleStore database with KubeDB using [`out-of-the-box` Prometheus operator](/docs/guides/singlestore/monitoring/prometheus-operator/index.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/builtin-prom-singlestore.yaml b/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/builtin-prom-singlestore.yaml new file mode 100644 index 0000000000..2891cd6fa6 --- /dev/null +++ b/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/builtin-prom-singlestore.yaml @@ -0,0 +1,54 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: builtin-prom-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + monitor: + agent: prometheus.io/builtin diff --git a/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/prom-config.yaml b/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/prom-config.yaml new file mode 100644 index 0000000000..45aee6317a --- /dev/null +++ b/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/prom-config.yaml @@ -0,0 +1,68 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-config + labels: + app: prometheus-demo + namespace: monitoring +data: + prometheus.yml: |- + global: + scrape_interval: 5s + evaluation_interval: 5s + scrape_configs: + - job_name: 'kubedb-databases' + honor_labels: true + scheme: http + kubernetes_sd_configs: + - role: endpoints + # by default Prometheus server select all Kubernetes services as possible target. + # relabel_config is used to filter only desired endpoints + relabel_configs: + # keep only those services that has "prometheus.io/scrape","prometheus.io/path" and "prometheus.io/port" anootations + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape, __meta_kubernetes_service_annotation_prometheus_io_port] + separator: ; + regex: true;(.*) + action: keep + # currently KubeDB supported databases uses only "http" scheme to export metrics. so, drop any service that uses "https" scheme. + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: drop + regex: https + # only keep the stats services created by KubeDB for monitoring purpose which has "-stats" suffix + - source_labels: [__meta_kubernetes_service_name] + separator: ; + regex: (.*-stats) + action: keep + # service created by KubeDB will have "app.kubernetes.io/name" and "app.kubernetes.io/instance" annotations. keep only those services that have these annotations. + - source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name] + separator: ; + regex: (.*) + action: keep + # read the metric path from "prometheus.io/path: " annotation + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + # read the port from "prometheus.io/port: " annotation and update scraping address accordingly + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + # add service namespace as label to the scraped metrics + - source_labels: [__meta_kubernetes_namespace] + separator: ; + regex: (.*) + target_label: namespace + replacement: $1 + action: replace + # add service name as a label to the scraped metrics + - source_labels: [__meta_kubernetes_service_name] + separator: ; + regex: (.*) + target_label: service + replacement: $1 + action: replace + # add stats service's labels to the scraped metrics + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) diff --git a/docs/guides/singlestore/monitoring/overview/images/database-monitoring-overview.svg b/docs/guides/singlestore/monitoring/overview/images/database-monitoring-overview.svg new file mode 100644 index 0000000000..395eefb334 --- /dev/null +++ b/docs/guides/singlestore/monitoring/overview/images/database-monitoring-overview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/guides/singlestore/monitoring/overview/index.md b/docs/guides/singlestore/monitoring/overview/index.md new file mode 100644 index 0000000000..7cb18f352e --- /dev/null +++ b/docs/guides/singlestore/monitoring/overview/index.md @@ -0,0 +1,122 @@ +--- +title: SingleStore Monitoring Overview +description: SingleStore Monitoring Overview +menu: + docs_{{ .version }}: + identifier: guides-sdb-monitoring-overview + name: Overview + parent: guides-sdb-monitoring + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Monitoring SingleStore with KubeDB + +KubeDB has native support for monitoring via [Prometheus](https://prometheus.io/). You can use builtin [Prometheus](https://github.com/prometheus/prometheus) scraper or [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) to monitor KubeDB managed databases. This tutorial will show you how database monitoring works with KubeDB and how to configure Database crd to enable monitoring. + +## Overview + +KubeDB uses Prometheus [exporter](https://prometheus.io/docs/instrumenting/exporters/#databases) images to export metrics for the respective databases. However, with SingleStore, you can obtain metrics without using an exporter image by configuring monitoring using the `memsql-admin` binary. We have integrated this configuration into our operator, supporting both TLS and non-TLS setups. To enable monitoring, you simply need to specify it in your SingleStore YAML file. The following diagram illustrates the logical flow of database monitoring with KubeDB. + +

+  Database Monitoring Flow +

+ +When a user creates a database crd with `spec.monitor` section configured, KubeDB operator provisions the respective database and injects an exporter image as sidecar to the database pod. It also creates a dedicated stats service with name `{database-crd-name}-stats` for monitoring. Prometheus server can scrape metrics using this stats service. + +## Configure Monitoring + +In order to enable monitoring for a database, you have to configure `spec.monitor` section. KubeDB provides following options to configure `spec.monitor` section: + +| Field | Type | Uses | +| -------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| `spec.monitor.agent` | `Required` | Type of the monitoring agent that will be used to monitor this database. It can be `prometheus.io/builtin` or `prometheus.io/operator`. | +| `spec.monitor.prometheus.exporter.port` | `Optional` | Port number where the exporter side car will serve metrics. | +| `spec.monitor.prometheus.exporter.args` | `Optional` | Arguments to pass to the exporter sidecar. | +| `spec.monitor.prometheus.exporter.env` | `Optional` | List of environment variables to set in the exporter sidecar container. | +| `spec.monitor.prometheus.exporter.resources` | `Optional` | Resources required by exporter sidecar container. | +| `spec.monitor.prometheus.exporter.securityContext` | `Optional` | Security options the exporter should run with. | +| `spec.monitor.prometheus.serviceMonitor.labels` | `Optional` | Labels for `ServiceMonitor` crd. | +| `spec.monitor.prometheus.serviceMonitor.interval` | `Optional` | Interval at which metrics should be scraped. | + +## Sample Configuration + +A sample YAML for MySQL crd with `spec.monitor` section configured to enable monitoring with [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) is shown below. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: prom-operator-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + monitor: + agent: prometheus.io/operator + prometheus: + serviceMonitor: + labels: + release: prometheus + interval: 10s +``` + +Assume that above Redis is configured to use basic authentication. So, exporter image also need to provide password to collect metrics. We have provided it through `spec.monitor.args` field. + +Here, we have specified that we are going to monitor this server using Prometheus operator through `spec.monitor.agent: prometheus.io/operator`. KubeDB will create a `ServiceMonitor` crd in `monitoring` namespace and this `ServiceMonitor` will have `release: prometheus` label. + +## Next Steps + +- Learn how to monitor Elasticsearch database with KubeDB using [builtin-Prometheus](/docs/guides/elasticsearch/monitoring/using-builtin-prometheus.md) and using [Prometheus operator](/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md). +- Learn how to monitor PostgreSQL database with KubeDB using [builtin-Prometheus](/docs/guides/postgres/monitoring/using-builtin-prometheus.md) and using [Prometheus operator](/docs/guides/postgres/monitoring/using-prometheus-operator.md). +- Learn how to monitor MySQL database with KubeDB using [builtin-Prometheus](/docs/guides/mysql/monitoring/builtin-prometheus/index.md) and using [Prometheus operator](/docs/guides/mysql/monitoring/prometheus-operator/index.md). +- Learn how to monitor MongoDB database with KubeDB using [builtin-Prometheus](/docs/guides/mongodb/monitoring/using-builtin-prometheus.md) and using [Prometheus operator](/docs/guides/mongodb/monitoring/using-prometheus-operator.md). +- Learn how to monitor Redis server with KubeDB using [builtin-Prometheus](/docs/guides/redis/monitoring/using-builtin-prometheus.md) and using [Prometheus operator](/docs/guides/redis/monitoring/using-prometheus-operator.md). +- Learn how to monitor Memcached server with KubeDB using [builtin-Prometheus](/docs/guides/memcached/monitoring/using-builtin-prometheus.md) and using [Prometheus operator](/docs/guides/memcached/monitoring/using-prometheus-operator.md). diff --git a/docs/guides/singlestore/monitoring/prometheus-operator/images/prom-operator-sdb-target.png b/docs/guides/singlestore/monitoring/prometheus-operator/images/prom-operator-sdb-target.png new file mode 100644 index 0000000000..d3c6416ec9 Binary files /dev/null and b/docs/guides/singlestore/monitoring/prometheus-operator/images/prom-operator-sdb-target.png differ diff --git a/docs/guides/singlestore/monitoring/prometheus-operator/images/prometheus-operator.png b/docs/guides/singlestore/monitoring/prometheus-operator/images/prometheus-operator.png new file mode 100644 index 0000000000..a9719d7f15 Binary files /dev/null and b/docs/guides/singlestore/monitoring/prometheus-operator/images/prometheus-operator.png differ diff --git a/docs/guides/singlestore/monitoring/prometheus-operator/index.md b/docs/guides/singlestore/monitoring/prometheus-operator/index.md new file mode 100644 index 0000000000..e951d4fbea --- /dev/null +++ b/docs/guides/singlestore/monitoring/prometheus-operator/index.md @@ -0,0 +1,361 @@ +--- +title: Monitor SingleStore using Prometheus Operator +menu: + docs_{{ .version }}: + identifier: guides-sdb-monitoring-prometheus-operator + name: Prometheus Operator + parent: guides-sdb-monitoring + weight: 15 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Monitoring SingleStore Using Prometheus operator + +[Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) provides simple and Kubernetes native way to deploy and configure Prometheus server. This tutorial will show you how to use Prometheus operator to monitor SingleStore database deployed with KubeDB. + +The following diagram shows how KubeDB Provisioner operator monitor `SingleStore` using Prometheus Operator. Open the image in a new tab to see the enlarged version. + +
+  Monitoring process of SingleStore using Prometheus Operator +
Fig: Monitoring process of SingleStore
+
+ +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- To learn how Prometheus monitoring works with KubeDB in general, please visit [here](/docs/guides/singlestore/monitoring/overview/index.md). + +- To keep database resources isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster: + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +- We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). + +- If you already don't have a Prometheus server running, deploy one following tutorial from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md#deploy-prometheus-server). + +> Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/monitoring/prometheus-operator/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/prometheus-operator/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Find out required labels for ServiceMonitor + +We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd. We are going to provide these labels in `spec.monitor.prometheus.labels` field of SingleStore crd so that KubeDB creates `ServiceMonitor` object accordingly. + +At first, let's find out the available Prometheus server in our cluster. + +```bash +$ kubectl get prometheus --all-namespaces +NAMESPACE NAME VERSION REPLICAS AGE +default prometheus 1 2m19s +``` + +> If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. + +Now, let's view the YAML of the available Prometheus server `prometheus` in `default` namespace. + +```yaml +$ kubectl get prometheus -n default prometheus -o yaml +apiVersion: monitoring.coreos.com/v1 +kind: Prometheus +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"monitoring.coreos.com/v1","kind":"Prometheus","metadata":{"annotations":{},"labels":{"prometheus":"prometheus"},"name":"prometheus","namespace":"default"},"spec":{"replicas":1,"resources":{"requests":{"memory":"400Mi"}},"serviceAccountName":"prometheus","serviceMonitorNamespaceSelector":{"matchLabels":{"prometheus":"prometheus"}},"serviceMonitorSelector":{"matchLabels":{"release":"prometheus"}}}} + creationTimestamp: "2020-08-25T04:02:07Z" + generation: 1 + labels: + prometheus: prometheus + ... + manager: kubectl + operation: Update + time: "2020-08-25T04:02:07Z" + name: prometheus + namespace: default + resourceVersion: "2087" + selfLink: /apis/monitoring.coreos.com/v1/namespaces/default/prometheuses/prometheus + uid: 972a50cb-b751-418b-b2bc-e0ecc9232730 +spec: + replicas: 1 + resources: + requests: + memory: 400Mi + serviceAccountName: prometheus + serviceMonitorNamespaceSelector: + matchLabels: + prometheus: prometheus + serviceMonitorSelector: + matchLabels: + release: prometheus +``` + +- `spec.serviceMonitorSelector` field specifies which ServiceMonitors should be included. The Above label `release: prometheus` is used to select `ServiceMonitors` by its selector. So, we are going to use this label in `spec.monitor.prometheus.labels` field of SingleStore crd. +- `spec.serviceMonitorNamespaceSelector` field specifies that the `ServiceMonitors` can be selected outside the Prometheus namespace by Prometheus using namespace selector. The Above label `prometheus: prometheus` is used to select the namespace where the `ServiceMonitor` is created. + +### Add Label to database namespace + +KubeDB creates a `ServiceMonitor` in database namespace `demo`. We need to add label to `demo` namespace. Prometheus will select this namespace by using its `spec.serviceMonitorNamespaceSelector` field. + +Let's add label `prometheus: prometheus` to `demo` namespace, + +```bash +$ kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' +namespace/demo patched +``` + +## Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +## Deploy SingleStore with Monitoring Enabled + +At first, let's deploy an SingleStore database with monitoring enabled. Below is the SingleStore object that we are going to create. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: prom-operator-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + monitor: + agent: prometheus.io/operator + prometheus: + serviceMonitor: + labels: + release: prometheus + interval: 10s +``` + +Here, + +- `monitor.agent: prometheus.io/operator` indicates that we are going to monitor this server using Prometheus operator. + +- `monitor.prometheus.labels` specifies that KubeDB should create `ServiceMonitor` with these labels. + +- `monitor.prometheus.interval` indicates that the Prometheus server should scrape metrics from this database with 10 seconds interval. + +Let's create the SingleStore object that we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/prometheus-operator/yamls/prom-operator-singlestore.yaml +singlestore.kubedb.com/prom-operator-sdb created +``` + +Now, wait for the database to go into `Running` state. + +```bash +$ watch -n 3 kubectl get singlestore -n demo prom-operator-sdb + +NAME TYPE VERSION STATUS AGE +prom-operator-sdb kubedb.com/v1alpha2 8.7.10 Ready 10m + +``` + +KubeDB will create a separate stats service with name `{SingleStore crd name}-stats` for monitoring purpose. + +```bash +$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=prom-operator-sdb" +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +prom-operator-sdb ClusterIP 10.128.249.124 3306/TCP,8081/TCP 12m +prom-operator-sdb-pods ClusterIP None 3306/TCP 12m +prom-operator-sdb-stats ClusterIP 10.128.25.236 9104/TCP 12m + +``` + +Here, `prom-operator-sdb-stats` service has been created for monitoring purpose. + +Let's describe this stats service. + +```yaml +$ kubectl describe svc -n demo prom-operator-sdb-stats +Name: prom-operator-sdb-stats +Namespace: demo +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=prom-operator-sdb + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=singlestores.kubedb.com + kubedb.com/role=stats +Annotations: monitoring.appscode.com/agent: prometheus.io/operator +Selector: app.kubernetes.io/instance=prom-operator-sdb,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=singlestores.kubedb.com +Type: ClusterIP +IP Family Policy: SingleStack +IP Families: IPv4 +IP: 10.128.25.236 +IPs: 10.128.25.236 +Port: metrics 9104/TCP +TargetPort: metrics/TCP +Endpoints: 10.2.1.140:9104,10.2.1.141:9104 +Session Affinity: None +Events: + +``` + +Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these information to target its endpoints. + +KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `prom-operator-sdb-stats` service. Verify that the `ServiceMonitor` crd has been created. + +```bash +$ kubectl get servicemonitor -n demo +NAME AGE +prom-operator-sdb-stats 32m + +``` + +Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of SingleStore crd. + +```yaml +$ kubectl get servicemonitor -n demo prom-operator-sdb-stats -oyaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + creationTimestamp: "2024-10-01T05:37:40Z" + generation: 1 + labels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: prom-operator-sdb + app.kubernetes.io/managed-by: kubedb.com + app.kubernetes.io/name: singlestores.kubedb.com + release: prometheus + name: prom-operator-sdb-stats + namespace: demo + ownerReferences: + - apiVersion: v1 + blockOwnerDeletion: true + controller: true + kind: Service + name: prom-operator-sdb-stats + uid: 33802913-be0f-49ea-ac81-cf0136ed9fbc + resourceVersion: "98648" + uid: f26855f0-5f0e-45a6-8bf2-531d2a370377 +spec: + endpoints: + - honorLabels: true + interval: 10s + path: /metrics + port: metrics + namespaceSelector: + matchNames: + - demo + selector: + matchLabels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: prom-operator-sdb + app.kubernetes.io/managed-by: kubedb.com + app.kubernetes.io/name: singlestores.kubedb.com + kubedb.com/role: stats +``` + +Notice that the `ServiceMonitor` has label `release: prometheus` that we had specified in SingleStore crd. + +Also notice that the `ServiceMonitor` has selector which match the labels we have seen in the `prom-operator-sdb-stats` service. It also, target the `prom-http` port that we have seen in the stats service. + +## Verify Monitoring Metrics + +At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. + +```bash +$ kubectl get pod -n default -l=app=prometheus +NAME READY STATUS RESTARTS AGE +prometheus-prometheus-0 3/3 Running 1 121m +``` + +Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. + +Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, + +```bash +$ kubectl port-forward -n default prometheus-prometheus-0 9090 +Forwarding from 127.0.0.1:9090 -> 9090 +Forwarding from [::1]:9090 -> 9090 +``` + +Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `prom-operator-sdb-stats` service as one of the targets. + +

+  Prometheus Target +

+ +Check the `endpoint` and `service` labels marked by red rectangle. It verifies that the target is our expected database. Now, you can view the collected metrics and create a graph from homepage of this Prometheus dashboard. You can also use this Prometheus server as data source for [Grafana](https://grafana.com/) and create beautiful dashboard with collected metrics. + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run following commands + +```bash +# cleanup database +kubectl delete -n demo sdb/prom-operator-sdb + +# cleanup Prometheus resources if exist +kubectl delete -f https://raw.githubusercontent.com/appscode/third-party-tools/master/monitoring/prometheus/coreos-operator/artifacts/prometheus.yaml +kubectl delete -f https://raw.githubusercontent.com/appscode/third-party-tools/master/monitoring/prometheus/coreos-operator/artifacts/prometheus-rbac.yaml + +# cleanup Prometheus operator resources if exist +kubectl delete -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/release-0.41/bundle.yaml + +# delete namespace +kubectl delete ns demo +``` + +## Next Steps + +- Monitor your SingleStore database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/singlestore/monitoring/builtin-prometheus/index.md). +- Detail concepts of [SingleStore object](/docs/guides/singlestore/concepts/singlestore.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/singlestore/monitoring/prometheus-operator/yamls/prom-operator-singlestore.yaml b/docs/guides/singlestore/monitoring/prometheus-operator/yamls/prom-operator-singlestore.yaml new file mode 100644 index 0000000000..370ddb2016 --- /dev/null +++ b/docs/guides/singlestore/monitoring/prometheus-operator/yamls/prom-operator-singlestore.yaml @@ -0,0 +1,59 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: prom-operator-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + monitor: + agent: prometheus.io/operator + prometheus: + serviceMonitor: + labels: + release: prometheus + interval: 10s \ No newline at end of file diff --git a/docs/guides/singlestore/quickstart/quickstart.md b/docs/guides/singlestore/quickstart/quickstart.md index f2a1724e85..9cc52e7183 100644 --- a/docs/guides/singlestore/quickstart/quickstart.md +++ b/docs/guides/singlestore/quickstart/quickstart.md @@ -47,10 +47,12 @@ This tutorial will show you how to use KubeDB to run a SingleStore database. When you have installed KubeDB, it has created `SinglestoreVersion` crd for all supported SingleStore versions. Check it by using the `kubectl get singlestoreversions` command. You can also use `sdbv` shorthand instead of `singlestoreversions`. ```bash -$ kubectl get singlestoreversions + $ kubectl get singlestoreversions.catalog.kubedb.com NAME VERSION DB_IMAGE DEPRECATED AGE -8.1.32 8.1.32 ghcr.io/appscode-images/singlestore-node:alma-8.1.32-e3d3cde6da 72m -8.5.7 8.5.7 ghcr.io/appscode-images/singlestore-node:alma-8.5.7-bf633c1a54 72m +8.1.32 8.1.32 ghcr.io/appscode-images/singlestore-node:alma-8.1.32-e3d3cde6da 2d1h +8.5.30 8.5.30 ghcr.io/appscode-images/singlestore-node:alma-8.5.30-4f46ab16a5 2d1h +8.5.7 8.5.7 ghcr.io/appscode-images/singlestore-node:alma-8.5.7-bf633c1a54 2d1h +8.7.10 8.7.10 ghcr.io/appscode-images/singlestore-node:alma-8.7.10-95e2357384 2d1h ``` ## Create SingleStore License Secret diff --git a/docs/guides/singlestore/reconfigure-tls/_index.md b/docs/guides/singlestore/reconfigure-tls/_index.md new file mode 100644 index 0000000000..3a49b8c81c --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/_index.md @@ -0,0 +1,10 @@ +--- +title: Reconfigure SingleStore TLS/SSL +menu: + docs_{{ .version }}: + identifier: guides-sdb-reconfigure-tls + name: Reconfigure TLS/SSL + parent: guides-singlestore + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/examples/issuer.yaml b/docs/guides/singlestore/reconfigure-tls/cluster/examples/issuer.yaml new file mode 100644 index 0000000000..8ffb97a846 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/cluster/examples/issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: sdb-issuer + namespace: demo +spec: + ca: + secretName: sdb-ca \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/examples/sample-sdb.yaml b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sample-sdb.yaml new file mode 100644 index 0000000000..f654417867 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sample-sdb.yaml @@ -0,0 +1,51 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-add-tls.yaml b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-add-tls.yaml new file mode 100644 index 0000000000..4f8ad58246 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-add-tls.yaml @@ -0,0 +1,21 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-add-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + issuerRef: + name: sdb-issuer + kind: Issuer + apiGroup: "cert-manager.io" + certificates: + - alias: client + subject: + organizations: + - singlestore + organizationalUnits: + - client \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-remove-tls.yaml b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-remove-tls.yaml new file mode 100644 index 0000000000..4643dbfe37 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-remove-tls.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-remove-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + remove: true \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-rotate-tls.yaml b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-rotate-tls.yaml new file mode 100644 index 0000000000..503b4040d6 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-rotate-tls.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-rotate-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + rotateCertificates: true \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-update-tls.yaml b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-update-tls.yaml new file mode 100644 index 0000000000..549fbd7480 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-update-tls.yaml @@ -0,0 +1,17 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-update-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + certificates: + - alias: server + subject: + organizations: + - kubedb:server + emailAddresses: + - "kubedb@appscode.com" \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/index.md b/docs/guides/singlestore/reconfigure-tls/cluster/index.md new file mode 100644 index 0000000000..37cc93eb74 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/cluster/index.md @@ -0,0 +1,657 @@ +--- +title: Reconfigure SingleStore TLS/SSL Encryption +menu: + docs_{{ .version }}: + identifier: guides-sdb-reconfigure-tls-cluster + name: Reconfigure TLS/SSL Encryption + parent: guides-sdb-reconfigure-tls + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Reconfigure SingleStore TLS/SSL (Transport Encryption) + +KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL certificates for existing SingleStore database via a SingleStoreOpsRequest. This tutorial will show you how to use KubeDB to reconfigure TLS/SSL encryption. + +## Before You Begin + +- At first, you need to have a Kubernetes Cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install [`cert-manger`](https://cert-manager.io/docs/installation/) v1.6.0 or later to your cluster to manage your SSL/TLS certificates. + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +## Add TLS to a SingleStore Cluster + +Here, We are going to create a SingleStore database without TLS and then reconfigure the database to use TLS. +> **Note:** Steps for reconfiguring TLS of SingleStore `Standalone` is same as SingleStore `Cluster`. + +### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +### Deploy SingleStore without TLS + +In this section, we are going to deploy a SingleStore Cluster database without TLS. In the next few sections we will reconfigure TLS using `SingleStoreOpsRequest` CRD. Below is the YAML of the `SingleStore` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + deletionPolicy: WipeOut +``` + +Let's create the `SingleStore` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sample-sdb.yaml +singlestore.kubedb.com/sample-sdb created +``` + +Now, wait until `sample-sdb` has status `Ready`. i.e, + +```bash +$ kubectl get sdb -n demo +NAME TYPE VERSION STATUS AGE +sample-sdb kubedb.com/v1alpha2 8.7.10 Ready 38m + +``` + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 1188 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> show variables like '%ssl%'; ++---------------------------------+------------+ +| Variable_name | Value | ++---------------------------------+------------+ +| default_user_require_ssl | OFF | +| exporter_ssl_ca | | +| exporter_ssl_capath | | +| exporter_ssl_cert | | +| exporter_ssl_key | | +| exporter_ssl_key_passphrase | [redacted] | +| have_openssl | OFF | +| have_ssl | OFF | +| jwks_ssl_ca_certificate | | +| node_replication_ssl_only | OFF | +| openssl_version | 805306480 | +| processlist_rpc_json_max_size | 2048 | +| ssl_ca | | +| ssl_capath | | +| ssl_cert | | +| ssl_cipher | | +| ssl_fips_mode | OFF | +| ssl_key | | +| ssl_key_passphrase | [redacted] | +| ssl_last_reload_attempt_time | | +| ssl_last_successful_reload_time | | ++---------------------------------+------------+ +21 rows in set (0.00 sec) +``` + +We can verify from the above output that TLS is disabled for this database. + +### Create Issuer/ClusterIssuer + +Now, we are going to create an example `Issuer` that will be used throughout the duration of this tutorial. Alternatively, you can follow this [cert-manager tutorial](https://cert-manager.io/docs/configuration/ca/) to create your own `Issuer`. By following the below steps, we are going to create our desired issuer, + +- Start off by generating our ca-certificates using openssl, + +```bash +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memsql/O=kubedb" +Generating a RSA private key +...........................................................................+++++ +........................................................................................................+++++ +writing new private key to './ca.key' +``` + +- create a secret using the certificate files we have just generated, + +```bash +kubectl create secret tls sdb-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +secret/sdb-ca created +``` + +Now, we are going to create an `Issuer` using the `sdb-ca` secret that hols the ca-certificate we have just created. Below is the YAML of the `Issuer` cr that we are going to create, + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: sdb-issuer + namespace: demo +spec: + ca: + secretName: sdb-ca +``` + +Let’s create the `Issuer` cr we have shown above, + +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/issuer.yaml +issuer.cert-manager.io/sdb-issuer created +``` + +### Create SingleStoreOpsRequest + +In order to add TLS to the database, we have to create a `SingleStoreOpsRequest` CRO with our created issuer. Below is the YAML of the `SingleStoreOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-add-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + issuerRef: + name: sdb-issuer + kind: Issuer + apiGroup: "cert-manager.io" + certificates: + - alias: client + subject: + organizations: + - singlestore + organizationalUnits: + - client +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.issuerRef` specifies the issuer name, kind and api group. +- `spec.tls.certificates` specifies the certificates. You can learn more about this field from [here](/docs/guides/singlestore/concepts/singlestore.md#spectls). + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-add-tls.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-add-tls created + +``` + +#### Verify TLS Enabled Successfully + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +singlestoreopsrequest.ops.kubedb.com/sdbops-add-tls ReconfigureTLS Successful 2m45s + +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. + +Now, we are going to connect to the database for verifying the `SingleStore` server has configured with TLS/SSL encryption. + +Let's exec into the pod to verify TLS/SSL configuration, + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ ls etc/memsql/certs/ +ca.crt client.crt client.key server.crt server.key +[memsql@sample-sdb-aggregator-0 /]$ +[memsql@sample-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 90 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> show variables like '%ssl%'; ++---------------------------------+------------------------------+ +| Variable_name | Value | ++---------------------------------+------------------------------+ +| default_user_require_ssl | OFF | +| exporter_ssl_ca | | +| exporter_ssl_capath | | +| exporter_ssl_cert | | +| exporter_ssl_key | | +| exporter_ssl_key_passphrase | [redacted] | +| have_openssl | ON | +| have_ssl | ON | +| jwks_ssl_ca_certificate | | +| node_replication_ssl_only | OFF | +| openssl_version | 805306480 | +| processlist_rpc_json_max_size | 2048 | +| ssl_ca | /etc/memsql/certs/ca.crt | +| ssl_capath | | +| ssl_cert | /etc/memsql/certs/server.crt | +| ssl_cipher | | +| ssl_fips_mode | OFF | +| ssl_key | /etc/memsql/certs/server.key | +| ssl_key_passphrase | [redacted] | +| ssl_last_reload_attempt_time | | +| ssl_last_successful_reload_time | | ++---------------------------------+------------------------------+ +21 rows in set (0.00 sec) +``` + +We can see from the above output that, `have_ssl` is set to `ture`. So, database TLS is enabled successfully to this database. + +## Rotate Certificate + +Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ openssl x509 -in /etc/memsql/certs/server.crt -inform PEM -enddate -nameopt RFC2253 -noout +notAfter=Jan 6 06:56:55 2025 GMT + +``` + +So, the certificate will expire on this time `Jan 6 06:56:55 2025 GMT`. + +### Create SingleStoreOpsRequest + +Now we are going to increase it using a SingleStoreOpsRequest. Below is the yaml of the ops request that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-rotate-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + rotateCertificates: true +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.rotateCertificates` specifies that we want to rotate the certificate of this database. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-rotate-tls.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-rotate-tls created +``` + +#### Verify Certificate Rotated Successfully + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-rotate-tls ReconfigureTLS Successful 4m14s + +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, let's check the expiration date of the certificate. + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ openssl x509 -in /etc/memsql/certs/server.crt -inform PEM -enddate -nameopt RFC2253 -noout +notAfter=Jan 6 07:15:47 2025 GMT + +``` + +As we can see from the above output, the certificate has been rotated successfully. + +## Update Certificate + +Now, we are going to update the server certificate. + +- Let's describe the server certificate `sample-sdb-server-cert` +```bash + $ kubectl describe certificate -n demo sample-sdb-server-cert +Name: sample-sdb-server-cert +Namespace: demo +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=sample-sdb + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=singlestores.kubedb.com +Annotations: +API Version: cert-manager.io/v1 +Kind: Certificate +Metadata: + Creation Timestamp: 2024-10-08T06:56:55Z + Generation: 1 + Owner References: + API Version: kubedb.com/v1alpha2 + Block Owner Deletion: true + Controller: true + Kind: Singlestore + Name: sample-sdb + UID: 5e42538e-c631-4583-9f47-328742e6d938 + Resource Version: 4965452 + UID: 65c6936b-1bd0-413d-a96d-edf0cff17897 +Spec: + Common Name: sample-sdb + Dns Names: + *.sample-sdb-pods.demo.svc + *.sample-sdb-pods.demo.svc.cluster.local + *.sample-sdb.demo.svc + localhost + sample-sdb + sample-sdb.demo.svc + Ip Addresses: + 127.0.0.1 + Issuer Ref: + Group: cert-manager.io + Kind: Issuer + Name: sdb-issuer + Secret Name: sample-sdb-server-cert + Usages: + digital signature + key encipherment + server auth + client auth +Status: + Conditions: + Last Transition Time: 2024-10-08T06:56:56Z + Message: Certificate is up to date and has not expired + Observed Generation: 1 + Reason: Ready + Status: True + Type: Ready + Not After: 2025-01-06T07:15:47Z + Not Before: 2024-10-08T07:15:47Z + Renewal Time: 2024-12-07T07:15:47Z + Revision: 23 +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Generated 23m cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "sample-sdb-server-cert-48d82" + Normal Requested 23m cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-msv5z" + Normal Issuing 23m cert-manager-certificates-trigger Issuing certificate as Secret does not exist + Normal Requested 7m39s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-qpmbp" + Normal Requested 7m38s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-2cldn" + Normal Requested 7m34s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-qtm4z" + Normal Requested 7m33s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-5tflq" + Normal Requested 7m29s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-qzd6h" + Normal Requested 7m28s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-q6bd7" + Normal Requested 7m12s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-jd2cx" + Normal Requested 7m11s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-74dr5" + Normal Requested 7m7s cert-manager-certificates-request-manager Created new CertificateRequest resource "sample-sdb-server-cert-4k2wf" + Normal Reused 5m7s (x22 over 7m39s) cert-manager-certificates-key-manager Reusing private key stored in existing Secret resource "sample-sdb-server-cert" + Normal Issuing 5m7s (x23 over 23m) cert-manager-certificates-issuing The certificate has been successfully issued + Normal Requested 5m7s (x13 over 7m6s) cert-manager-certificates-request-manager (combined from similar events): Created new CertificateRequest resource "sample-sdb-server-cert-qn8g9" + +``` + +We want to add `subject` and `emailAddresses` in the spec of server sertificate. + +### Create SingleStoreOpsRequest + +Below is the YAML of the `SingleStoreOpsRequest` CRO that we are going to create ton update the server certificate, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-update-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + certificates: + - alias: server + subject: + organizations: + - kubedb:server + emailAddresses: + - "kubedb@appscode.com" +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.issuerRef` specifies the issuer name, kind and api group. +- `spec.tls.certificates` specifies the changes that we want in certificate objects. +- `spec.tls.certificates[].alias` specifies the certificate type which is one of these: `server`, `client`. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-update-tls.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-update-tls created + +``` + +#### Verify certificate is updated successfully + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-update-tls ReconfigureTLS Successful 3m24s + + +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. + +Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ openssl x509 -in /etc/memsql/certs/server.crt -inform PEM -subject -email -nameopt RFC2253 -noout +subject=CN=sample-sdb,O=kubedb:server +kubedb@appscode.com +``` + +We can see from the above output that, the subject name and email address match with the new ca certificate that we have created. So, the issuer is changed successfully. + +## Remove TLS from the Database + +Now, we are going to remove TLS from this database using a SingleStoreOpsRequest. + +### Create SingleStoreOpsRequest + +Below is the YAML of the `SingleStoreOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-remove-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: sample-sdb + tls: + remove: true +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.remove` specifies that we want to remove tls from this database. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-remove-tls.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-remove-tls created +``` + +#### Verify TLS Removed Successfully + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-remove-tls ReconfigureTLS Successful 27m +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. If we describe the `SingleStoreOpsRequest` we will get an overview of the steps that were followed. + +Now, Let's exec into the database and find out that TLS is disabled or not. + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ ls etc/memsql/ +memsql_exporter.cnf memsqlctl.hcl +[memsql@sample-sdb-aggregator-0 /]$ +[memsql@sample-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 840 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> show variables like '%ssl%'; ++---------------------------------+------------+ +| Variable_name | Value | ++---------------------------------+------------+ +| default_user_require_ssl | OFF | +| exporter_ssl_ca | | +| exporter_ssl_capath | | +| exporter_ssl_cert | | +| exporter_ssl_key | | +| exporter_ssl_key_passphrase | [redacted] | +| have_openssl | OFF | +| have_ssl | OFF | +| jwks_ssl_ca_certificate | | +| node_replication_ssl_only | OFF | +| openssl_version | 805306480 | +| processlist_rpc_json_max_size | 2048 | +| ssl_ca | | +| ssl_capath | | +| ssl_cert | | +| ssl_cipher | | +| ssl_fips_mode | OFF | +| ssl_key | | +| ssl_key_passphrase | [redacted] | +| ssl_last_reload_attempt_time | | +| ssl_last_successful_reload_time | | ++---------------------------------+------------+ +21 rows in set (0.00 sec) + +singlestore> exit +Bye +``` + +So, we can see from the above that, output that tls is disabled successfully. + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete sdb -n demo --all +$ kubectl delete issuer -n demo --all +$ kubectl delete singlestoreopsrequest -n demo --all +$ kubectl delete ns demo +``` diff --git a/docs/guides/singlestore/reconfigure-tls/overview/images/reconfigure-tls.svg b/docs/guides/singlestore/reconfigure-tls/overview/images/reconfigure-tls.svg new file mode 100644 index 0000000000..cdb554c409 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/overview/images/reconfigure-tls.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guides/singlestore/reconfigure-tls/overview/index.md b/docs/guides/singlestore/reconfigure-tls/overview/index.md new file mode 100644 index 0000000000..39f958d519 --- /dev/null +++ b/docs/guides/singlestore/reconfigure-tls/overview/index.md @@ -0,0 +1,54 @@ +--- +title: Reconfiguring TLS of SingleStore Database +menu: + docs_{{ .version }}: + identifier: guides-sdb-reconfigure-tls-overview + name: Overview + parent: guides-sdb-reconfigure-tls + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Reconfiguring TLS of SingleStore Database + +This guide will give an overview on how KubeDB Ops Manager reconfigures TLS configuration i.e. add TLS, remove TLS, update issuer/cluster issuer or Certificates and rotate the certificates of a `SingleStore` database. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +## How Reconfiguring SingleStore TLS Configuration Process Works + +The following diagram shows how KubeDB Ops Manager reconfigures TLS of a `SingleStore` database. Open the image in a new tab to see the enlarged version. + +
+  Reconfiguring TLS process of SingleStore +
Fig: Reconfiguring TLS process of SingleStore
+
+ +The Reconfiguring SingleStore TLS process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource Object (CRO). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CRO. + +3. When the operator finds a `SingleStore` CR, it creates required number of `PetSets` and related necessary stuff like secrets, services, etc. + +4. Then, in order to reconfigure the TLS configuration of the `SingleStore` database the user creates a `SingleStoreOpsRequest` CR with desired information. + +5. `KubeDB` Ops-manager operator watches the `SingleStoreOpsRequest` CR. + +6. When it finds a `SingleStoreOpsRequest` CR, it pauses the `SingleStore` object which is referred from the `SingleStoreOpsRequest`. So, the `KubeDB` Community operator doesn't perform any operations on the `SingleStore` object during the reconfiguring TLS process. + +7. Then the `KubeDB` Enterprise operator will add, remove, update or rotate TLS configuration based on the Ops Request yaml. + +8. Then the `KubeDB` Enterprise operator will restart all the Pods of the database so that they restart with the new TLS configuration defined in the `SingleStoreOpsRequest` CR. + +9. After the successful reconfiguring of the `SingleStore` TLS, the `KubeDB` Enterprise operator resumes the `SingleStore` object so that the `KubeDB` Community operator resumes its usual operations. + +In the next docs, we are going to show a step by step guide on reconfiguring TLS configuration of a SingleStore database using `SingleStoreOpsRequest` CRD. \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure/_index.md b/docs/guides/singlestore/reconfigure/_index.md new file mode 100644 index 0000000000..831d6b443b --- /dev/null +++ b/docs/guides/singlestore/reconfigure/_index.md @@ -0,0 +1,10 @@ +--- +title: Reconfigure SingleStore Configuration +menu: + docs_{{ .version }}: + identifier: guides-sdb-reconfigure + name: Reconfigure + parent: guides-singlestore + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/reconfigure/overview/images/sdb-reconfigure.svg b/docs/guides/singlestore/reconfigure/overview/images/sdb-reconfigure.svg new file mode 100644 index 0000000000..232221941c --- /dev/null +++ b/docs/guides/singlestore/reconfigure/overview/images/sdb-reconfigure.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guides/singlestore/reconfigure/overview/index.md b/docs/guides/singlestore/reconfigure/overview/index.md new file mode 100644 index 0000000000..88796eb9f2 --- /dev/null +++ b/docs/guides/singlestore/reconfigure/overview/index.md @@ -0,0 +1,54 @@ +--- +title: Reconfiguring SingleStore +menu: + docs_{{ .version }}: + identifier: guides-sdb-reconfigure-overview + name: Overview + parent: guides-sdb-reconfigure + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +### Reconfiguring SingleStore + +This guide will give an overview on how KubeDB Ops Manager reconfigures `SingleStore`. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +## How Reconfiguring SingleStore Process Works + +The following diagram shows how KubeDB Ops Manager reconfigures `SingleStore` database components. Open the image in a new tab to see the enlarged version. + +
+  Reconfiguring process of SingleStore +
Fig: Reconfiguring process of SingleStore
+
+ +The Reconfiguring SingleStore process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource (CR). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CR. + +3. When the operator finds a `SingleStore` CR, it creates required number of `PetSets` and related necessary stuff like secrets, services, etc. + +4. Then, in order to reconfigure the `SingleStore` standalone or cluster the user creates a `SingleStoreOpsRequest` CR with desired information. + +5. `KubeDB` Ops-manager operator watches the `SingleStoreOpsRequest` CR. + +6. When it finds a `SingleStoreOpsRequest` CR, it halts the `SingleStore` object which is referred from the `SingleStoreOpsRequest`. So, the `KubeDB` provisioner operator doesn't perform any operations on the `SingleStore` object during the reconfiguring process. + +7. Then the `KubeDB` Ops-manager operator will replace the existing configuration with the new configuration provided or merge the new configuration with the existing configuration according to the `SingleStoreOpsRequest` CR. + +8. Then the `KubeDB` Ops-manager operator will restart the related PetSet Pods so that they restart with the new configuration defined in the `SingleStoreOpsRequest` CR. + +9. After the successful reconfiguring of the `SingleStore`, the `KubeDB` Ops-manager operator resumes the `SingleStore` object so that the `KubeDB` Provisioner operator resumes its usual operations. + +In the next docs, we are going to show a step by step guide on reconfiguring SingleStore database components using `SingleStoreOpsRequest` CRD. \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure/reconfigure-steps/index.md b/docs/guides/singlestore/reconfigure/reconfigure-steps/index.md new file mode 100644 index 0000000000..dd1b01c344 --- /dev/null +++ b/docs/guides/singlestore/reconfigure/reconfigure-steps/index.md @@ -0,0 +1,477 @@ +--- +title: Reconfigure SingleStore Configuration +menu: + docs_{{ .version }}: + identifier: guides-sdb-reconfigure-reconfigure-steps + name: Reconfigure OpsRequest + parent: guides-sdb-reconfigure + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- +> New to KubeDB? Please start [here](/docs/README.md). + +# Reconfigure SingleStore Cluster Database + +This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure a SingleStore Cluster. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the `kubectl` command-line tool must be configured to communicate with your cluster. + +- Install `KubeDB` Provisioner and Ops-manager operator in your cluster following the steps [here](/docs/setup/README.md). + +- You should be familiar with the following `KubeDB` concepts: +- [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) +- [SingleStore Cluster](/docs/guides/singlestore/clustering) +- [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) +- [Reconfigure Overview](/docs/guides/singlestore/reconfigure/overview) + +To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +Now, we are going to deploy a `SingleStore` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `SingleStoreOpsRequest` to reconfigure its configuration. + +## Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +## Deploy SingleStore + +At first, we will create `sdb-config.cnf` file containing required configuration settings. + +```ini +$ cat sdb-config.cnf +[server] +max_connections = 250 +read_buffer_size = 122880 + +``` + +Here, `max_connections` is set to `250`, whereas the default value is `100000`. Likewise, `read_buffer_size` has the deafult value `131072`. + +Now, we will create a secret with this configuration file. + +```bash +$ kubectl create secret generic -n demo sdb-configuration --from-file=./sdb-config.cnf +secret/sdb-configuration created +``` + +In this section, we are going to create a SingleStore object specifying `spec.topology.aggreagtor.configSecret` field to apply this custom configuration. Below is the YAML of the `SingleStore` CR that we are going to create, + + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: custom-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +Let's create the `SingleStore` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/custom-sdb.yaml +singlestore.kubedb.com/custom-sdb created + + +Now, wait until `custom-sdb` has status `Ready`. i.e, + +```bash +$ kubectl get pod -n demo +NAME READY STATUS RESTARTS AGE +custom-sdb-aggregator-0 2/2 Running 0 94s +custom-sdb-aggregator-1 2/2 Running 0 88s +custom-sdb-leaf-0 2/2 Running 0 91s +custom-sdb-leaf-1 2/2 Running 0 86s + +$ kubectl get sdb -n demo +NAME TYPE VERSION STATUS AGE +custom-sdb kubedb.com/v1alpha2 8.7.10 Ready 4m29s +``` + +We can see the database is in ready phase so it can accept conncetion. + +Now, we will check if the database has started with the custom configuration we have provided. + +> Read the comment written for the following commands. They contain the instructions and explanations of the commands. + +```bash +# Connceting to the database +$ kubectl exec -it -n demo custom-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@custom-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 208 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +# value of `max_conncetions` is same as provided +singlestore> show variables like 'max_connections'; ++-----------------+-------+ +| Variable_name | Value | ++-----------------+-------+ +| max_connections | 250 | ++-----------------+-------+ +1 row in set (0.00 sec) + +# value of `read_buffer_size` is same as provided +singlestore> show variables like 'read_buffer_size'; ++------------------+--------+ +| Variable_name | Value | ++------------------+--------+ +| read_buffer_size | 122880 | ++------------------+--------+ +1 row in set (0.00 sec) + +singlestore> exit +Bye + +``` + +As we can see from the configuration of ready singlestore, the value of `max_connections` has been set to `250` and `read_buffer_size` has been set to `122880`. + +### Reconfigure using new config secret + +Now we will reconfigure this database to set `max_connections` to `350` and `read_buffer_size` to `132880`. + +Now, we will create new file `new-sdb-config.cnf` containing required configuration settings. + +#### Create SingleStoreOpsRequest + +Now, we will use this secret to replace the previous secret using a `SingleStoreOpsRequest` CR. The `SingleStoreOpsRequest` yaml is given below, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-config + namespace: demo +spec: + type: Configuration + databaseRef: + name: custom-sdb + configuration: + aggregator: + applyConfig: + sdb-apply.cnf: |- + max_connections = 550 +``` + +Here, + +- `spec.databaseRef.name` specifies that we are reconfiguring `custom-sdb` database. +- `spec.type` specifies that we are performing `Configuration` on our database. +- `spec.configuration.aggregator.applyConfig` is a map where key supports 1 values, namely `sdb-apply.cnf` for aggregator nodes. You can also specifies `spec.configuration.leaf.applyConfig` which is a map where key supports 1 values, namely `sdb-apply.cnf` for leaf nodes. + +Let's create the `SinglestoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-steps/yamls/reconfigure-using-applyConfig.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-reconfigure-config created +``` + +#### Verify the new configuration is working + +If everything goes well, `KubeDB` Ops-manager operator will update the `configSecret` of `SingleStore` object. + +Let's wait for `SinglestoreOpsRequest` to be `Successful`. Run the following command to watch `SinglestoreOpsRequest` CR, + +```bash +$ kubectl get singlestoreopsrequest --all-namespaces +NAMESPACE NAME TYPE STATUS AGE +demo sdbops-reconfigure-config Configuration Successful 10m + +``` + +We can see from the above output that the `SinglestoreOpsRequest` has succeeded. If we describe the `SinglestoreOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. + +```bash +$ kubectl describe singlestoreopsrequest -n demo sdbops-reconfigure-config +Name: sdbops-reconfigure-config +Namespace: demo +Labels: +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: SinglestoreOpsRequest +Metadata: + Creation Timestamp: 2024-10-04T10:18:22Z + Generation: 1 + Resource Version: 2114236 + UID: 56b37f6d-d8be-49c7-a588-9740863edd2a +Spec: + Apply: IfReady + Configuration: + Aggregator: + Apply Config: + sdb-apply.cnf: max_connections = 550 + Database Ref: + Name: custom-sdb + Type: Configuration +Status: + Conditions: + Last Transition Time: 2024-10-04T10:18:22Z + Message: Singlestore ops-request has started to expand volume of singlestore nodes. + Observed Generation: 1 + Reason: Configuration + Status: True + Type: Configuration + Last Transition Time: 2024-10-04T10:18:28Z + Message: Successfully paused database + Observed Generation: 1 + Reason: DatabasePauseSucceeded + Status: True + Type: DatabasePauseSucceeded + Last Transition Time: 2024-10-04T10:18:28Z + Message: Successfully updated PetSets Resources + Observed Generation: 1 + Reason: UpdatePetSets + Status: True + Type: UpdatePetSets + Last Transition Time: 2024-10-04T10:19:53Z + Message: Successfully Restarted Pods With Resources + Observed Generation: 1 + Reason: RestartPods + Status: True + Type: RestartPods + Last Transition Time: 2024-10-04T10:18:33Z + Message: get pod; ConditionStatus:True; PodName:custom-sdb-aggregator-0 + Observed Generation: 1 + Status: True + Type: GetPod--custom-sdb-aggregator-0 + Last Transition Time: 2024-10-04T10:18:33Z + Message: evict pod; ConditionStatus:True; PodName:custom-sdb-aggregator-0 + Observed Generation: 1 + Status: True + Type: EvictPod--custom-sdb-aggregator-0 + Last Transition Time: 2024-10-04T10:19:08Z + Message: check pod ready; ConditionStatus:True; PodName:custom-sdb-aggregator-0 + Observed Generation: 1 + Status: True + Type: CheckPodReady--custom-sdb-aggregator-0 + Last Transition Time: 2024-10-04T10:19:13Z + Message: get pod; ConditionStatus:True; PodName:custom-sdb-aggregator-1 + Observed Generation: 1 + Status: True + Type: GetPod--custom-sdb-aggregator-1 + Last Transition Time: 2024-10-04T10:19:13Z + Message: evict pod; ConditionStatus:True; PodName:custom-sdb-aggregator-1 + Observed Generation: 1 + Status: True + Type: EvictPod--custom-sdb-aggregator-1 + Last Transition Time: 2024-10-04T10:19:48Z + Message: check pod ready; ConditionStatus:True; PodName:custom-sdb-aggregator-1 + Observed Generation: 1 + Status: True + Type: CheckPodReady--custom-sdb-aggregator-1 + Last Transition Time: 2024-10-04T10:19:53Z + Message: Successfully completed the reconfiguring for Singlestore + Observed Generation: 1 + Reason: Successful + Status: True + Type: Successful + Observed Generation: 1 + Phase: Successful +Events: + +``` + +Now let's connect to a singlestore instance and run a memsql internal command to check the new configuration we have provided. + +```bash +$ kubectl exec -it -n demo custom-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@custom-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 626 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> show variables like 'max_connections'; ++-----------------+-------+ +| Variable_name | Value | ++-----------------+-------+ +| max_connections | 550 | ++-----------------+-------+ +1 row in set (0.00 sec) + +singlestore> exit +Bye + + +``` + +As we can see from the configuration has changed, the value of `max_connections` has been changed from `250` to `550`. So the reconfiguration of the database is successful. + +### Remove Custom Configuration + +We can also remove exisiting custom config using `SinglestoreOpsRequest`. Provide `true` to field `spec.configuration.aggregator.removeCustomConfig` and make an Ops Request to remove existing custom configuration. + +#### Create SingleStoreOpsRequest + +Lets create an `SinglestoreOpsRequest` having `spec.configuration.aggregator.removeCustomConfig` is equal `true`, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-remove + namespace: demo +spec: + type: Configuration + databaseRef: + name: custom-sdb + configuration: + aggregator: + removeCustomConfig: true +``` + +Here, + +- `spec.databaseRef.name` specifies that we are reconfiguring `custom-sdb` database. +- `spec.type` specifies that we are performing `Reconfigure` on our database. +- `spec.configuration.aggregator.removeCustomConfig` is a bool field that should be `true` when you want to remove existing custom configuration. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure/yamls/reconfigure-steps/reconfigure-remove.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-reconfigure-remove created +``` + +#### Verify the new configuration is working + +If everything goes well, `KubeDB` Ops-manager operator will update the `configSecret` of `SingleStore` object. + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-reconfigure-remove Configuration Successful 5m31s +``` + +Now let's connect to a singlestore instance and run a singlestore internal command to check the new configuration we have provided. + +```bash +$ kubectl exec -it -n demo custom-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@custom-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 166 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> +singlestore> +singlestore> show variables like 'max_connections'; ++-----------------+-------+ +| Variable_name | Value | ++-----------------+-------+ +| max_connections | 100000| ++-----------------+-------+ +1 row in set (0.00 sec) + +singlestore> exit +Bye + + +``` + +As we can see from the configuration has changed to its default value. So removal of existing custom configuration using `SingleStoreOpsRequest` is successful. + +## Cleaning Up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete singlestore -n demo custom-sdb +$ kubectl delete singlestoreopsrequest -n demo sdbops-reconfigure-config sdbops-reconfigure-remove +$ kubectl delete ns demo +``` diff --git a/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/custom-sdb.yaml b/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/custom-sdb.yaml new file mode 100644 index 0000000000..8438852626 --- /dev/null +++ b/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/custom-sdb.yaml @@ -0,0 +1,56 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: custom-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + configSecret: + name: sdb-configuration + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/reconfigure-remove.yaml b/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/reconfigure-remove.yaml new file mode 100644 index 0000000000..b557e898e9 --- /dev/null +++ b/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/reconfigure-remove.yaml @@ -0,0 +1,12 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-config + namespace: demo +spec: + type: Configuration + databaseRef: + name: custom-sdb + configuration: + aggregator: + removeCustomConfig: true \ No newline at end of file diff --git a/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/reconfigure-using-applyConfig.yaml b/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/reconfigure-using-applyConfig.yaml new file mode 100644 index 0000000000..65b617765d --- /dev/null +++ b/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/reconfigure-using-applyConfig.yaml @@ -0,0 +1,14 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-reconfigure-config + namespace: demo +spec: + type: Configuration + databaseRef: + name: custom-sdb + configuration: + aggregator: + applyConfig: + sdb-apply.cnf: |- + max_connections = 550 \ No newline at end of file diff --git a/docs/guides/singlestore/restart/_index.md b/docs/guides/singlestore/restart/_index.md new file mode 100644 index 0000000000..100ea6b049 --- /dev/null +++ b/docs/guides/singlestore/restart/_index.md @@ -0,0 +1,10 @@ +--- +title: Restart SingleStore +menu: + docs_{{ .version }}: + identifier: sdb-restart + name: Restart + parent: guides-singlestore + weight: 49 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/restart/restart.md b/docs/guides/singlestore/restart/restart.md new file mode 100644 index 0000000000..5fa613bd30 --- /dev/null +++ b/docs/guides/singlestore/restart/restart.md @@ -0,0 +1,266 @@ +--- +title: Restart SingleStore +menu: + docs_{{ .version }}: + identifier: sdb-restart-details + name: Restart SingleStore + parent: sdb-restart + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Restart SingleStore + +KubeDB supports restarting the SingleStore database via a SingleStoreOpsRequest. Restarting is useful if some pods are got stuck in some phase, or they are not working correctly. This tutorial will show you how to use that. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + +```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/restart/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +## Deploy SingleStore + +In this section, we are going to deploy a SingleStore database using KubeDB. + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable +``` + +Let's create the `SingleStore` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls/sdb-sample.yaml +singlestore.kubedb.com/sdb-sample created +``` +**Wait for the database to be ready:** + +Now, wait for `SingleStore` going on `Ready` state + +```bash +kubectl get singlestore -n demo +NAME TYPE VERSION STATUS AGE +sdb-sample kubedb.com/v1alpha2 8.7.10 Ready 2m + +``` + +## Apply Restart opsRequest + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: restart + namespace: demo +spec: + type: Restart + databaseRef: + name: sdb-sample + timeout: 10m + apply: Always +``` + +- `spec.type` specifies the Type of the ops Request +- `spec.databaseRef` holds the name of the SingleStore database. The db should be available in the same namespace as the opsRequest +- The meaning of `spec.timeout` & `spec.apply` fields will be found [here](/docs/guides/rabbitmq/concepts/opsrequest.md#spectimeout) + +> Note: The method of restarting the standalone & clustered singlestore is exactly same as above. All you need, is to specify the corresponding SingleStore name in `spec.databaseRef.name` section. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls/restart-ops.yaml +singlestoreopsrequest.ops.kubedb.com/restart created +``` + +Now the Ops-manager operator will restart the pods sequentially by their cardinal suffix. + +```shell +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +restart Restart Successful 10m + +$ kubectl get singlestoreopsrequest -n demo restart -oyaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"ops.kubedb.com/v1alpha1","kind":"SinglestoreOpsRequest","metadata":{"annotations":{},"name":"restart","namespace":"demo"},"spec":{"apply":"Always","databaseRef":{"name":"sdb-sample"},"timeout":"10m","type":"Restart"}} + creationTimestamp: "2024-10-28T05:31:00Z" + generation: 1 + name: restart + namespace: demo + resourceVersion: "3549386" + uid: b2512e44-89eb-4f1b-ae0d-232caee94f01 +spec: + apply: Always + databaseRef: + name: sdb-sample + timeout: 10m + type: Restart +status: + conditions: + - lastTransitionTime: "2024-10-28T05:31:00Z" + message: Singlestore ops-request has started to restart singlestore nodes + observedGeneration: 1 + reason: Restart + status: "True" + type: Restart + - lastTransitionTime: "2024-10-28T05:31:03Z" + message: Successfully paused database + observedGeneration: 1 + reason: DatabasePauseSucceeded + status: "True" + type: DatabasePauseSucceeded + - lastTransitionTime: "2024-10-28T05:33:33Z" + message: Successfully restarted Singlestore nodes + observedGeneration: 1 + reason: RestartNodes + status: "True" + type: RestartNodes + - lastTransitionTime: "2024-10-28T05:31:08Z" + message: get pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + observedGeneration: 1 + status: "True" + type: GetPod--sdb-sample-aggregator-0 + - lastTransitionTime: "2024-10-28T05:31:08Z" + message: evict pod; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + observedGeneration: 1 + status: "True" + type: EvictPod--sdb-sample-aggregator-0 + - lastTransitionTime: "2024-10-28T05:31:48Z" + message: check pod ready; ConditionStatus:True; PodName:sdb-sample-aggregator-0 + observedGeneration: 1 + status: "True" + type: CheckPodReady--sdb-sample-aggregator-0 + - lastTransitionTime: "2024-10-28T05:31:53Z" + message: get pod; ConditionStatus:True; PodName:sdb-sample-leaf-0 + observedGeneration: 1 + status: "True" + type: GetPod--sdb-sample-leaf-0 + - lastTransitionTime: "2024-10-28T05:31:53Z" + message: evict pod; ConditionStatus:True; PodName:sdb-sample-leaf-0 + observedGeneration: 1 + status: "True" + type: EvictPod--sdb-sample-leaf-0 + - lastTransitionTime: "2024-10-28T05:32:38Z" + message: check pod ready; ConditionStatus:True; PodName:sdb-sample-leaf-0 + observedGeneration: 1 + status: "True" + type: CheckPodReady--sdb-sample-leaf-0 + - lastTransitionTime: "2024-10-28T05:32:43Z" + message: get pod; ConditionStatus:True; PodName:sdb-sample-leaf-1 + observedGeneration: 1 + status: "True" + type: GetPod--sdb-sample-leaf-1 + - lastTransitionTime: "2024-10-28T05:32:43Z" + message: evict pod; ConditionStatus:True; PodName:sdb-sample-leaf-1 + observedGeneration: 1 + status: "True" + type: EvictPod--sdb-sample-leaf-1 + - lastTransitionTime: "2024-10-28T05:33:28Z" + message: check pod ready; ConditionStatus:True; PodName:sdb-sample-leaf-1 + observedGeneration: 1 + status: "True" + type: CheckPodReady--sdb-sample-leaf-1 + - lastTransitionTime: "2024-10-28T05:33:33Z" + message: Controller has successfully restart the Singlestore replicas + observedGeneration: 1 + reason: Successful + status: "True" + type: Successful + observedGeneration: 1 + phase: Successful +``` + + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete singlestoreopsrequest -n demo restart +kubectl delete singlestore -n demo sdb-sample +kubectl delete ns demo +``` + +## Next Steps + +- Detail concepts of [SingleStore object](/docs/guides/singlestore/concepts/singlestore.md). +- Monitor your SingleStore database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/singlestore/monitoring/prometheus-operator/index.md). +- Monitor your SingleStore database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/singlestore/monitoring/builtin-prometheus/index.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/singlestore/restart/yamls/restart-ops.yaml b/docs/guides/singlestore/restart/yamls/restart-ops.yaml new file mode 100644 index 0000000000..4271b8adb0 --- /dev/null +++ b/docs/guides/singlestore/restart/yamls/restart-ops.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: restart + namespace: demo +spec: + type: Restart + databaseRef: + name: sdb-sample + timeout: 10m + apply: Always \ No newline at end of file diff --git a/docs/guides/singlestore/restart/yamls/sdb-sample.yaml b/docs/guides/singlestore/restart/yamls/sdb-sample.yaml new file mode 100644 index 0000000000..67a26cdcf0 --- /dev/null +++ b/docs/guides/singlestore/restart/yamls/sdb-sample.yaml @@ -0,0 +1,51 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-sample + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/_index.md b/docs/guides/singlestore/scaling/_index.md new file mode 100644 index 0000000000..809575b24b --- /dev/null +++ b/docs/guides/singlestore/scaling/_index.md @@ -0,0 +1,10 @@ +--- +title: Scaling SingleStore +menu: + docs_{{ .version }}: + identifier: guides-sdb-scaling + name: Scaling + parent: guides-singlestore + weight: 43 +menu_name: docs_{{ .version }} +--- \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/_index.md b/docs/guides/singlestore/scaling/horizontal-scaling/_index.md new file mode 100644 index 0000000000..7c75aacefb --- /dev/null +++ b/docs/guides/singlestore/scaling/horizontal-scaling/_index.md @@ -0,0 +1,10 @@ +--- +title: Horizontal Scaling +menu: + docs_{{ .version }}: + identifier: guides-sdb-scaling-horizontal + name: Horizontal Scaling + parent: guides-sdb-scaling + weight: 10 +menu_name: docs_{{ .version }} +--- \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sample-sdb.yaml b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sample-sdb.yaml new file mode 100644 index 0000000000..437685dccf --- /dev/null +++ b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sample-sdb.yaml @@ -0,0 +1,52 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-downscale.yaml b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-downscale.yaml new file mode 100644 index 0000000000..4ca154c9d2 --- /dev/null +++ b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-downscale.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-scale-horizontal-down + namespace: demo +spec: + type: HorizontalScaling + databaseRef: + name: sample-sdb + horizontalScaling: + leaf: 2 \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-upscale.yaml b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-upscale.yaml new file mode 100644 index 0000000000..26c0b50178 --- /dev/null +++ b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-upscale.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-scale-horizontal-up + namespace: demo +spec: + type: HorizontalScaling + databaseRef: + name: sample-sdb + horizontalScaling: + leaf: 3 \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/cluster/index.md b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/index.md new file mode 100644 index 0000000000..7b289a738e --- /dev/null +++ b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/index.md @@ -0,0 +1,326 @@ +--- +title: Horizontal Scaling SingleStore +menu: + docs_{{ .version }}: + identifier: guides-sdb-scaling-horizontal-cluster + name: Horizontal Scaling OpsRequest + parent: guides-sdb-scaling-horizontal + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Horizontal Scale SingleStore + +This guide will show you how to use `KubeDB` Enterprise operator to scale the cluster of a SingleStore database. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the `kubectl` command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install `KubeDB` Community and Enterprise operator in your cluster following the steps [here](/docs/setup/README.md). + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStore Cluster](/docs/guides/singlestore/clustering/) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + - [Horizontal Scaling Overview](/docs/guides/singlestore/scaling/horizontal-scaling/overview/) + +To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +## Apply Horizontal Scaling on Cluster + +Here, we are going to deploy a `SingleStore` cluster using a supported version by `KubeDB` operator. Then we are going to apply horizontal scaling on it. + +### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +### Deploy SingleStore Cluster + +In this section, we are going to deploy a SingleStore cluster. Then, in the next section we will scale the database using `SingleStoreOpsRequest` CRD. Below is the YAML of the `SingleStore` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +Let's create the `SingleStore` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sample-sdb.yaml +singlestore.kubedb.com/sample-sdb created +``` + +Now, wait until `sample-sdb` has status `Ready`. i.e, + +```bash +$ kubectl get singlestore -n demo +NAME TYPE VERSION STATUS AGE +sample-sdb kubedb.com/v1alpha2 8.7.10 Ready 86s +``` + +Let's check the number of `aggreagtor replicas` and `leaf replicas` this database has from the SingleStore object, number of pods the `aggregator-petset` and `leaf-petset` have, + +```bash +$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.aggregator.replicas' +1 +$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' +2 + +$ kubectl get petset -n demo sample-sdb-aggregator -o=jsonpath='{.spec.replicas}{"\n"}' +1 +kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' +2 + + +``` + +We can see from both command that the database has 1 `aggregator replicas` and 2 `leaf replicas` in the cluster. + +Also, we can verify the replicas of the from an internal memsqlctl command by execing into a replica. + +Now let's connect to a singlestore instance and run a memsqlctl internal command to check the number of replicas, + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ memsqlctl show-cluster ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ +| Role | Host | Port | Availability Group | Pair Host | Pair Port | State | Opened Connections | Average Roundtrip Latency ms | NodeId | Master Aggregator | ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ +| Leaf | sample-sdb-leaf-0.sample-sdb-pods.demo.svc | 3306 | 1 | null | null | online | 2 | | 2 | | +| Leaf | sample-sdb-leaf-1.sample-sdb-pods.demo.svc | 3306 | 1 | null | null | online | 3 | | 3 | | +| Aggregator (Leader) | sample-sdb-aggregator-0.sample-sdb-pods.demo.svc | 3306 | | null | null | online | 1 | null | 1 | 1 | ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ + + +``` + +We can see from the above output that the cluster has 1 aggregator node and 2 leaf nodes. + +We are now ready to apply the `SingleStoreOpsRequest` CR to scale this database. + +## Scale Up Replicas + +Here, we are going to scale up the replicas of the `leaf nodes` to meet the desired number of replicas after scaling. + +#### Create SingleStoreOpsRequest + +In order to scale up the replicas of the `leaf nodes` of the database, we have to create a `SingleStoreOpsRequest` CR with our desired replicas. Below is the YAML of the `SingleStoreOpsRequest` CR that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-scale-horizontal-up + namespace: demo +spec: + type: HorizontalScaling + databaseRef: + name: sample-sdb + horizontalScaling: + leaf: 3 +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing horizontal scaling operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `HorizontalScaling` on our database. +- `spec.horizontalScaling.leaf` specifies the desired leaf replicas after scaling. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-upscale.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-scale-horizontal-up created +``` + +#### Verify Cluster replicas scaled up successfully + +If everything goes well, `KubeDB` Enterprise operator will update the replicas of `SingleStore` object and related `PetSets` and `Pods`. + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, + +```bash + $ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-scale-horizontal-up HorizontalScaling Successful 74s +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to verify the number of `leaf replicas` this database has from the SingleStore object, number of pods the `leaf petset` have, + +```bash +$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' +3 +$ kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' +3 + +``` + +Now let's connect to a singlestore instance and run a memsqlctl internal command to check the number of replicas, + +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sample-sdb-aggregator-0 /]$ memsqlctl show-cluster ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ +| Role | Host | Port | Availability Group | Pair Host | Pair Port | State | Opened Connections | Average Roundtrip Latency ms | NodeId | Master Aggregator | ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ +| Leaf | sample-sdb-leaf-0.sample-sdb-pods.demo.svc | 3306 | 1 | null | null | online | 2 | | 2 | | +| Leaf | sample-sdb-leaf-1.sample-sdb-pods.demo.svc | 3306 | 1 | null | null | online | 3 | | 3 | | +| Leaf | sample-sdb-leaf-2.sample-sdb-pods.demo.svc | 3306 | 1 | null | null | online | 2 | | 4 | | +| Aggregator (Leader) | sample-sdb-aggregator-0.sample-sdb-pods.demo.svc | 3306 | | null | null | online | 1 | null | 1 | 1 | ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ + +``` + +From all the above outputs we can see that the `leaf replicas` of the cluster is `3`. That means we have successfully scaled up the `leaf replicas` of the SingleStore Cluster. + +### Scale Down Replicas + +Here, we are going to scale down the `leaf replicas` of the cluster to meet the desired number of replicas after scaling. + +#### Create SingleStoreOpsRequest + +In order to scale down the cluster of the database, we have to create a `SingleStoreOpsRequest` CR with our desired replicas. Below is the YAML of the `SingleStoreOpsRequest` CR that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-scale-horizontal-down + namespace: demo +spec: + type: HorizontalScaling + databaseRef: + name: sample-sdb + horizontalScaling: + leaf: 2 +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing horizontal scaling down operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `HorizontalScaling` on our database. +- `spec.horizontalScaling.leaf` specifies the desired `leaf replicas` after scaling. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-downscale.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-scale-horizontal-down created +``` + +#### Verify Cluster replicas scaled down successfully + +If everything goes well, `KubeDB` Enterprise operator will update the replicas of `SingleStore` object and related `PetSets` and `Pods`. + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-scale-horizontal-down HorizontalScaling Successful 63s +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to verify the number of `leaf replicas` this database has from the SingleStore object, number of pods the `leaf petset` have, + +```bash +$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' +2 +$ kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' +2 + +``` + +Now let's connect to a singlestore instance and run a memsqlctl internal command to check the number of replicas, +```bash +$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +bash: mesqlctl: command not found +[memsql@sample-sdb-aggregator-0 /]$ memsqlctl show-cluster ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ +| Role | Host | Port | Availability Group | Pair Host | Pair Port | State | Opened Connections | Average Roundtrip Latency ms | NodeId | Master Aggregator | ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ +| Leaf | sample-sdb-leaf-0.sample-sdb-pods.demo.svc | 3306 | 1 | null | null | online | 2 | | 2 | | +| Leaf | sample-sdb-leaf-1.sample-sdb-pods.demo.svc | 3306 | 1 | null | null | online | 3 | | 3 | | +| Aggregator (Leader) | sample-sdb-aggregator-0.sample-sdb-pods.demo.svc | 3306 | | null | null | online | 1 | null | 1 | 1 | ++---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ + +``` + +From all the above outputs we can see that the `leaf replicas` of the cluster is `2`. That means we have successfully scaled down the `leaf replicas` of the SingleStore database. + +## Cleaning Up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete sdb -n demo sample-sdb +$ kubectl delete singlestoreopsrequest -n demo sdbops-scale-horizontal-up sdbops-scale-horizontal-down +``` \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/overview/images/horizontal-scaling.svg b/docs/guides/singlestore/scaling/horizontal-scaling/overview/images/horizontal-scaling.svg new file mode 100644 index 0000000000..6d09610348 --- /dev/null +++ b/docs/guides/singlestore/scaling/horizontal-scaling/overview/images/horizontal-scaling.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/overview/index.md b/docs/guides/singlestore/scaling/horizontal-scaling/overview/index.md new file mode 100644 index 0000000000..ade92b2c09 --- /dev/null +++ b/docs/guides/singlestore/scaling/horizontal-scaling/overview/index.md @@ -0,0 +1,54 @@ +--- +title: SingleStore Horizontal Scaling Overview +menu: + docs_{{ .version }}: + identifier: guides-sdb-scaling-horizontal-overview + name: Overview + parent: guides-sdb-scaling-horizontal + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore Horizontal Scaling + +This guide will give an overview on how KubeDB Ops Manager scales up or down `SingleStore Cluster`. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +## How Horizontal Scaling Process Works + +The following diagram shows how KubeDB Ops Manager scales up or down `SingleStore` database components. Open the image in a new tab to see the enlarged version. + +
+  Horizontal scaling process of SingleStore +
Fig: Horizontal scaling process of SingleStore
+
+ +The Horizontal scaling process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource (CR). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CR. + +3. When the operator finds a `SingleStore` CR, it creates required number of `PetSets` and related necessary stuff like secrets, services, etc. + +4. Then, in order to scale the `SingleStore` database the user creates a `SingleStoreOpsRequest` CR with desired information. + +5. `KubeDB` Ops-manager operator watches the `SingleStoreOpsRequest` CR. + +6. When it finds a `SingleStoreOpsRequest` CR, it pauses the `SingleStore` object which is referred from the `SingleStoreOpsRequest`. So, the `KubeDB` Provisioner operator doesn't perform any operations on the `SingleStore` object during the horizontal scaling process. + +7. Then the `KubeDB` Ops-manager operator will scale the related PetSet Pods to reach the expected number of replicas defined in the `SingleStoreOpsRequest` CR. + +8. After the successfully scaling the replicas of the PetSet Pods, the `KubeDB` Ops-manager operator updates the number of replicas in the `SingleStore` object to reflect the updated state. + +9. After the successful scaling of the `SingleStore` replicas, the `KubeDB` Ops-manager operator resumes the `SingleStore` object so that the `KubeDB` Provisioner operator resumes its usual operations. + +In the next docs, we are going to show a step by step guide on horizontal scaling of SingleStore database using `SingleStoreOpsRequest` CRD. diff --git a/docs/guides/singlestore/scaling/vertical-scaling/_index.md b/docs/guides/singlestore/scaling/vertical-scaling/_index.md new file mode 100644 index 0000000000..7d88aa0a8d --- /dev/null +++ b/docs/guides/singlestore/scaling/vertical-scaling/_index.md @@ -0,0 +1,10 @@ +--- +title: Vertical Scaling +menu: + docs_{{ .version }}: + identifier: guides-sdb-scaling-vertical + name: Vertical Scaling + parent: guides-sdb-scaling + weight: 20 +menu_name: docs_{{ .version }} +--- \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sample-sdb.yaml b/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sample-sdb.yaml new file mode 100644 index 0000000000..437685dccf --- /dev/null +++ b/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sample-sdb.yaml @@ -0,0 +1,52 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sdbops-vscale.yaml b/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sdbops-vscale.yaml new file mode 100644 index 0000000000..661a44385e --- /dev/null +++ b/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sdbops-vscale.yaml @@ -0,0 +1,18 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-vscale + namespace: demo +spec: + type: VerticalScaling + databaseRef: + name: sample-sdb + verticalScaling: + aggregator: + resources: + requests: + memory: "2500Mi" + cpu: "0.7" + limits: + memory: "2500Mi" + cpu: "0.7" \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/vertical-scaling/cluster/index.md b/docs/guides/singlestore/scaling/vertical-scaling/cluster/index.md new file mode 100644 index 0000000000..dab35d70ea --- /dev/null +++ b/docs/guides/singlestore/scaling/vertical-scaling/cluster/index.md @@ -0,0 +1,226 @@ +--- +title: Vertical Scaling SingleStore Cluster +menu: + docs_{{ .version }}: + identifier: guides-sdb-scaling-vertical-cluster + name: Vertical Scaling OpsRequest + parent: guides-sdb-scaling-vertical + weight: 30 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Vertical Scale SingleStore Cluster + +This guide will show you how to use `KubeDB` Enterprise operator to update the resources of a SingleStore cluster database. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the `kubectl` command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install `KubeDB` Community and Enterprise operator in your cluster following the steps [here](/docs/setup/README.md). + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [Clustering](/docs/guides/singlestore/clustering/singlestore-clustering/) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + - [Vertical Scaling Overview](/docs/guides/singlestore/scaling/vertical-scaling/overview/) + +To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +## Apply Vertical Scaling on Cluster + +Here, we are going to deploy a `SingleStore` cluster using a supported version by `KubeDB` operator. Then we are going to apply vertical scaling on it. + +### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +### Deploy SingleStore Cluster + +In this section, we are going to deploy a SingleStore cluster database. Then, in the next section we will update the resources of the database using `SingleStoreOpsRequest` CRD. Below is the YAML of the `SingleStore` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +Let's create the `SingleStore` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sample-sdb.yaml +singlestore.kubedb.com/sample-sdb created +``` + +Now, wait until `sample-sdb` has status `Ready`. i.e, + +```bash +$ kubectl get sdb -n demo +NAME TYPE VERSION STATUS AGE +sample-sdb kubedb.com/v1alpha2 8.7.10 Ready 101s +``` + +Let's check the Pod containers resources, + +```bash +$ kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers[].resources' +{ + "limits": { + "cpu": "600m", + "memory": "2Gi" + }, + "requests": { + "cpu": "600m", + "memory": "2Gi" + } +} + +``` + +We are now ready to apply the `SingleStoreOpsRequest` CR to update the resources of this database. + +### Vertical Scaling + +Here, we are going to update the resources of the database to meet the desired resources after scaling. + +#### Create SingleStoreOpsRequest + +In order to update the resources of the database, we have to create a `SingleStoreOpsRequest` CR with our desired resources. Below is the YAML of the `SingleStoreOpsRequest` CR that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdbops-vscale + namespace: demo +spec: + type: VerticalScaling + databaseRef: + name: sample-sdb + verticalScaling: + aggregator: + resources: + requests: + memory: "2500Mi" + cpu: "0.7" + limits: + memory: "2500Mi" + cpu: "0.7" +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing vertical scaling operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `VerticalScaling` on our database. +- `spec.VerticalScaling.aggregator` specifies the desired `aggregator` nodes resources after scaling. As well you can scale resources for leaf node, standalone node and coordinator container. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sdbops-vscale.yaml +singlestoreopsrequest.ops.kubedb.com/sdbops-vscale created +``` + +#### Verify SingleStore Cluster resources updated successfully + +If everything goes well, `KubeDB` Enterprise operator will update the resources of `SingleStore` object and related `PetSets` and `Pods`. + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdbops-vscale VerticalScaling Successful 7m30s +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to verify from one of the Pod yaml whether the resources of the database has updated to meet up the desired state, Let's check, + +```bash +$ kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers[].resources' +{ + "limits": { + "cpu": "700m", + "memory": "2500Mi" + }, + "requests": { + "cpu": "700m", + "memory": "2500Mi" + } +} + +``` + +The above output verifies that we have successfully scaled up the resources of the SingleStore database. + +## Cleaning Up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete sdb -n demo sample-sdb +$ kubectl delete singlestoreopsrequest -n demo sdbops-vscale +``` \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/vertical-scaling/overview/images/vertical-sacling.svg b/docs/guides/singlestore/scaling/vertical-scaling/overview/images/vertical-sacling.svg new file mode 100644 index 0000000000..8f0e835339 --- /dev/null +++ b/docs/guides/singlestore/scaling/vertical-scaling/overview/images/vertical-sacling.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guides/singlestore/scaling/vertical-scaling/overview/index.md b/docs/guides/singlestore/scaling/vertical-scaling/overview/index.md new file mode 100644 index 0000000000..ae12482b8c --- /dev/null +++ b/docs/guides/singlestore/scaling/vertical-scaling/overview/index.md @@ -0,0 +1,52 @@ +--- +title: SingleStore Vertical Scaling Overview +menu: + docs_{{ .version }}: + identifier: guides-sdb-scaling-vertical-overview + name: Overview + parent: guides-sdb-scaling-vertical + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore Vertical Scaling + +This guide will give an overview on how KubeDB Ops Manager vertically scales up `SingleStore`. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +The following diagram shows how KubeDB Ops Manager scales up or down `SingleStore` database components. Open the image in a new tab to see the enlarged version. + +
+  Vertical scaling process of SingleStore +
Fig: Vertical scaling process of SingleStore
+
+ +The vertical scaling process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource (CR). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CR. + +3. When the operator finds a `SingleStore` CR, it creates required number of `PetSets` and related necessary stuff like secrets, services, etc. + +4. Then, in order to update the resources(for example `CPU`, `Memory` etc.) of the `SingleStore` database the user creates a `SingleStoreOpsRequest` CR with desired information. + +5. `KubeDB` Ops-manager operator watches the `SingleStoreOpsRequest` CR. + +6. When it finds a `SingleStoreOpsRequest` CR, it halts the `SingleStore` object which is referred from the `SingleStoreOpsRequest`. So, the `KubeDB` Provisioner operator doesn't perform any operations on the `SingleStore` object during the vertical scaling process. + +7. Then the `KubeDB` Ops-manager operator will update resources of the PetSet Pods to reach desired state. + +8. After the successful update of the resources of the PetSet's replica, the `KubeDB` Ops-manager operator updates the `SingleStore` object to reflect the updated state. + +9. After the successful update of the `SingleStore` resources, the `KubeDB` Ops-manager operator resumes the `SingleStore` object so that the `KubeDB` Provisioner operator resumes its usual operations. + +In the next docs, we are going to show a step by step guide on updating resources of SingleStore database using `SingleStoreOpsRequest` CRD. \ No newline at end of file diff --git a/docs/guides/singlestore/tls/_index.md b/docs/guides/singlestore/tls/_index.md new file mode 100644 index 0000000000..9503da0132 --- /dev/null +++ b/docs/guides/singlestore/tls/_index.md @@ -0,0 +1,10 @@ +--- +title: TLS/SSL Encryption +menu: + docs_{{ .version }}: + identifier: guides-sdb-tls + name: TLS/SSL Encryption + parent: guides-singlestore + weight: 45 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/tls/configure/examples/issuer.yaml b/docs/guides/singlestore/tls/configure/examples/issuer.yaml new file mode 100644 index 0000000000..8ffb97a846 --- /dev/null +++ b/docs/guides/singlestore/tls/configure/examples/issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: sdb-issuer + namespace: demo +spec: + ca: + secretName: sdb-ca \ No newline at end of file diff --git a/docs/guides/singlestore/tls/configure/examples/tls-cluster.yaml b/docs/guides/singlestore/tls/configure/examples/tls-cluster.yaml new file mode 100644 index 0000000000..49a24c692e --- /dev/null +++ b/docs/guides/singlestore/tls/configure/examples/tls-cluster.yaml @@ -0,0 +1,66 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-tls + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + deletionPolicy: WipeOut + tls: + issuerRef: + apiGroup: cert-manager.io + kind: Issuer + name: sdb-issuer + certificates: + - alias: server + subject: + organizations: + - kubedb:server + dnsNames: + - localhost + ipAddresses: + - "127.0.0.1" + diff --git a/docs/guides/singlestore/tls/configure/index.md b/docs/guides/singlestore/tls/configure/index.md new file mode 100644 index 0000000000..a1a555cd8c --- /dev/null +++ b/docs/guides/singlestore/tls/configure/index.md @@ -0,0 +1,334 @@ +--- +title: TLS/SSL (Transport Encryption) +menu: + docs_{{ .version }}: + identifier: guides-sdb-tls-configure + name: SingleStore TLS/SSL Configuration + parent: guides-sdb-tls + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Configure TLS/SSL in SingleStore + +`KubeDB` supports providing TLS/SSL encryption (via, `tls` mode) for `SingleStore`. This tutorial will show you how to use `KubeDB` to deploy a `SingleStore` database with TLS/SSL configuration. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install [`cert-manger`](https://cert-manager.io/docs/installation/) v1.0.0 or later to your cluster to manage your SSL/TLS certificates. + +- Install `KubeDB` in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/tls/configure/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/tls/configure/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +### Deploy SingleStore database with TLS/SSL configuration + +As pre-requisite, at first, we are going to create an Issuer/ClusterIssuer. This Issuer/ClusterIssuer is used to create certificates. Then we are going to deploy a SingleStore standalone and cluster that will be configured with these certificates by `KubeDB` operator. + +### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +### Create Issuer/ClusterIssuer + +Now, we are going to create an example `Issuer` that will be used throughout the duration of this tutorial. Alternatively, you can follow this [cert-manager tutorial](https://cert-manager.io/docs/configuration/ca/) to create your own `Issuer`. By following the below steps, we are going to create our desired issuer, + +- Start off by generating our ca-certificates using openssl, + +```bash +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memsql/O=kubedb" +Generating a RSA private key +...........................................................................+++++ +........................................................................................................+++++ +writing new private key to './ca.key' +``` + +- create a secret using the certificate files we have just generated, + +```bash +kubectl create secret tls sdb-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +secret/sdb-ca created +``` + +Now, we are going to create an `Issuer` using the `sdb-ca` secret that hols the ca-certificate we have just created. Below is the YAML of the `Issuer` cr that we are going to create, + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: sdb-issuer + namespace: demo +spec: + ca: + secretName: sdb-ca +``` + +Let’s create the `Issuer` cr we have shown above, + +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/tls/configure/examples/issuer.yaml +issuer.cert-manager.io/sdb-issuer created +``` + +### Deploy SingleStore Cluster with TLS/SSL configuration + +Here, our issuer `sdb-issuer` is ready to deploy a `SingleStore` cluster with TLS/SSL configuration. Below is the YAML for SingleStore Cluster that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sdb-tls + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "700m" + requests: + memory: "2Gi" + cpu: "700m" + storage: + storageClassName: "standard" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + deletionPolicy: WipeOut + tls: + issuerRef: + apiGroup: cert-manager.io + kind: Issuer + name: sdb-issuer + certificates: + - alias: server + subject: + organizations: + - kubedb:server + dnsNames: + - localhost + ipAddresses: + - "127.0.0.1" +``` + +Here, + +- `spec.tls.issuerRef` refers to the `sdb-issuer` issuer. + +- `spec.tls.certificates` gives you a lot of options to configure so that the certificate will be renewed and kept up to date. +You can found more details from [here](/docs/guides/singlestore/concepts/singlestore.md#spectls) + +Let’s create the `SingleStore` cr we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/tls/configure/examples/tls-cluster.yaml +singlestore.kubedb.com/sdb-tls created +``` + +**Wait for the database to be ready:** + +Now, wait for `SingleStore` going on `Running` state and also wait for `PetSet` and its pod to be created and going to `Running` state, + +```bash +$ kubectl get sdb,petset -n demo +NAME TYPE VERSION STATUS AGE +singlestore.kubedb.com/sdb-tls kubedb.com/v1alpha2 8.7.10 Ready 3m57s + +NAME AGE +petset.apps.k8s.appscode.com/sdb-tls-aggregator 3m53s +petset.apps.k8s.appscode.com/sdb-tls-leaf 3m50s +``` + +**Verify tls-secrets created successfully:** + +If everything goes well, you can see that our tls-secrets will be created which contains server, client, exporter certificate. Server tls-secret will be used for server configuration and client tls-secret will be used for a secure connection. + +All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name formed as _{singlestore-object-name}-{cert-alias}-cert_. + +Let's check the tls-secrets have created, + +```bash +$ kubectl get secret -n demo | grep sdb-tls +sdb-tls-client-cert kubernetes.io/tls 3 5m41s +sdb-tls-root-cred kubernetes.io/basic-auth 2 5m41s +sdb-tls-server-cert kubernetes.io/tls +``` + +**Verify SingleStore configured with TLS/SSL:** + +Now, we are going to connect to the database for verifying the `SingleStore` server has configured with TLS/SSL encryption. + +Let's exec into the pod to verify TLS/SSL configuration, + +```bash +$ kubectl exec -it -n demo sdb-tls-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) + +[memsql@sdb-tls-aggregator-0 /]$ ls etc/memsql/certs +ca.crt client.crt client.key server.crt server.key + +[memsql@sdb-tls-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 237 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> show variables like '%ssl%'; ++---------------------------------+------------------------------+ +| Variable_name | Value | ++---------------------------------+------------------------------+ +| default_user_require_ssl | OFF | +| exporter_ssl_ca | | +| exporter_ssl_capath | | +| exporter_ssl_cert | | +| exporter_ssl_key | | +| exporter_ssl_key_passphrase | [redacted] | +| have_openssl | ON | +| have_ssl | ON | +| jwks_ssl_ca_certificate | | +| node_replication_ssl_only | OFF | +| openssl_version | 805306480 | +| processlist_rpc_json_max_size | 2048 | +| ssl_ca | /etc/memsql/certs/ca.crt | +| ssl_capath | | +| ssl_cert | /etc/memsql/certs/server.crt | +| ssl_cipher | | +| ssl_fips_mode | OFF | +| ssl_key | /etc/memsql/certs/server.key | +| ssl_key_passphrase | [redacted] | +| ssl_last_reload_attempt_time | | +| ssl_last_successful_reload_time | | ++---------------------------------+------------------------------+ +21 rows in set (0.00 sec) +singlestore> exit +Bye + +``` + +The above output shows that the `SingleStore` server is configured to TLS/SSL. You can also see that the `.crt` and `.key` files are stored in `/etc/mysql/certs/` directory for client and server respectively. + +**Verify secure connection for SSL required user:** + +Now, you can create an SSL required user that will be used to connect to the database with a secure connection. + +Let's connect to the database server with a secure connection, + +```bash +$ kubectl exec -it -n demo sdb-tls-aggregator-0 -- bash +Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) +[memsql@sdb-tls-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 316 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> CREATE USER 'new_user'@'localhost' IDENTIFIED BY '1234' REQUIRE SSL; +Query OK, 0 rows affected (0.05 sec) + +singlestore> FLUSH PRIVILEGES; +Query OK, 0 rows affected (0.00 sec) + +singlestore> exit +Bye + +# accessing the database server newly created user with certificates +[memsql@sdb-tls-aggregator-0 /]$ memsql -unew_user -p1234 --ssl-ca=/etc/memsql/certs/ca.crt --ssl-cert=/etc/memsql/certs/server.crt --ssl-key=/etc/memsql/certs/server.key +singlestore-client: [Warning] Using a password on the command line interface can be insecure. +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 462 +Server version: 5.7.32 SingleStoreDB source distribution (compatible; MySQL Enterprise & MySQL Commercial) + +Copyright (c) 2000, 2022, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +singlestore> exit; +Bye + +``` + +From the above output, you can see that only using client certificate we can access the database securely, otherwise, it shows "Access denied". Our client certificate is stored in `/etc/memsql/certs/` directory. + +## Cleaning up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete sdb demo sdb-tls +singlestore.kubedb.com "sdb-tls" deleted +$ kubectl delete ns demo +namespace "demo" deleted +``` \ No newline at end of file diff --git a/docs/guides/singlestore/tls/overview/images/sdb-tls.svg b/docs/guides/singlestore/tls/overview/images/sdb-tls.svg new file mode 100644 index 0000000000..18c72067a9 --- /dev/null +++ b/docs/guides/singlestore/tls/overview/images/sdb-tls.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guides/singlestore/tls/overview/index.md b/docs/guides/singlestore/tls/overview/index.md new file mode 100644 index 0000000000..0da1189929 --- /dev/null +++ b/docs/guides/singlestore/tls/overview/index.md @@ -0,0 +1,69 @@ +--- +title: SingleStore TLS/SSL Encryption Overview +menu: + docs_{{ .version }}: + identifier: guides-sdb-tls-overview + name: Overview + parent: guides-sdb-tls + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore TLS/SSL Encryption + +**Prerequisite :** To configure TLS/SSL in `SingleStore`, `KubeDB` uses `cert-manager` to issue certificates. So first you have to make sure that the cluster has `cert-manager` installed. To install `cert-manager` in your cluster following steps [here](https://cert-manager.io/docs/installation/kubernetes/). + +To issue a certificate, the following cr of `cert-manager` is used: + +- `Issuer/ClusterIssuer`: Issuers and ClusterIssuers represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request. You can learn more details [here](https://cert-manager.io/docs/concepts/issuer/). + +- `Certificate`: `cert-manager` has the concept of Certificates that define the desired x509 certificate which will be renewed and kept up to date. You can learn more details [here](https://cert-manager.io/docs/concepts/certificate/). + +**SingleStore CRD Specification:** + +KubeDB uses the following cr fields to enable SSL/TLS encryption in `SingleStore`. + +- `spec:` + - `tls:` + - `issuerRef` + - `certificates` + +Read about the fields in details from [singlestore concept](/docs/guides/singlestore/concepts/singlestore.md#spectls), + +`KubeDB` uses the `issuer` or `clusterIssuer` referenced in the `tls.issuerRef` field, and the certificate specs provided in `tls.certificate` to generate certificate secrets using `Issuer/ClusterIssuers` specification. These certificates secrets including `ca.crt`, `tls.crt` and `tls.key` etc. are used to configure `SingleStore` server, studio, exporter etc. respectively. + +## How TLS/SSL configures in SingleStore + +The following figure shows how `KubeDB` enterprise is used to configure TLS/SSL in SingleStore. Open the image in a new tab to see the enlarged version. + +
+ Stash Backup Flow +
Fig: Deploy SingleStore with TLS/SSL
+
+ +Deploying SingleStore with TLS/SSL configuration process consists of the following steps: + +1. At first, a user creates an `Issuer/ClusterIssuer` cr. + +2. Then the user creates a `SingleStore` cr. + +3. `KubeDB` Provisioner operator watches for the `SingleStore` cr. + +4. When it finds one, it creates `Secret`, `Service`, etc. for the `SingleStore` database. + +5. `KubeDB` Ops Manager watches for `SingleStore`(5c), `Issuer/ClusterIssuer`(5b), `Secret` and `Service`(5a). + +6. When it finds all the resources(`SingleStore`, `Issuer/ClusterIssuer`, `Secret`, `Service`), it creates `Certificates` by using `tls.issuerRef` and `tls.certificates` field specification from `SingleStore` cr. + +7. `cert-manager` watches for certificates. + +8. When it finds one, it creates certificate secrets `tls-secrets`(server, client, secrets, etc.) that hold the actual self-signed certificate. + +9. `KubeDB` Provisioner operator watches for the Certificate secrets `tls-secrets`. + +10. When it finds all the tls-secret, it creates a `PetSet` so that SingleStore server is configured with TLS/SSL. + +In the next doc, we are going to show a step by step guide on how to configure a `SingleStore` database with TLS/SSL. diff --git a/docs/guides/singlestore/update-version/_index.md b/docs/guides/singlestore/update-version/_index.md new file mode 100644 index 0000000000..cfa345ebab --- /dev/null +++ b/docs/guides/singlestore/update-version/_index.md @@ -0,0 +1,10 @@ +--- +title: Updating +menu: + docs_{{ .version }}: + identifier: guides-sdb-updating + name: UpdateVersion + parent: guides-singlestore + weight: 42 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/singlestore/update-version/overview/images/sdb-version-update.svg b/docs/guides/singlestore/update-version/overview/images/sdb-version-update.svg new file mode 100644 index 0000000000..26d68cac6b --- /dev/null +++ b/docs/guides/singlestore/update-version/overview/images/sdb-version-update.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guides/singlestore/update-version/overview/index.md b/docs/guides/singlestore/update-version/overview/index.md new file mode 100644 index 0000000000..80c06027a0 --- /dev/null +++ b/docs/guides/singlestore/update-version/overview/index.md @@ -0,0 +1,54 @@ +--- +title: Updating SingleStore Overview +menu: + docs_{{ .version }}: + identifier: guides-sdb-updating-overview + name: Overview + parent: guides-sdb-updating + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# updating SingleStore version Overview + +This guide will give you an overview on how KubeDB Ops Manager update the version of `SingleStore` database. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +## How update version Process Works + +The following diagram shows how KubeDB Ops Manager used to update the version of `SingleStore`. Open the image in a new tab to see the enlarged version. + +
+  updating Process of SingleStore +
Fig: updating Process of SingleStore
+
+ +The updating process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource (CR). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CR. + +3. When the operator finds a `SingleStore` CR, it creates required number of `PetSets` and related necessary stuff like secrets, services, etc. + +4. Then, in order to update the version of the `SingleStore` database the user creates a `SingleStoreOpsRequest` CR with the desired version. + +5. `KubeDB` Ops-manager operator watches the `SingleStoreOpsRequest` CR. + +6. When it finds a `SingleStoreOpsRequest` CR, it halts the `SingleStore` object which is referred from the `SingleStoreOpsRequest`. So, the `KubeDB` Provisioner operator doesn't perform any operations on the `SingleStore` object during the updating process. + +7. By looking at the target version from `SingleStoreOpsRequest` CR, `KubeDB` Ops-manager operator updates the images of all the `PetSets`. After each image update, the operator performs some checks such as if the oplog is synced and database size is almost same or not. + +8. After successfully updating the `PetSets` and their `Pods` images, the `KubeDB` Ops-manager operator updates the image of the `SingleStore` object to reflect the updated state of the database. + +9. After successfully updating of `SingleStore` object, the `KubeDB` Ops-manager operator resumes the `SingleStore` object so that the `KubeDB` Provisioner operator can resume its usual operations. + +In the next doc, we are going to show a step by step guide on updating of a SingleStore database using update operation. \ No newline at end of file diff --git a/docs/guides/singlestore/update-version/sdb update-version opsrequest/examples/sample-sdb.yaml b/docs/guides/singlestore/update-version/sdb update-version opsrequest/examples/sample-sdb.yaml new file mode 100644 index 0000000000..5efd9bf8dc --- /dev/null +++ b/docs/guides/singlestore/update-version/sdb update-version opsrequest/examples/sample-sdb.yaml @@ -0,0 +1,52 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.5.30" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/singlestore/update-version/sdb update-version opsrequest/examples/sdbops-update.yaml b/docs/guides/singlestore/update-version/sdb update-version opsrequest/examples/sdbops-update.yaml new file mode 100644 index 0000000000..0f4ab34f3a --- /dev/null +++ b/docs/guides/singlestore/update-version/sdb update-version opsrequest/examples/sdbops-update.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-update-patch + namespace: demo +spec: + type: UpdateVersion + databaseRef: + name: sample-sdb + updateVersion: + targetVersion: "8.7.10" \ No newline at end of file diff --git a/docs/guides/singlestore/update-version/sdb update-version opsrequest/index.md b/docs/guides/singlestore/update-version/sdb update-version opsrequest/index.md new file mode 100644 index 0000000000..4593512230 --- /dev/null +++ b/docs/guides/singlestore/update-version/sdb update-version opsrequest/index.md @@ -0,0 +1,207 @@ +--- +title: Updating SingleStore Cluster +menu: + docs_{{ .version }}: + identifier: guides-sdb-updating-cluster + name: Update Version OpsRequest + parent: guides-sdb-updating + weight: 30 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# update version of SingleStore Cluster + +This guide will show you how to use `KubeDB` Ops-manager operator to update the version of `SingleStore` Cluster. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the `kubectl` command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install `KubeDB` Community and Ops-manager operator in your cluster following the steps [here](/docs/setup/README.md). + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [Cluster](/docs/guides/singlestore/clustering/overview/) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + - [Updating Overview](/docs/guides/singlestore/update-version/overview/) + +To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +## Prepare SingleStore Cluster + +### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +Now, we are going to deploy a `SingleStore` cluster database with version `8.5.30`. + +### Deploy SingleStore cluster + +In this section, we are going to deploy a SingleStore Cluster. Then, in the next section we will update the version of the database using `SingleStoreOpsRequest` CRD. Below is the YAML of the `SingleStore` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.5.30" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + +``` + +Let's create the `SingleStore` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/update-version/cluster/examples/sample-sdb.yaml +singlestore.kubedb.com/sample-sdb created +``` + +Now, wait until `sample-sdb` created has status `Ready`. i.e, + +```bash +$ kubectl get sdb -n demo +NAME TYPE VERSION STATUS AGE +sample-sdb kubedb.com/v1alpha2 8.5.30 Ready 4m37s +``` + +We are now ready to apply the `SingleStoreOpsRequest` CR to update this database. + +### update SingleStore Version + +Here, we are going to update `SingleStore` cluster from `8.5.30` to `8.7.10`. + +#### Create SingleStoreOpsRequest: + +In order to update the database cluster, we have to create a `SingleStoreOpsRequest` CR with your desired version that is supported by `KubeDB`. Below is the YAML of the `SingleStoreOpsRequest` CR that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-update-patch + namespace: demo +spec: + type: UpdateVersion + databaseRef: + name: sample-sdb + updateVersion: + targetVersion: "8.7.10" +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing operation on `sample-sdb` SingleStore database. +- `spec.type` specifies that we are going to perform `UpdateVersion` on our database. +- `spec.updateVersion.targetVersion` specifies the expected version of the database `8.7.10`. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/update-version/cluster/examples/sdbops-update.yaml +singlestoreopsrequest.ops.kubedb.com/sdb-update-patch created +``` + +#### Verify SingleStore version updated successfully + +If everything goes well, `KubeDB` Ops-manager operator will update the image of `SingleStore` object and related `PetSets` and `Pods`. + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, + +```bash +$ kubectl get sdbops -n demo +NAME TYPE STATUS AGE +sdb-update-patch UpdateVersion Successful 3m46s +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. + +Now, we are going to verify whether the `SingleStore` and the related `PetSets` and their `Pods` have the new version image. Let's check, + +```bash +$ kubectl get sdb -n demo sample-sdb -o=jsonpath='{.spec.version}{"\n"}' +8.7.10 + +$ kubectl get petset -n demo sample-sdb-aggregator -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +ghcr.io/appscode-images/singlestore-node:alma-8.7.10-95e2357384 + +$ kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +ghcr.io/appscode-images/singlestore-node:alma-8.7.10-95e2357384 + +$ kubectl get pods -n demo sample-sdb-aggregator-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +ghcr.io/appscode-images/singlestore-node:alma-8.7.10-95e2357384 + +$ kubectl get pods -n demo sample-sdb-leaf-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +ghcr.io/appscode-images/singlestore-node:alma-8.7.10-95e2357384 +``` + +You can see from above, our `SingleStore` cluster database has been updated with the new version. So, the update process is successfully completed. + +## Cleaning Up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete sdb -n demo sample-sdb +$ kubectl delete singlestoreopsrequest -n demo sdb-update-patch +``` \ No newline at end of file diff --git a/docs/guides/singlestore/volume-expansion/_index.md b/docs/guides/singlestore/volume-expansion/_index.md new file mode 100644 index 0000000000..a171ea223c --- /dev/null +++ b/docs/guides/singlestore/volume-expansion/_index.md @@ -0,0 +1,10 @@ +--- +title: Volume Expansion +menu: + docs_{{ .version }}: + identifier: guides-sdb-volume-expansion + name: Volume Expansion + parent: guides-singlestore + weight: 44 +menu_name: docs_{{ .version }} +--- \ No newline at end of file diff --git a/docs/guides/singlestore/volume-expansion/overview/images/volume-expansion.svg b/docs/guides/singlestore/volume-expansion/overview/images/volume-expansion.svg new file mode 100644 index 0000000000..553336d631 --- /dev/null +++ b/docs/guides/singlestore/volume-expansion/overview/images/volume-expansion.svg @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guides/singlestore/volume-expansion/overview/index.md b/docs/guides/singlestore/volume-expansion/overview/index.md new file mode 100644 index 0000000000..56abd1e431 --- /dev/null +++ b/docs/guides/singlestore/volume-expansion/overview/index.md @@ -0,0 +1,56 @@ +--- +title: SingleStore Volume Expansion Overview +menu: + docs_{{ .version }}: + identifier: guides-sdb-volume-expansion-overview + name: Overview + parent: guides-sdb-volume-expansion + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore Volume Expansion + +This guide will give an overview on how KubeDB Ops Manager expand the volume of `SingleStore`. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + +## How Volume Expansion Process Works + +The following diagram shows how KubeDB Ops Manager expand the volumes of `SingleStore` database components. Open the image in a new tab to see the enlarged version. + +
+  Volume Expansion process of SingleStore +
Fig: Volume Expansion process of SingleStore
+
+ +The Volume Expansion process consists of the following steps: + +1. At first, a user creates a `SingleStore` Custom Resource (CR). + +2. `KubeDB` Provisioner operator watches the `SingleStore` CR. + +3. When the operator finds a `SingleStore` CR, it creates required `PetSet` and related necessary stuff like secrets, services, etc. + +4. The petSet creates Persistent Volumes according to the Volume Claim Template provided in the petset configuration. This Persistent Volume will be expanded by the `KubeDB` Ops-manager operator. + +5. Then, in order to expand the volume of the `SingleStore` database the user creates a `SingleStoreOpsRequest` CR with desired information. + +6. `KubeDB` Ops-manager operator watches the `SingleStoreOpsRequest` CR. + +7. When it finds a `SingleStoreOpsRequest` CR, it pauses the `SingleStore` object which is referred from the `SingleStoreOpsRequest`. So, the `KubeDB` Provisioner operator doesn't perform any operations on the `SingleStore` object during the volume expansion process. + +8. Then the `KubeDB` Ops-manager operator will expand the persistent volume to reach the expected size defined in the `SingleStoreOpsRequest` CR. + +9. After the successfully expansion of the volume of the related PetSet Pods, the `KubeDB` Ops-manager operator updates the new volume size in the `SingleStore` object to reflect the updated state. + +10. After the successful Volume Expansion of the `SingleStore`, the `KubeDB` Ops-manager operator resumes the `SingleStore` object so that the `KubeDB` Provisioner operator resumes its usual operations. + +In the next docs, we are going to show a step by step guide on Volume Expansion of various SingleStore database using `SingleStoreOpsRequest` CRD. diff --git a/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/example/sample-sdb.yaml b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/example/sample-sdb.yaml new file mode 100644 index 0000000000..df3fdd1cde --- /dev/null +++ b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/example/sample-sdb.yaml @@ -0,0 +1,53 @@ +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut + diff --git a/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/example/sdb-offline-volume-expansion.yaml b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/example/sdb-offline-volume-expansion.yaml new file mode 100644 index 0000000000..39b1598a8d --- /dev/null +++ b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/example/sdb-offline-volume-expansion.yaml @@ -0,0 +1,13 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-offline-vol-expansion + namespace: demo +spec: + type: VolumeExpansion + databaseRef: + name: sample-sdb + volumeExpansion: + mode: "Offline" + aggregator: 2Gi + leaf: 11Gi \ No newline at end of file diff --git a/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/index.md b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/index.md new file mode 100644 index 0000000000..a0edd23f02 --- /dev/null +++ b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/index.md @@ -0,0 +1,480 @@ +--- +title: SingleStore Volume Expansion +menu: + docs_{{ .version }}: + identifier: guides-sdb-volume-expansion-volume-expansion + name: SingleStore Volume Expansion + parent: guides-sdb-volume-expansion + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# SingleStore Volume Expansion + +This guide will show you how to use `KubeDB` Ops-manager operator to expand the volume of a SingleStore. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the `kubectl` command-line tool must be configured to communicate with your cluster. + +- You must have a `StorageClass` that supports volume expansion. + +- Install `KubeDB` Provisioner and Ops-manager operator in your cluster following the steps [here](/docs/setup/README.md). + +- You should be familiar with the following `KubeDB` concepts: + - [SingleStore](/docs/guides/singlestore/concepts/singlestore.md) + - [SingleStoreOpsRequest](/docs/guides/singlestore/concepts/opsrequest.md) + - [Volume Expansion Overview](/docs/guides/singlestore/volume-expansion/overview) + +To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. + +```bash +$ kubectl create ns demo +namespace/demo created +``` + +## Expand Volume of SingleStore + +Here, we are going to deploy a `SingleStore` cluster using a supported version by `KubeDB` operator. Then we are going to apply `SingleStoreOpsRequest` to expand its volume. The process of expanding SingleStore `standalone` is same as SingleStore cluster. + +### Create SingleStore License Secret + +We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. + +```bash +$ kubectl create secret generic -n demo license-secret \ + --from-literal=username=license \ + --from-literal=password='your-license-set-here' +secret/license-secret created +``` + +### Prepare SingleStore Database + +At first verify that your cluster has a storage class, that supports volume expansion. Let's check, + +```bash +$ kubectl get storageClass +NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE +local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 6d2h +longhorn (default) driver.longhorn.io Delete Immediate true 3d21h +longhorn-static driver.longhorn.io Delete Immediate true 42m +``` + +Here, we will use `longhorn` storageClass for this tuitorial. + +Now, we are going to deploy a `SingleStore` database of 3 replicas with version `8.7.10`. + +### Deploy SingleStore + +In this section, we are going to deploy a SingleStore Cluster with 1GB volume for `aggregator` nodes and 10GB volume for `leaf` nodes. Then, in the next section we will expand its volume to 2GB using `SingleStoreOpsRequest` CRD. Below is the YAML of the `SingleStore` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Singlestore +metadata: + name: sample-sdb + namespace: demo +spec: + version: "8.7.10" + topology: + aggregator: + replicas: 1 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + leaf: + replicas: 2 + podTemplate: + spec: + containers: + - name: singlestore + resources: + limits: + memory: "2Gi" + cpu: "600m" + requests: + memory: "2Gi" + cpu: "600m" + storage: + storageClassName: "longhorn" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + licenseSecret: + name: license-secret + storageType: Durable + deletionPolicy: WipeOut +``` + +Let's create the `SingleStore` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/volume-expansion/volume-expansion/example/sample-sdb.yaml +singlestore.kubedb.com/sample-sdb created +``` + +Now, wait until `sample-sdb` has status `Ready`. i.e, + +```bash +$ kubectl get sdb -n demo +NAME TYPE VERSION STATUS AGE +sample-sdb kubedb.com/v1alpha2 8.7.10 Ready 4m25s + +``` + +Let's check volume size from petset, and from the persistent volume, + +```bash +$ kubectl get petset -n demo sample-sdb-aggregator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +"1Gi" + +$ kubectl get petset -n demo sample-sdb-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +"10Gi" + +$ kubectl get pv -n demo +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE +pvc-41cb892c-99fc-4211-a8c2-4e6f8a16c661 10Gi RWO Delete Bound demo/data-sample-sdb-leaf-0 longhorn 90s +pvc-6e241724-6577-408e-b8de-9569d7d785c4 10Gi RWO Delete Bound demo/data-sample-sdb-leaf-1 longhorn 75s +pvc-95ecc525-540b-4496-bf14-bfac901d73c4 1Gi RWO Delete Bound demo/data-sample-sdb-aggregator-0 longhorn 94s + + +``` + +You can see the `aggregator` petset has 1GB storage, and the capacity of all the `aggregator` persistent volumes are also 1GB. + +You can see the `leaf` petset has 10GB storage, and the capacity of all the `leaf` persistent volumes are also 10GB. + +We are now ready to apply the `SingleStoreOpsRequest` CR to expand the volume of this database. + +### Volume Expansion + +Here, we are going to expand the volume of the SingleStore cluster. + +#### Create SingleStoreOpsRequest + +In order to expand the volume of the database, we have to create a `SingleStoreOpsRequest` CR with our desired volume size. Below is the YAML of the `SingleStoreOpsRequest` CR that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: SinglestoreOpsRequest +metadata: + name: sdb-offline-vol-expansion + namespace: demo +spec: + type: VolumeExpansion + databaseRef: + name: sample-sdb + volumeExpansion: + mode: "Offline" + aggregator: 2Gi + leaf: 11Gi +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing volume expansion operation on `sample-sdb` database. +- `spec.type` specifies that we are performing `VolumeExpansion` on our database. +- `spec.volumeExpansion.aggregator` and `spec.volumeExpansion.leaf` specifies the desired volume size for `aggregator` and `leaf` nodes. +- `spec.volumeExpansion.mode` specifies the desired volume expansion mode (`Online` or `Offline`). Storageclass `longhorn` supports `Offline` volume expansion. + +> **Note:** If the Storageclass you are using doesn't support `Online` Volume Expansion, Try offline volume expansion by using `spec.volumeExpansion.mode:"Offline"`. + +Let's create the `SingleStoreOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/volume-expansion/volume-expansion/example/sdb-offline-volume-expansion.yaml +singlestoreopsrequest.ops.kubedb.com/sdb-offline-vol-expansion created +``` + +#### Verify SingleStore volume expanded successfully + +If everything goes well, `KubeDB` Ops-manager operator will update the volume size of `SingleStore` object and related `PetSets` and `Persistent Volumes`. + +Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, + +```bash +$ kubectl get singlestoreopsrequest -n demo +NAME TYPE STATUS AGE +sdb-offline-vol-expansion VolumeExpansion Successful 13m +``` + +We can see from the above output that the `SingleStoreOpsRequest` has succeeded. If we describe the `SingleStoreOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. + +```bash +$ kubectl describe sdbops -n demo sdb-offline-vol-expansion +Name: sdb-offline-vol-expansion +Namespace: demo +Labels: +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: SinglestoreOpsRequest +Metadata: + Creation Timestamp: 2024-10-15T08:49:11Z + Generation: 1 + Resource Version: 12476 + UID: a0e2f1c3-a6b7-4993-a012-2823c3a2675b +Spec: + Apply: IfReady + Database Ref: + Name: sample-sdb + Type: VolumeExpansion + Volume Expansion: + Aggregator: 2Gi + Leaf: 11Gi + Mode: Offline +Status: + Conditions: + Last Transition Time: 2024-10-15T08:49:11Z + Message: Singlestore ops-request has started to expand volume of singlestore nodes. + Observed Generation: 1 + Reason: VolumeExpansion + Status: True + Type: VolumeExpansion + Last Transition Time: 2024-10-15T08:49:17Z + Message: Successfully paused database + Observed Generation: 1 + Reason: DatabasePauseSucceeded + Status: True + Type: DatabasePauseSucceeded + Last Transition Time: 2024-10-15T08:49:42Z + Message: successfully deleted the petSets with orphan propagation policy + Observed Generation: 1 + Reason: OrphanPetSetPods + Status: True + Type: OrphanPetSetPods + Last Transition Time: 2024-10-15T08:49:22Z + Message: get pet set; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetPetSet + Last Transition Time: 2024-10-15T08:49:22Z + Message: delete pet set; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: DeletePetSet + Last Transition Time: 2024-10-15T08:51:07Z + Message: successfully updated Aggregator node PVC sizes + Observed Generation: 1 + Reason: UpdateAggregatorNodePVCs + Status: True + Type: UpdateAggregatorNodePVCs + Last Transition Time: 2024-10-15T08:53:32Z + Message: get pod; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetPod + Last Transition Time: 2024-10-15T08:49:47Z + Message: is ops req patch; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: IsOpsReqPatch + Last Transition Time: 2024-10-15T08:49:47Z + Message: delete pod; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: DeletePod + Last Transition Time: 2024-10-15T08:50:22Z + Message: get pvc; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetPvc + Last Transition Time: 2024-10-15T08:50:22Z + Message: is pvc patch; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: IsPvcPatch + Last Transition Time: 2024-10-15T08:53:52Z + Message: compare storage; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CompareStorage + Last Transition Time: 2024-10-15T08:50:42Z + Message: create pod; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CreatePod + Last Transition Time: 2024-10-15T08:50:47Z + Message: is running single store; ConditionStatus:False + Observed Generation: 1 + Status: False + Type: IsRunningSingleStore + Last Transition Time: 2024-10-15T08:54:32Z + Message: successfully updated Leaf node PVC sizes + Observed Generation: 1 + Reason: UpdateLeafNodePVCs + Status: True + Type: UpdateLeafNodePVCs + Last Transition Time: 2024-10-15T08:54:43Z + Message: successfully reconciled the Singlestore resources + Observed Generation: 1 + Reason: UpdatePetSets + Status: True + Type: UpdatePetSets + Last Transition Time: 2024-10-15T08:54:48Z + Message: PetSet is recreated + Observed Generation: 1 + Reason: ReadyPetSets + Status: True + Type: ReadyPetSets + Last Transition Time: 2024-10-15T08:54:48Z + Message: Successfully completed volumeExpansion for Singlestore + Observed Generation: 1 + Reason: Successful + Status: True + Type: Successful + Observed Generation: 1 + Phase: Successful +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Starting 14m KubeDB Ops-manager Operator Start processing for SinglestoreOpsRequest: demo/sdb-offline-vol-expansion + Normal Starting 14m KubeDB Ops-manager Operator Pausing Singlestore database: demo/sample-sdb + Normal Successful 14m KubeDB Ops-manager Operator Successfully paused Singlestore database: demo/sample-sdb for SinglestoreOpsRequest: sdb-offline-vol-expansion + Warning get pet set; ConditionStatus:True 14m KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Warning delete pet set; ConditionStatus:True 14m KubeDB Ops-manager Operator delete pet set; ConditionStatus:True + Warning get pet set; ConditionStatus:True 14m KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Warning get pet set; ConditionStatus:True 14m KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Warning delete pet set; ConditionStatus:True 14m KubeDB Ops-manager Operator delete pet set; ConditionStatus:True + Warning get pet set; ConditionStatus:True 14m KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Normal OrphanPetSetPods 13m KubeDB Ops-manager Operator successfully deleted the petSets with orphan propagation policy + Warning get pod; ConditionStatus:True 13m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning is ops req patch; ConditionStatus:True 13m KubeDB Ops-manager Operator is ops req patch; ConditionStatus:True + Warning delete pod; ConditionStatus:True 13m KubeDB Ops-manager Operator delete pod; ConditionStatus:True + Warning get pod; ConditionStatus:False 13m KubeDB Ops-manager Operator get pod; ConditionStatus:False + Warning get pod; ConditionStatus:True 13m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 13m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning is pvc patch; ConditionStatus:True 13m KubeDB Ops-manager Operator is pvc patch; ConditionStatus:True + Warning compare storage; ConditionStatus:False 13m KubeDB Ops-manager Operator compare storage; ConditionStatus:False + Warning get pod; ConditionStatus:True 13m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 13m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 13m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 13m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 13m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 13m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 12m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 12m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning compare storage; ConditionStatus:True 12m KubeDB Ops-manager Operator compare storage; ConditionStatus:True + Warning create pod; ConditionStatus:True 12m KubeDB Ops-manager Operator create pod; ConditionStatus:True + Warning is ops req patch; ConditionStatus:True 12m KubeDB Ops-manager Operator is ops req patch; ConditionStatus:True + Warning get pod; ConditionStatus:True 12m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning is running single store; ConditionStatus:False 12m KubeDB Ops-manager Operator is running single store; ConditionStatus:False + Warning get pod; ConditionStatus:True 12m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 12m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 12m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Normal UpdateAggregatorNodePVCs 12m KubeDB Ops-manager Operator successfully updated Aggregator node PVC sizes + Warning get pod; ConditionStatus:True 12m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning is ops req patch; ConditionStatus:True 12m KubeDB Ops-manager Operator is ops req patch; ConditionStatus:True + Warning delete pod; ConditionStatus:True 12m KubeDB Ops-manager Operator delete pod; ConditionStatus:True + Warning get pod; ConditionStatus:False 12m KubeDB Ops-manager Operator get pod; ConditionStatus:False + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning is pvc patch; ConditionStatus:True 11m KubeDB Ops-manager Operator is pvc patch; ConditionStatus:True + Warning compare storage; ConditionStatus:False 11m KubeDB Ops-manager Operator compare storage; ConditionStatus:False + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 11m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning compare storage; ConditionStatus:True 11m KubeDB Ops-manager Operator compare storage; ConditionStatus:True + Warning create pod; ConditionStatus:True 11m KubeDB Ops-manager Operator create pod; ConditionStatus:True + Warning is ops req patch; ConditionStatus:True 11m KubeDB Ops-manager Operator is ops req patch; ConditionStatus:True + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning is running single store; ConditionStatus:False 11m KubeDB Ops-manager Operator is running single store; ConditionStatus:False + Warning get pod; ConditionStatus:True 11m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 10m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 10m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 10m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 10m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning is ops req patch; ConditionStatus:True 10m KubeDB Ops-manager Operator is ops req patch; ConditionStatus:True + Warning delete pod; ConditionStatus:True 10m KubeDB Ops-manager Operator delete pod; ConditionStatus:True + Warning get pod; ConditionStatus:False 10m KubeDB Ops-manager Operator get pod; ConditionStatus:False + Warning get pod; ConditionStatus:True 10m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 10m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning is pvc patch; ConditionStatus:True 10m KubeDB Ops-manager Operator is pvc patch; ConditionStatus:True + Warning compare storage; ConditionStatus:False 10m KubeDB Ops-manager Operator compare storage; ConditionStatus:False + Warning get pod; ConditionStatus:True 10m KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 10m KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m55s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 9m55s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m50s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 9m50s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m45s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pvc; ConditionStatus:True 9m45s KubeDB Ops-manager Operator get pvc; ConditionStatus:True + Warning compare storage; ConditionStatus:True 9m45s KubeDB Ops-manager Operator compare storage; ConditionStatus:True + Warning create pod; ConditionStatus:True 9m45s KubeDB Ops-manager Operator create pod; ConditionStatus:True + Warning is ops req patch; ConditionStatus:True 9m45s KubeDB Ops-manager Operator is ops req patch; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m40s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m35s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m30s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m25s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m20s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m15s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Warning get pod; ConditionStatus:True 9m10s KubeDB Ops-manager Operator get pod; ConditionStatus:True + Normal UpdateLeafNodePVCs 9m5s KubeDB Ops-manager Operator successfully updated Leaf node PVC sizes + Normal UpdatePetSets 8m54s KubeDB Ops-manager Operator successfully reconciled the Singlestore resources + Warning get pet set; ConditionStatus:True 8m49s KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Warning get pet set; ConditionStatus:True 8m49s KubeDB Ops-manager Operator get pet set; ConditionStatus:True + Normal ReadyPetSets 8m49s KubeDB Ops-manager Operator PetSet is recreated + Normal Starting 8m49s KubeDB Ops-manager Operator Resuming Singlestore database: demo/sample-sdb + Normal Successful 8m49s KubeDB Ops-manager Operator Successfully resumed Singlestore database: demo/sample-sdb for SinglestoreOpsRequest: sdb-offline-vol-expansion + + +``` + +Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, + +```bash +$ kubectl get petset -n demo sample-sdb-aggregator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +"2Gi" +$ kubectl get petset -n demo sample-sdb-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +"11Gi" + + +$ kubectl get pv -n demo +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE +pvc-0a4b35e6-988e-4088-ae41-852ad82c5800 2Gi RWO Delete Bound demo/data-sample-sdb-aggregator-0 longhorn 22m +pvc-f6df5743-2bb1-4705-a2f7-be6cf7cdd7f1 11Gi RWO Delete Bound demo/data-sample-sdb-leaf-0 longhorn 22m +pvc-f8fee59d-74dc-46ac-9973-ff1701a6837b 11Gi RWO Delete Bound demo/data-sample-sdb-leaf-1 longhorn 19m +``` + +The above output verifies that we have successfully expanded the volume of the SingleStore database. + +## Cleaning Up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl delete sdb -n demo sample-sdb +$ kubectl delete singlestoreopsrequest -n demo sdb-offline-volume-expansion +``` diff --git a/docs/images/singlestore/compute-process.svg b/docs/images/singlestore/compute-process.svg new file mode 100644 index 0000000000..a0f7d8300a --- /dev/null +++ b/docs/images/singlestore/compute-process.svg @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/singlestore/storage-autoscaling.svg b/docs/images/singlestore/storage-autoscaling.svg new file mode 100644 index 0000000000..f1bfe7205a --- /dev/null +++ b/docs/images/singlestore/storage-autoscaling.svg @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +