From fe66d984441e04fd9e274518e392f601acca680a Mon Sep 17 00:00:00 2001 From: Nikita Vaniasin Date: Thu, 19 Oct 2023 15:47:42 +0200 Subject: [PATCH] (Documentation) Move documentation from ArangoDB site into this repo (#1450) - remove duplicated docs - update old docs with new info - rework docs index page - file names not changed to make sure redirects from old site will work as expected Co-authored-by: jwierzbo --- CHANGELOG.md | 1 + README.md | 4 +- docs/README.md | 60 +- docs/authentication.md | 18 + docs/backup-resource.md | 554 ++++++++++++ docs/backuppolicy-resource.md | 185 ++++ docs/configuration-and-secrets.md | 36 + docs/{design/dashboard.md => dashboards.md} | 2 +- ...ployment-replication-resource-reference.md | 334 +++++++ docs/deployment-resource-reference.md | 840 ++++++++++++++++++ docs/design/README.md | 3 +- docs/design/scaling.md | 21 - docs/draining-nodes.md | 453 ++++++++++ docs/driver-configuration.md | 132 +++ docs/helm.md | 156 ++++ docs/how-to/README.md | 2 +- docs/how-to/set_license.md | 17 + docs/images/HealthyCluster.png | Bin 0 -> 116745 bytes docs/images/ShardsInSync.png | Bin 0 -> 85868 bytes docs/metrics.md | 152 ++++ docs/scaling.md | 42 + docs/services-and-load-balancer.md | 125 +++ docs/storage-resource.md | 63 ++ docs/storage.md | 144 +++ docs/tls.md | 54 ++ docs/troubleshooting.md | 115 +++ docs/upgrading.md | 31 + docs/using-the-operator.md | 298 +++++++ 28 files changed, 3808 insertions(+), 34 deletions(-) create mode 100644 docs/authentication.md create mode 100644 docs/backup-resource.md create mode 100644 docs/backuppolicy-resource.md create mode 100644 docs/configuration-and-secrets.md rename docs/{design/dashboard.md => dashboards.md} (70%) create mode 100644 docs/deployment-replication-resource-reference.md create mode 100644 docs/deployment-resource-reference.md delete mode 100644 docs/design/scaling.md create mode 100644 docs/draining-nodes.md create mode 100644 docs/driver-configuration.md create mode 100644 docs/helm.md create mode 100644 docs/how-to/set_license.md create mode 100644 docs/images/HealthyCluster.png create mode 100644 docs/images/ShardsInSync.png create mode 100644 docs/metrics.md create mode 100644 docs/scaling.md create mode 100644 docs/services-and-load-balancer.md create mode 100644 docs/storage-resource.md create mode 100644 docs/storage.md create mode 100644 docs/tls.md create mode 100644 docs/troubleshooting.md create mode 100644 docs/upgrading.md create mode 100644 docs/using-the-operator.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 4468d104f..c801d6b68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - (Improvement) Print assigned node name to log and condition message when pod is scheduled - (Maintenance) Remove obsolete docs, restructure for better UX, generate index files - (Feature) Add `spec.upgrade.debugLog` option to configure upgrade container logging +- (Documentation) Move documentation from ArangoDB into this repo, update and improve structure ## [1.2.34](https://github.com/arangodb/kube-arangodb/tree/1.2.34) (2023-10-16) - (Bugfix) Fix make manifests-crd-file command diff --git a/README.md b/README.md index 3ad0657a1..fc9497221 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ ArangoDB Kubernetes Operator helps to run ArangoDB deployments on Kubernetes clusters. To get started, follow the Installation instructions below and/or -read the [tutorial](https://www.arangodb.com/docs/stable/deployment-kubernetes-usage.html). +read the [tutorial](docs/using-the-operator.md). ## State The ArangoDB Kubernetes Operator is Production ready. -[Documentation](https://www.arangodb.com/docs/stable/deployment-kubernetes.html) +[Documentation](docs/README.md) ### Limits diff --git a/docs/README.md b/docs/README.md index 1b6e9a982..61bdd1e9a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,11 +1,57 @@ # ArangoDB Kubernetes Operator -- [Tutorial](https://www.arangodb.com/docs/stable/tutorials-kubernetes.html) -- [Documentation](https://www.arangodb.com/docs/stable/deployment-kubernetes.html) -- [Architecture](./design/README.md) -- [Features description and usage](./features/README.md) -- [Custom Resources API Reference](./api/README.md) -- [Operator Metrics & Alerts](./generated/metrics/README.md) -- [Operator Actions](./generated/actions.md) +- [Intro](#intro) +- [Using the ArangoDB Kubernetes Operator](using-the-operator.md) +- [Architecture overview](design/README.md) +- [Features description and usage](features/README.md) +- [Custom Resources API Reference](api/README.md) +- [Operator Metrics & Alerts](generated/metrics/README.md) +- [Operator Actions](generated/actions.md) +- [Authentication](authentication.md) +- Custom resources overview: + - [ArangoDeployment](deployment-resource-reference.md) + - [ArangoDeploymentReplication](deployment-replication-resource-reference.md) + - [ArangoLocalStorage](storage-resource.md) + - [Backup](backup-resource.md) + - [BackupPolicy](backuppolicy-resource.md) +- [Configuration and secrets](configuration-and-secrets.md) +- [Configuring your driver for ArangoDB access](driver-configuration.md) +- [Using Helm](helm.md) +- [Collecting metrics](metrics.md) +- [Services & Load balancer](services-and-load-balancer.md) +- [Storage configuration](storage.md) +- [Secure connections (TLS)](tls.md) +- [Upgrading ArangoDB version](upgrading.md) +- [Scaling your ArangoDB deployment](scaling.md) +- [Draining the Kubernetes nodes](draining-nodes.md) - Known issues (TBD) +- [Troubleshooting](troubleshooting.md) - [How-to ...](how-to/README.md) + +## Intro + +The ArangoDB Kubernetes Operator (`kube-arangodb`) is a set of operators +that you deploy in your Kubernetes cluster to: + +- Manage deployments of the ArangoDB database +- Manage backups +- Provide `PersistentVolumes` on local storage of your nodes for optimal storage performance. +- Configure ArangoDB Datacenter-to-Datacenter Replication + +Each of these uses involves a different custom resource. + +- Use an [`ArangoDeployment` resource](deployment-resource-reference.md) to + create an ArangoDB database deployment. +- Use an [`ArangoBackup`](backup-resource.md) and `ArangoBackupPolicy` resources to + create ArangoDB backups. +- Use an [`ArangoLocalStorage` resource](storage-resource.md) to + provide local `PersistentVolumes` for optimal I/O performance. +- Use an [`ArangoDeploymentReplication` resource](deployment-replication-resource-reference.md) to + configure ArangoDB Datacenter-to-Datacenter Replication. + +Continue with [Using the ArangoDB Kubernetes Operator](using-the-operator.md) +to learn how to install the ArangoDB Kubernetes operator and create +your first deployment. + +For more information about the production readiness state, please refer to the +[ArangoDB Kubernetes Operator repository](https://github.com/arangodb/kube-arangodb#production-readiness-state). diff --git a/docs/authentication.md b/docs/authentication.md new file mode 100644 index 000000000..2fed638c0 --- /dev/null +++ b/docs/authentication.md @@ -0,0 +1,18 @@ +# Authentication + +The ArangoDB Kubernetes Operator will by default create ArangoDB deployments +that require authentication to access the database. + +It uses a single JWT secret (stored in a Kubernetes secret) +to provide *super-user* access between all servers of the deployment +as well as access from the ArangoDB Operator to the deployment. + +To disable authentication, set `spec.auth.jwtSecretName` to `None`. + +Initially the deployment is accessible through the web user-interface and +APIs, using the user `root` with an empty password. +Make sure to change this password immediately after starting the deployment! + +## See also + +- [Secure connections (TLS)](tls.md) diff --git a/docs/backup-resource.md b/docs/backup-resource.md new file mode 100644 index 000000000..2c607aa33 --- /dev/null +++ b/docs/backup-resource.md @@ -0,0 +1,554 @@ +# ArangoBackup Custom Resource + +The ArangoBackup Operator creates and maintains ArangoBackups +in a Kubernetes cluster, given a Backup specification. +This deployment specification is a `CustomResource` following +a `CustomResourceDefinition` created by the operator. + +## Examples: + +### Create simple Backup + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackup" +metadata: + name: "example-arangodb-backup" + namespace: "arangodb" +spec: + deployment: + name: "my-deployment" +``` + +Action: + +Create Backup on ArangoDeployment named `my-deployment` + +### Create and upload Backup + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackup" +metadata: + name: "example-arangodb-backup" + namespace: "arangodb" +spec: + deployment: + name: "my-deployment" + upload: + repositoryURL: "S3://test/kube-test" + credentialsSecretName: "my-s3-rclone-credentials" +``` + +Action: + +Create Backup on ArangoDeployment named `my-deployment` and upload it to `S3://test/kube-test`. + +### Download Backup + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackup" +metadata: + name: "example-arangodb-backup" + namespace: "arangodb" +spec: + deployment: + name: "my-deployment" + download: + repositoryURL: "S3://test/kube-test" + credentialsSecretName: "my-s3-rclone-credentials" + id: "backup-id" +``` + +Download Backup with id `backup-id` from `S3://test/kube-test` on ArangoDeployment named `my-deployment` + +### Restore + +Information about restoring can be found in [ArangoDeployment](deployment-resource-reference.md). + +## Advertised fields + +List of custom columns in CRD specification for Kubectl: +- `.spec.policyName` - optional name of the policy +- `.spec.deployment.name` - name of the deployment +- `.status.state` - current ArangoBackup Custom Resource state +- `.status.message` - additional message for current state + +## ArangoBackup Custom Resource Spec: + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackup" +metadata: + name: "example-arangodb-backup" + namespace: "arangodb" +spec: + policyName: "my-policy" + deployment: + name: "my-deployment" + options: + timeout: 3 + force: true + download: + repositoryURL: "s3:/..." + credentialsSecretName: "secret-name" + id: "backup-id" + upload: + repositoryURL: "s3:/..." + credentialsSecretName: "secret-name" +status: + state: "Ready" + time: "time" + message: "Message details" - + progress: + jobID: "id" + progress: "10%" + backup: + id: "id" + version: "3.9.0-dev" + forced: true + uploaded: true + downloaded: true + createdAt: "time" + sizeInBytes: 1 + numberOfDBServers: 3 + available: true +``` + +## `spec: Object` + +Spec of the ArangoBackup Custom Resource. + +Required: true + +Default: {} + +### `spec.deployment: Object` + +ArangoDeployment specification. + +Field is immutable. + +Required: true + +Default: {} + +#### `spec.deployment.name: String` + +Name of the ArangoDeployment Custom Resource within same namespace as ArangoBackup Custom Resource. + +Field is immutable. + +Required: true + +Default: "" + +#### `spec.policyName: String` + +Name of the ArangoBackupPolicy which created this Custom Resource + +Field is immutable. + +Required: false + +Default: "" + +### `spec.options: Object` + +Backup options. + +Field is immutable. + +Required: false + +Default: {} + +#### `spec.options.timeout: float` + +Timeout for Backup creation request in seconds. + +Field is immutable. + +Required: false + +Default: 30 + +#### `spec.options.allowInconsistent: bool` + +AllowInconsistent flag for Backup creation request. +If this value is set to true, backup is taken even if we are not able to acquire lock. + +Field is immutable. + +Required: false + +Default: false + +### `spec.download: Object` + +Backup download settings. + +Field is immutable. + +Required: false + +Default: {} + +#### `spec.download.repositoryURL: string` + +Field is immutable. Protocol needs to be defined in `spec.download.credentialsSecretName` if protocol is other than local. + +Mode protocols can be found at [rclone.org](https://rclone.org/). + +Format: `:/` + +Examples: +- `s3://my-bucket/test` +- `azure://test` + +Required: true + +Default: "" + +#### `spec.download.credentialsSecretName: string` + +Field is immutable. Name of the secret used while accessing repository + +Secret structure: + +```yaml +apiVersion: v1 +data: + token: +kind: Secret +metadata: + name: +type: Opaque +``` + +`JSON Token` options are described on the [rclone](https://rclone.org/) page. +We can define more than one protocols at same time in one secret. + +This field is defined in json format: + +```json +{ + "": { + "type":"", + ...parameters + } +} +``` + +AWS S3 example - based on [rclone S3](https://rclone.org/s3/) documentation and interactive process: + +```json +{ + "S3": { + "type": "s3", # Choose s3 type + "provider": "AWS", # Choose one of the providers + "env_auth": "false", # Define credentials in next step instead of using ENV + "access_key_id": "xxx", + "secret_access_key": "xxx", + "region": "eu-west-2", # Choose region + "acl": "private", # Set permissions on newly created remote object + } +} +``` + +and you can from now use `S3://bucket/path`. + +Required: false + +Default: "" + +##### Use IAM with Amazon EKS + +Instead of creating and distributing your AWS credentials to the containers or +using the Amazon EC2 instance's role, you can associate an IAM role with a +Kubernetes service account and configure pods to use the service account. + +1. Create a Policy to access the S3 bucket. + + ```bash + aws iam create-policy \ + --policy-name S3-ACCESS_ROLE \ + --policy-document \ + '{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:ListAllMyBuckets", + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": "*", + "Resource": "arn:aws:s3:::MY_BUCKET" + }, + { + "Effect": "Allow", + "Action": "*", + "Resource": "arn:aws:s3:::MY_BUCKET/*" + } + ] + }' + ``` + +2. Create an IAM role for the service account (SA). + + ```bash + eksctl create iamserviceaccount \ + --name SA_NAME \ + --namespace NAMESPACE \ + --cluster CLUSTER_NAME \ + --attach-policy-arn arn:aws:iam::ACCOUNT_ID:policy/S3-ACCESS_ROLE \ + --approve + ``` + +3. Ensure that you use that SA in your ArangoDeployment for `dbservers` and + `coordinators`. + + ```yaml + apiVersion: database.arangodb.com/v1 + kind: ArangoDeployment + metadata: + name: cluster + spec: + image: arangodb/enterprise + mode: Cluster + + dbservers: + serviceAccountName: SA_NAME + coordinators: + serviceAccountName: SA_NAME + ``` + +4. Create a `Secret` Kubernetes object with a configuration for S3. + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: arangodb-cluster-backup-credentials + type: Opaque + stringData: + token: | + { + "s3": { + "type": "s3", + "provider": "AWS", + "env_auth": "true", + "location_constraint": "eu-central-1", + "region": "eu-central-1", + "acl": "private", + "no_check_bucket": "true" + } + } + ``` + +5. Create an `ArangoBackup` Kubernetes object with upload to S3. + + ```yaml + apiVersion: "backup.arangodb.com/v1alpha" + kind: "ArangoBackup" + metadata: + name: backup + spec: + deployment: + name: MY_DEPLOYMENT + upload: + repositoryURL: "s3:MY_BUCKET" + credentialsSecretName: arangodb-cluster-backup-credentials + ``` + +#### `spec.download.id: string` + +ID of the ArangoBackup to be downloaded. + +Field is immutable. + +Required: true + +Default: "" + +### `spec.upload: Object` + +Backup upload settings. + +This field can be removed and created again with different values. This operation will trigger upload again. +Fields in Custom Resource Spec Upload are immutable. + +Required: false + +Default: {} + +#### `spec.upload.repositoryURL: string` + +Same structure as `spec.download.repositoryURL`. + +Required: true + +Default: "" + +#### `spec.upload.credentialsSecretName: string` + +Same structure as `spec.download.credentialsSecretName`. + +Required: false + +Default: "" + +## `status: Object` + +Status of the ArangoBackup Custom Resource. This field is managed by subresource and only by operator + +Required: true + +Default: {} + +### `status.state: enum` + +State of the ArangoBackup object. + +Required: true + +Default: "" + +Possible states: +- "" - default state, changed to "Pending" +- "Pending" - state in which Custom Resource is queued. If Backup is possible changed to "Scheduled" +- "Scheduled" - state which will start create/download process +- "Download" - state in which download request will be created on ArangoDB +- "DownloadError" - state when download failed +- "Downloading" - state for downloading progress +- "Create" - state for creation, field available set to true +- "Upload" - state in which upload request will be created on ArangoDB +- "Uploading" - state for uploading progress +- "UploadError" - state when uploading failed +- "Ready" - state when Backup is finished +- "Deleted" - state when Backup was once in ready, but has been deleted +- "Failed" - state for failure +- "Unavailable" - state when Backup is not available on the ArangoDB. It can happen in case of upgrades, node restarts etc. + +### `status.time: timestamp` + +Time in UTC when state of the ArangoBackup Custom Resource changed. + +Required: true + +Default: "" + +### `status.message: string` + +State message of the ArangoBackup Custom Resource. + +Required: false + +Default: "" + +### `status.progress: object` + +Progress info of the uploading and downloading process. + +Required: false + +Default: {} + +#### `status.progress.jobID: string` + +ArangoDB job ID for uploading or downloading. + +Required: true + +Default: "" + +#### `status.progress.progress: string` + +ArangoDeployment job progress. + +Required: true + +Default: "0%" + +### `status.backup: object` + +ArangoBackup details. + +Required: true + +Default: {} + +#### `status.backup.id: string` + +ArangoBackup ID. + +Required: true + +Default: "" + +#### `status.backup.version: string` + +ArangoBackup version. + +Required: true + +Default: "" + +#### `status.backup.potentiallyInconsistent: bool` + +ArangoBackup potentially inconsistent flag. + +Required: false + +Default: false + +#### `status.backup.uploaded: bool` + +Determines if ArangoBackup has been uploaded. + +Required: false + +Default: false + +#### `status.backup.downloaded: bool` + +Determines if ArangoBackup has been downloaded. + +Required: false + +Default: false + +#### `status.backup.createdAt: TimeStamp` + +ArangoBackup Custom Resource creation time in UTC. + +Required: true + +Default: now() + +#### `status.backup.sizeInBytes: uint64` + +Size of the Backup in ArangoDB. + +Required: true + +Default: 0 + +#### `status.backup.numberOfDBServers: uint` + +Cluster size of the Backup in ArangoDB. + +Required: true + +Default: 0 + +### `status.available: bool` + +Determines if we can restore from ArangoBackup. + +Required: true + +Default: false diff --git a/docs/backuppolicy-resource.md b/docs/backuppolicy-resource.md new file mode 100644 index 000000000..b863238ec --- /dev/null +++ b/docs/backuppolicy-resource.md @@ -0,0 +1,185 @@ +# ArangoBackupPolicy Custom Resource + +The ArangoBackupPolicy represents schedule definition for creating ArangoBackup Custom Resources by operator. +This deployment specification is a `CustomResource` following a `CustomResourceDefinition` created by the operator. + +## Examples + +### Create schedule for all deployments + +You can create an ArangoBackup Custom Resource for each ArangoBackup every 15 minutes. + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackupPolicy" +metadata: + name: "example-arangodb-backup-policy" +spec: + schedule: "*/15 * * * *" +``` + +### Create schedule for selected deployments + +You can create an ArangoBackup Custom Resource for selected ArangoBackups every 15 minutes. + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackupPolicy" +metadata: + name: "example-arangodb-backup-policy" +spec: + schedule: "*/15 * * * *" + selector: + matchLabels: + labelName: "labelValue" +``` + +### Create schedule for all deployments and upload + +You can create an ArangoBackup Custom Resource for each ArangoBackup every 15 +minutes and upload it to the specified repositoryURL. + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackupPolicy" +metadata: + name: "example-arangodb-backup-policy" +spec: + schedule: "*/15 * * * * " + template: + upload: + repositoryURL: "s3:/..." + credentialsSecretName: "secret-name" +``` + +### Create schedule for all deployments, don't allow parallel backup runs, keep limited number of backups + +You can create an ArangoBackup Custom Resource for each ArangoBackup every 15 +minutes. You can keep 10 backups per deployment at the same time, and delete the +oldest ones. Don't allow to run backup if previous backup is not finished. + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackupPolicy" +metadata: + name: "example-arangodb-backup-policy" +spec: + schedule: "*/15 * * * *" + maxBackups: 10 + allowConcurrent: False +``` + +## ArangoBackup Custom Resource Spec + +```yaml +apiVersion: "backup.arangodb.com/v1" +kind: "ArangoBackupPolicy" +metadata: + name: "example-arangodb-backup-policy" +spec: + schedule: "*/15 * * * * " + selector: + matchLabels: + labelName: "labelValue" + matchExpressions: [] + template: + options: + timeout: 3 + force: true + upload: + repositoryURL: "s3:/..." + credentialsSecretName: "secret-name" +status: + scheduled: "time" + message: "message" +``` + +## `spec: Object` + +Spec of the ArangoBackupPolicy Custom Resource + +Required: true + +Default: {} + +### `spec.schedule: String` + +Schedule definition. Parser from https://godoc.org/github.com/robfig/cron + +Required: true + +Default: "" + +### `spec.allowConcurrent: String` + +If false, ArangoBackup will not be created when previous backups are not finished. +`ScheduleSkipped` event will be published in that case. + +Required: false + +Default: True + +### `spec.maxBackups: Integer` + +If > 0, then old healthy backups of that policy will be removed to ensure that only `maxBackups` are present at same time. +`CleanedUpOldBackups` event will be published on automatic removal of old backups. + +Required: false + +Default: 0 + +### `spec.selector: Object` + +Selector definition for selecting matching ArangoBackup Custom Resources. Parser from https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#LabelSelector + +Required: false + +Default: {} + +### `spec.template: ArangoBackupTemplate` + +Template for the ArangoBackup Custom Resource + +Required: false + +Default: {} + +### `spec.template.options: ArangoBackup - spec.options` + +ArangoBackup options + +Required: false + +Default: {} + +### `spec.template.upload: ArangoBackup - spec.upload` + +ArangoBackup upload configuration + +Required: false + +Default: {} + +## `status: Object` + +Status of the ArangoBackupPolicy Custom Resource managed by operator + +Required: true + +Default: {} + +### `status.scheduled: TimeStamp` + +Next scheduled time in UTC + +Required: true + +Default: "" + +### `status.message: String` + +Message from the operator in case of failure - schedule not valid, ArangoBackupPolicy not valid + +Required: false + +Default: "" diff --git a/docs/configuration-and-secrets.md b/docs/configuration-and-secrets.md new file mode 100644 index 000000000..798524b68 --- /dev/null +++ b/docs/configuration-and-secrets.md @@ -0,0 +1,36 @@ +# Configuration & secrets + +An ArangoDB cluster has lots of configuration options. +Some will be supported directly in the ArangoDB Operator, +others will have to specified separately. + +## Passing command line options + +All command-line options of `arangod` (and `arangosync`) are available +by adding options to the `spec..args` list of a group +of servers. + +These arguments are added to the command-line created for these servers. + +## Secrets + +The ArangoDB cluster needs several secrets such as JWT tokens +TLS certificates and so on. + +All these secrets are stored as Kubernetes Secrets and passed to +the applicable Pods as files, mapped into the Pods filesystem. + +The name of the secret is specified in the custom resource. +For example: + +```yaml +apiVersion: "database.arangodb.com/v1" +kind: "ArangoDeployment" +metadata: + name: "example-simple-cluster" +spec: + mode: Cluster + image: 'arangodb/arangodb:3.10.8' + auth: + jwtSecretName: +``` diff --git a/docs/design/dashboard.md b/docs/dashboards.md similarity index 70% rename from docs/design/dashboard.md rename to docs/dashboards.md index 022606b1c..3c34f39ef 100644 --- a/docs/design/dashboard.md +++ b/docs/dashboards.md @@ -1,3 +1,3 @@ -# Deployment Operator Dashboard +# Deployment Operator Dashboards ### Dashboard UI now is deprecated and will be removed in next minor version diff --git a/docs/deployment-replication-resource-reference.md b/docs/deployment-replication-resource-reference.md new file mode 100644 index 000000000..c7f33962e --- /dev/null +++ b/docs/deployment-replication-resource-reference.md @@ -0,0 +1,334 @@ +# ArangoDeploymentReplication Custom Resource + +#### Enterprise Edition only + + +The ArangoDB Replication Operator creates and maintains ArangoDB +`arangosync` configurations in a Kubernetes cluster, given a replication specification. +This replication specification is a `CustomResource` following +a `CustomResourceDefinition` created by the operator. + +Example of a minimal replication definition for two ArangoDB clusters with +sync in the same Kubernetes cluster: + +```yaml +apiVersion: "replication.database.arangodb.com/v1" +kind: "ArangoDeploymentReplication" +metadata: + name: "replication-from-a-to-b" +spec: + source: + deploymentName: cluster-a + auth: + keyfileSecretName: cluster-a-sync-auth + destination: + deploymentName: cluster-b +``` + +This definition results in: + +- the arangosync `SyncMaster` in deployment `cluster-b` is called to configure a synchronization + from the syncmasters in `cluster-a` to the syncmasters in `cluster-b`, + using the client authentication certificate stored in `Secret` `cluster-a-sync-auth`. + To access `cluster-a`, the JWT secret found in the deployment of `cluster-a` is used. + To access `cluster-b`, the JWT secret found in the deployment of `cluster-b` is used. + +Example replication definition for replicating from a source that is outside the current Kubernetes cluster +to a destination that is in the same Kubernetes cluster: + +```yaml +apiVersion: "replication.database.arangodb.com/v1" +kind: "ArangoDeploymentReplication" +metadata: + name: "replication-from-a-to-b" +spec: + source: + masterEndpoint: ["https://163.172.149.229:31888", "https://51.15.225.110:31888", "https://51.15.229.133:31888"] + auth: + keyfileSecretName: cluster-a-sync-auth + tls: + caSecretName: cluster-a-sync-ca + destination: + deploymentName: cluster-b +``` + +This definition results in: + +- the arangosync `SyncMaster` in deployment `cluster-b` is called to configure a synchronization + from the syncmasters located at the given list of endpoint URLs to the syncmasters `cluster-b`, + using the client authentication certificate stored in `Secret` `cluster-a-sync-auth`. + To access `cluster-a`, the keyfile (containing a client authentication certificate) is used. + To access `cluster-b`, the JWT secret found in the deployment of `cluster-b` is used. + +## DC2DC Replication Example + +The requirements for setting up Datacenter-to-Datacenter (DC2DC) Replication are: + +- You need to have two ArangoDB clusters running in two different Kubernetes clusters. +- Both Kubernetes clusters are equipped with support for `Services` of type `LoadBalancer`. +- You can create (global) DNS names for configured `Services` with low propagation times. E.g. use Cloudflare. +- You have 4 DNS names available: + - One for the database in the source ArangoDB cluster, e.g. `src-db.mycompany.com` + - One for the ArangoDB syncmasters in the source ArangoDB cluster, e.g. `src-sync.mycompany.com` + - One for the database in the destination ArangoDB cluster, e.g. `dst-db.mycompany.com` + - One for the ArangoDB syncmasters in the destination ArangoDB cluster, e.g. `dst-sync.mycompany.com` + +Follow these steps to configure DC2DC replication between two ArangoDB clusters +running in Kubernetes: + +1. Enable DC2DC Replication support on the source ArangoDB cluster. + + Set your current Kubernetes context to the Kubernetes source cluster. + + Edit the `ArangoDeployment` of the source ArangoDB clusters: + + - Set `spec.tls.altNames` to `["src-db.mycompany.com"]` (can include more names / IP addresses) + - Set `spec.sync.enabled` to `true` + - Set `spec.sync.externalAccess.masterEndpoint` to `["https://src-sync.mycompany.com:8629"]` + - Set `spec.sync.externalAccess.accessPackageSecretNames` to `["src-accesspackage"]` + +2. Extract the access package from the source ArangoDB cluster. + + ```bash + kubectl get secret src-accesspackage --template='{{index .data "accessPackage.yaml"}}' | \ + base64 -D > accessPackage.yaml + ``` + +3. Configure the source DNS names. + + ```bash + kubectl get service + ``` + + Find the IP address contained in the `LoadBalancer` column for the following `Services`: + - `-ea` Use this IP address for the `src-db.mycompany.com` DNS name. + - `-sync` Use this IP address for the `src-sync.mycompany.com` DNS name. + + The process for configuring DNS names is specific to each DNS provider. + + Set your current Kubernetes context to the Kubernetes destination cluster. + + Edit the `ArangoDeployment` of the source ArangoDB clusters: + + - Set `spec.tls.altNames` to `["dst-db.mycompany.com"]` (can include more names / IP addresses) + - Set `spec.sync.enabled` to `true` + - Set `spec.sync.externalAccess.masterEndpoint` to `["https://dst-sync.mycompany.com:8629"]` + +4. Enable DC2DC Replication support on the destination ArangoDB cluster. + +5. Import the access package in the destination cluster. + + ```bash + kubectl apply -f accessPackage.yaml + ``` + + Note: This imports two `Secrets`, containing TLS information about the source + cluster, into the destination cluster. + +6. Configure the destination DNS names. + + ```bash + kubectl get service + ``` + + Find the IP address contained in the `LoadBalancer` column for the following `Services`: + + - `-ea` Use this IP address for the `dst-db.mycompany.com` DNS name. + - `-sync` Use this IP address for the `dst-sync.mycompany.com` DNS name. + + The process for configuring DNS names is specific to each DNS provider. + +7. Create an `ArangoDeploymentReplication` resource. + + Create a yaml file (e.g. called `src-to-dst-repl.yaml`) with the following content: + + ```yaml + apiVersion: "replication.database.arangodb.com/v1" + kind: "ArangoDeploymentReplication" + metadata: + name: "replication-src-to-dst" + spec: + source: + masterEndpoint: ["https://src-sync.mycompany.com:8629"] + auth: + keyfileSecretName: src-accesspackage-auth + tls: + caSecretName: src-accesspackage-ca + destination: + deploymentName: + ``` + +8. Wait for the DNS names to propagate. + + Wait until the DNS names configured in step 3 and 6 resolve to their configured + IP addresses. + + Depending on your DNS provides this can take a few minutes up to 24 hours. + +9. Activate the replication. + + ```bash + kubectl apply -f src-to-dst-repl.yaml + ``` + + Replication from the source cluster to the destination cluster will now be configured. + + Check the status of the replication by inspecting the status of the + `ArangoDeploymentReplication` resource using: + + ```bash + kubectl describe ArangoDeploymentReplication replication-src-to-dst + ``` + + As soon as the replication is configured, the `Add collection` button in the `Collections` + page of the web interface (of the destination cluster) will be grayed out. + +## Specification reference + +Below you'll find all settings of the `ArangoDeploymentReplication` custom resource. + +### `spec.source.deploymentName: string` + +This setting specifies the name of an `ArangoDeployment` resource that runs a cluster +with sync enabled. + +This cluster configured as the replication source. + +### `spec.source.masterEndpoint: []string` + +This setting specifies zero or more master endpoint URLs of the source cluster. + +Use this setting if the source cluster is not running inside a Kubernetes cluster +that is reachable from the Kubernetes cluster the `ArangoDeploymentReplication` resource is deployed in. + +Specifying this setting and `spec.source.deploymentName` at the same time is not allowed. + +### `spec.source.auth.keyfileSecretName: string` + +This setting specifies the name of a `Secret` containing a client authentication certificate called `tls.keyfile` used to authenticate +with the SyncMaster at the specified source. + +If `spec.source.auth.userSecretName` has not been set, +the client authentication certificate found in the secret with this name is also used to configure +the synchronization and fetch the synchronization status. + +This setting is required. + +### `spec.source.auth.userSecretName: string` + +This setting specifies the name of a `Secret` containing a `username` & `password` used to authenticate +with the SyncMaster at the specified source in order to configure synchronization and fetch synchronization status. + +The user identified by the username must have write access in the `_system` database of the source ArangoDB cluster. + +### `spec.source.tls.caSecretName: string` + +This setting specifies the name of a `Secret` containing a TLS CA certificate `ca.crt` used to verify +the TLS connection created by the SyncMaster at the specified source. + +This setting is required, unless `spec.source.deploymentName` has been set. + +### `spec.destination.deploymentName: string` + +This setting specifies the name of an `ArangoDeployment` resource that runs a cluster +with sync enabled. + +This cluster configured as the replication destination. + +### `spec.destination.masterEndpoint: []string` + +This setting specifies zero or more master endpoint URLs of the destination cluster. + +Use this setting if the destination cluster is not running inside a Kubernetes cluster +that is reachable from the Kubernetes cluster the `ArangoDeploymentReplication` resource is deployed in. + +Specifying this setting and `spec.destination.deploymentName` at the same time is not allowed. + +### `spec.destination.auth.keyfileSecretName: string` + +This setting specifies the name of a `Secret` containing a client authentication certificate called `tls.keyfile` used to authenticate +with the SyncMaster at the specified destination. + +If `spec.destination.auth.userSecretName` has not been set, +the client authentication certificate found in the secret with this name is also used to configure +the synchronization and fetch the synchronization status. + +This setting is required, unless `spec.destination.deploymentName` or `spec.destination.auth.userSecretName` has been set. + +Specifying this setting and `spec.destination.userSecretName` at the same time is not allowed. + +### `spec.destination.auth.userSecretName: string` + +This setting specifies the name of a `Secret` containing a `username` & `password` used to authenticate +with the SyncMaster at the specified destination in order to configure synchronization and fetch synchronization status. + +The user identified by the username must have write access in the `_system` database of the destination ArangoDB cluster. + +Specifying this setting and `spec.destination.keyfileSecretName` at the same time is not allowed. + +### `spec.destination.tls.caSecretName: string` + +This setting specifies the name of a `Secret` containing a TLS CA certificate `ca.crt` used to verify +the TLS connection created by the SyncMaster at the specified destination. + +This setting is required, unless `spec.destination.deploymentName` has been set. + +## Authentication details + +The authentication settings in a `ArangoDeploymentReplication` resource are used for two distinct purposes. + +The first use is the authentication of the syncmasters at the destination with the syncmasters at the source. +This is always done using a client authentication certificate which is found in a `tls.keyfile` field +in a secret identified by `spec.source.auth.keyfileSecretName`. + +The second use is the authentication of the ArangoDB Replication operator with the syncmasters at the source +or destination. These connections are made to configure synchronization, stop configuration and fetch the status +of the configuration. +The method used for this authentication is derived as follows (where `X` is either `source` or `destination`): + +- If `spec.X.userSecretName` is set, the username + password found in the `Secret` identified by this name is used. +- If `spec.X.keyfileSecretName` is set, the client authentication certificate (keyfile) found in the `Secret` identifier by this name is used. +- If `spec.X.deploymentName` is set, the JWT secret found in the deployment is used. + +## Creating client authentication certificate keyfiles + +The client authentication certificates needed for the `Secrets` identified by `spec.source.auth.keyfileSecretName` & `spec.destination.auth.keyfileSecretName` +are normal ArangoDB keyfiles that can be created by the `arangosync create client-auth keyfile` command. +In order to do so, you must have access to the client authentication CA of the source/destination. + +If the client authentication CA at the source/destination also contains a private key (`ca.key`), the ArangoDeployment operator +can be used to create such a keyfile for you, without the need to have `arangosync` installed locally. +Read the following paragraphs for instructions on how to do that. + +## Creating and using access packages + +An access package is a YAML file that contains: + +- A client authentication certificate, wrapped in a `Secret` in a `tls.keyfile` data field. +- A TLS certificate authority public key, wrapped in a `Secret` in a `ca.crt` data field. + +The format of the access package is such that it can be inserted into a Kubernetes cluster using the standard `kubectl` tool. + +To create an access package that can be used to authenticate with the ArangoDB SyncMasters of an `ArangoDeployment`, +add a name of a non-existing `Secret` to the `spec.sync.externalAccess.accessPackageSecretNames` field of the `ArangoDeployment`. +In response, a `Secret` is created in that Kubernetes cluster, with the given name, that contains a `accessPackage.yaml` data field +that contains a Kubernetes resource specification that can be inserted into the other Kubernetes cluster. + +The process for creating and using an access package for authentication at the source cluster is as follows: + +- Edit the `ArangoDeployment` resource of the source cluster, set `spec.sync.externalAccess.accessPackageSecretNames` to `["my-access-package"]` +- Wait for the `ArangoDeployment` operator to create a `Secret` named `my-access-package`. +- Extract the access package from the Kubernetes source cluster using: + +```bash +kubectl get secret my-access-package --template='{{index .data "accessPackage.yaml"}}' | base64 -D > accessPackage.yaml +``` + +- Insert the secrets found in the access package in the Kubernetes destination cluster using: + +```bash +kubectl apply -f accessPackage.yaml +``` + +As a result, the destination Kubernetes cluster will have 2 additional `Secrets`. One contains a client authentication certificate +formatted as a keyfile. Another contains the public key of the TLS CA certificate of the source cluster. diff --git a/docs/deployment-resource-reference.md b/docs/deployment-resource-reference.md new file mode 100644 index 000000000..6e8f2d3cf --- /dev/null +++ b/docs/deployment-resource-reference.md @@ -0,0 +1,840 @@ +# ArangoDeployment Custom Resource + +The ArangoDB Deployment Operator creates and maintains ArangoDB deployments +in a Kubernetes cluster, given a deployment specification. +This deployment specification is a `CustomResource` following +a `CustomResourceDefinition` created by the operator. + +Example minimal deployment definition of an ArangoDB database cluster: + +```yaml +apiVersion: "database.arangodb.com/v1" +kind: "ArangoDeployment" +metadata: + name: "example-arangodb-cluster" +spec: + mode: Cluster +``` + +Example more elaborate deployment definition: + +```yaml +apiVersion: "database.arangodb.com/v1" +kind: "ArangoDeployment" +metadata: + name: "example-arangodb-cluster" +spec: + mode: Cluster + environment: Production + agents: + count: 3 + args: + - --log.level=debug + resources: + requests: + storage: 8Gi + storageClassName: ssd + dbservers: + count: 5 + resources: + requests: + storage: 80Gi + storageClassName: ssd + coordinators: + count: 3 + image: "arangodb/arangodb:3.9.3" +``` + +## Specification reference + +Below you'll find all settings of the `ArangoDeployment` custom resource. +Several settings are for various groups of servers. These are indicated +with `` where `` can be any of: + +- `agents` for all Agents of a `Cluster` or `ActiveFailover` pair. +- `dbservers` for all DB-Servers of a `Cluster`. +- `coordinators` for all Coordinators of a `Cluster`. +- `single` for all single servers of a `Single` instance or `ActiveFailover` pair. +- `syncmasters` for all syncmasters of a `Cluster`. +- `syncworkers` for all syncworkers of a `Cluster`. + +Special group `id` can be used for image discovery and testing affinity/toleration settings. + +### `spec.architecture: []string` + +This setting specifies a CPU architecture for the deployment. +Possible values are: + +- `amd64` (default): Use processors with the x86-64 architecture. +- `arm64`: Use processors with the 64-bit ARM architecture. + +The setting expects a list of strings, but you should only specify a single +list item for the architecture, except when you want to migrate from one +architecture to the other. The first list item defines the new default +architecture for the deployment that you want to migrate to. + +_Tip:_ +To use the ARM architecture, you need to enable it in the operator first using +`--set "operator.architectures={amd64,arm64}"`. See +[Installation with Helm](using-the-operator.md#installation-with-helm). + +To create a new deployment with `arm64` nodes, specify the architecture in the +deployment specification as follows: + +```yaml +spec: + architecture: + - arm64 +``` + +To migrate nodes of an existing deployment from `amd64` to `arm64`, modify the +deployment specification so that both architectures are listed: + +```diff + spec: + architecture: ++ - arm64 + - amd64 +``` + +This lets new members as well as recreated members use `arm64` nodes. + +Then run the following command: + +```bash +kubectl annotate pod $POD "deployment.arangodb.com/replace=true" +``` + +To change an existing member to `arm64`, annotate the pod as follows: + +```bash +kubectl annotate pod $POD "deployment.arangodb.com/arch=arm64" +``` + +An `ArchitectureMismatch` condition occurs in the deployment: + +```yaml +members: + single: + - arango-version: 3.10.0 + architecture: arm64 + conditions: + reason: Member has a different architecture than the deployment + status: "True" + type: ArchitectureMismatch +``` + +Restart the pod using this command: + +```bash +kubectl annotate pod $POD "deployment.arangodb.com/rotate=true" +``` + +### `spec.mode: string` + +This setting specifies the type of deployment you want to create. +Possible values are: + +- `Cluster` (default) Full cluster. Defaults to 3 Agents, 3 DB-Servers & 3 Coordinators. +- `ActiveFailover` Active-failover single pair. Defaults to 3 Agents and 2 single servers. +- `Single` Single server only (note this does not provide high availability or reliability). + +This setting cannot be changed after the deployment has been created. + +### `spec.environment: string` + +This setting specifies the type of environment in which the deployment is created. +Possible values are: + +- `Development` (default) This value optimizes the deployment for development + use. It is possible to run a deployment on a small number of nodes (e.g. minikube). +- `Production` This value optimizes the deployment for production use. + It puts required affinity constraints on all pods to avoid Agents & DB-Servers + from running on the same machine. + +### `spec.image: string` + +This setting specifies the docker image to use for all ArangoDB servers. +In a `development` environment this setting defaults to `arangodb/arangodb:latest`. +For `production` environments this is a required setting without a default value. +It is highly recommend to use explicit version (not `latest`) for production +environments. + +### `spec.imagePullPolicy: string` + +This setting specifies the pull policy for the docker image to use for all ArangoDB servers. +Possible values are: + +- `IfNotPresent` (default) to pull only when the image is not found on the node. +- `Always` to always pull the image before using it. + +### `spec.imagePullSecrets: []string` + +This setting specifies the list of image pull secrets for the docker image to use for all ArangoDB servers. + +### `spec.annotations: map[string]string` + +This setting set specified annotations to all ArangoDeployment owned resources (pods, services, PVC's, PDB's). + +### `spec.storageEngine: string` + +This setting specifies the type of storage engine used for all servers +in the cluster. +Possible values are: + +- `MMFiles` To use the MMFiles storage engine. +- `RocksDB` (default) To use the RocksDB storage engine. + +This setting cannot be changed after the cluster has been created. + +### `spec.downtimeAllowed: bool` + +This setting is used to allow automatic reconciliation actions that yield +some downtime of the ArangoDB deployment. +When this setting is set to `false` (the default), no automatic action that +may result in downtime is allowed. +If the need for such an action is detected, an event is added to the `ArangoDeployment`. + +Once this setting is set to `true`, the automatic action is executed. + +Operations that may result in downtime are: + +- Rotating TLS CA certificate + +Note: It is still possible that there is some downtime when the Kubernetes +cluster is down, or in a bad state, irrespective of the value of this setting. + +### `spec.memberPropagationMode` + +Changes to a pod's configuration require a restart of that pod in almost all +cases. Pods are restarted eagerly by default, which can cause more restarts than +desired, especially when updating _arangod_ as well as the operator. +The propagation of the configuration changes can be deferred to the next restart, +either triggered manually by the user or by another operation like an upgrade. +This reduces the number of restarts for upgrading both the server and the +operator from two to one. + +- `always`: Restart the member as soon as a configuration change is discovered +- `on-restart`: Wait until the next restart to change the member configuration + +### `spec.rocksdb.encryption.keySecretName` + +This setting specifies the name of a Kubernetes `Secret` that contains +an encryption key used for encrypting all data stored by ArangoDB servers. +When an encryption key is used, encryption of the data in the cluster is enabled, +without it encryption is disabled. +The default value is empty. + +This requires the Enterprise Edition. + +The encryption key cannot be changed after the cluster has been created. + +The secret specified by this setting, must have a data field named 'key' containing +an encryption key that is exactly 32 bytes long. + +### `spec.networkAttachedVolumes: bool` + +The default of this option is `false`. If set to `true`, a `ResignLeaderShip` +operation will be triggered when a DB-Server pod is evicted (rather than a +`CleanOutServer` operation). Furthermore, the pod will simply be +redeployed on a different node, rather than cleaned and retired and +replaced by a new member. You must only set this option to `true` if +your persistent volumes are "movable" in the sense that they can be +mounted from a different k8s node, like in the case of network attached +volumes. If your persistent volumes are tied to a specific pod, you +must leave this option on `false`. + +### `spec.externalAccess.type: string` + +This setting specifies the type of `Service` that will be created to provide +access to the ArangoDB deployment from outside the Kubernetes cluster. +Possible values are: + +- `None` To limit access to application running inside the Kubernetes cluster. +- `LoadBalancer` To create a `Service` of type `LoadBalancer` for the ArangoDB deployment. +- `NodePort` To create a `Service` of type `NodePort` for the ArangoDB deployment. +- `Auto` (default) To create a `Service` of type `LoadBalancer` and fallback to a `Service` or type `NodePort` when the + `LoadBalancer` is not assigned an IP address. + +### `spec.externalAccess.loadBalancerIP: string` + +This setting specifies the IP used to for the LoadBalancer to expose the ArangoDB deployment on. +This setting is used when `spec.externalAccess.type` is set to `LoadBalancer` or `Auto`. + +If you do not specify this setting, an IP will be chosen automatically by the load-balancer provisioner. + +### `spec.externalAccess.loadBalancerSourceRanges: []string` + +If specified and supported by the platform (cloud provider), this will restrict traffic through the cloud-provider +load-balancer will be restricted to the specified client IPs. This field will be ignored if the +cloud-provider does not support the feature. + +More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/ + +### `spec.externalAccess.nodePort: int` + +This setting specifies the port used to expose the ArangoDB deployment on. +This setting is used when `spec.externalAccess.type` is set to `NodePort` or `Auto`. + +If you do not specify this setting, a random port will be chosen automatically. + +### `spec.externalAccess.advertisedEndpoint: string` + +This setting specifies the advertised endpoint for all Coordinators. + +### `spec.auth.jwtSecretName: string` + +This setting specifies the name of a kubernetes `Secret` that contains +the JWT token used for accessing all ArangoDB servers. +When no name is specified, it defaults to `-jwt`. +To disable authentication, set this value to `None`. + +If you specify a name of a `Secret`, that secret must have the token +in a data field named `token`. + +If you specify a name of a `Secret` that does not exist, a random token is created +and stored in a `Secret` with given name. + +Changing a JWT token results in stopping the entire cluster +and restarting it. + +### `spec.tls.caSecretName: string` + +This setting specifies the name of a kubernetes `Secret` that contains +a standard CA certificate + private key used to sign certificates for individual +ArangoDB servers. +When no name is specified, it defaults to `-ca`. +To disable authentication, set this value to `None`. + +If you specify a name of a `Secret` that does not exist, a self-signed CA certificate + key is created +and stored in a `Secret` with given name. + +The specified `Secret`, must contain the following data fields: + +- `ca.crt` PEM encoded public key of the CA certificate +- `ca.key` PEM encoded private key of the CA certificate + +### `spec.tls.altNames: []string` + +This setting specifies a list of alternate names that will be added to all generated +certificates. These names can be DNS names or email addresses. +The default value is empty. + +### `spec.tls.ttl: duration` + +This setting specifies the time to live of all generated +server certificates. +The default value is `2160h` (about 3 month). + +When the server certificate is about to expire, it will be automatically replaced +by a new one and the affected server will be restarted. + +Note: The time to live of the CA certificate (when created automatically) +will be set to 10 years. + +### `spec.sync.enabled: bool` + +This setting enables/disables support for data center 2 data center +replication in the cluster. When enabled, the cluster will contain +a number of `syncmaster` & `syncworker` servers. +The default value is `false`. + +### `spec.sync.externalAccess.type: string` + +This setting specifies the type of `Service` that will be created to provide +access to the ArangoSync syncMasters from outside the Kubernetes cluster. +Possible values are: + +- `None` To limit access to applications running inside the Kubernetes cluster. +- `LoadBalancer` To create a `Service` of type `LoadBalancer` for the ArangoSync SyncMasters. +- `NodePort` To create a `Service` of type `NodePort` for the ArangoSync SyncMasters. +- `Auto` (default) To create a `Service` of type `LoadBalancer` and fallback to a `Service` or type `NodePort` when the + `LoadBalancer` is not assigned an IP address. + +Note that when you specify a value of `None`, a `Service` will still be created, but of type `ClusterIP`. + +### `spec.sync.externalAccess.loadBalancerIP: string` + +This setting specifies the IP used for the LoadBalancer to expose the ArangoSync SyncMasters on. +This setting is used when `spec.sync.externalAccess.type` is set to `LoadBalancer` or `Auto`. + +If you do not specify this setting, an IP will be chosen automatically by the load-balancer provisioner. + +### `spec.sync.externalAccess.nodePort: int` + +This setting specifies the port used to expose the ArangoSync SyncMasters on. +This setting is used when `spec.sync.externalAccess.type` is set to `NodePort` or `Auto`. + +If you do not specify this setting, a random port will be chosen automatically. + +### `spec.sync.externalAccess.loadBalancerSourceRanges: []string` + +If specified and supported by the platform (cloud provider), this will restrict traffic through the cloud-provider +load-balancer will be restricted to the specified client IPs. This field will be ignored if the +cloud-provider does not support the feature. + +More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/ + +### `spec.sync.externalAccess.masterEndpoint: []string` + +This setting specifies the master endpoint(s) advertised by the ArangoSync SyncMasters. +If not set, this setting defaults to: + +- If `spec.sync.externalAccess.loadBalancerIP` is set, it defaults to `https://:<8629>`. +- Otherwise it defaults to `https://:<8629>`. + +### `spec.sync.externalAccess.accessPackageSecretNames: []string` + +This setting specifies the names of zero of more `Secrets` that will be created by the deployment +operator containing "access packages". An access package contains those `Secrets` that are needed +to access the SyncMasters of this `ArangoDeployment`. + +By removing a name from this setting, the corresponding `Secret` is also deleted. +Note that to remove all access packages, leave an empty array in place (`[]`). +Completely removing the setting results in not modifying the list. + +See [the `ArangoDeploymentReplication` specification](deployment-replication-resource-reference.md) for more information +on access packages. + +### `spec.sync.auth.jwtSecretName: string` + +This setting specifies the name of a kubernetes `Secret` that contains +the JWT token used for accessing all ArangoSync master servers. +When not specified, the `spec.auth.jwtSecretName` value is used. + +If you specify a name of a `Secret` that does not exist, a random token is created +and stored in a `Secret` with given name. + +### `spec.sync.auth.clientCASecretName: string` + +This setting specifies the name of a kubernetes `Secret` that contains +a PEM encoded CA certificate used for client certificate verification +in all ArangoSync master servers. +This is a required setting when `spec.sync.enabled` is `true`. +The default value is empty. + +### `spec.sync.mq.type: string` + +This setting sets the type of message queue used by ArangoSync. +Possible values are: + +- `Direct` (default) for direct HTTP connections between the 2 data centers. + +### `spec.sync.tls.caSecretName: string` + +This setting specifies the name of a kubernetes `Secret` that contains +a standard CA certificate + private key used to sign certificates for individual +ArangoSync master servers. + +When no name is specified, it defaults to `-sync-ca`. + +If you specify a name of a `Secret` that does not exist, a self-signed CA certificate + key is created +and stored in a `Secret` with given name. + +The specified `Secret`, must contain the following data fields: + +- `ca.crt` PEM encoded public key of the CA certificate +- `ca.key` PEM encoded private key of the CA certificate + +### `spec.sync.tls.altNames: []string` + +This setting specifies a list of alternate names that will be added to all generated +certificates. These names can be DNS names or email addresses. +The default value is empty. + +### `spec.sync.monitoring.tokenSecretName: string` + +This setting specifies the name of a kubernetes `Secret` that contains +the bearer token used for accessing all monitoring endpoints of all ArangoSync +servers. +When not specified, no monitoring token is used. +The default value is empty. + +### `spec.disableIPv6: bool` + +This setting prevents the use of IPv6 addresses by ArangoDB servers. +The default is `false`. + +This setting cannot be changed after the deployment has been created. + +### `spec.restoreFrom: string` + +This setting specifies a `ArangoBackup` resource name the cluster should be restored from. + +After a restore or failure to do so, the status of the deployment contains information about the +restore operation in the `restore` key. + +It will contain some of the following fields: +- _requestedFrom_: name of the `ArangoBackup` used to restore from. +- _message_: optional message explaining why the restore failed. +- _state_: state indicating if the restore was successful or not. Possible values: `Restoring`, `Restored`, `RestoreFailed` + +If the `restoreFrom` key is removed from the spec, the `restore` key is deleted as well. + +A new restore attempt is made if and only if either in the status restore is not set or if spec.restoreFrom and status.requestedFrom are different. + +### `spec.license.secretName: string` + +This setting specifies the name of a kubernetes `Secret` that contains +the license key token used for enterprise images. This value is not used for +the Community Edition. + +### `spec.bootstrap.passwordSecretNames.root: string` + +This setting specifies a secret name for the credentials of the root user. + +When a deployment is created the operator will setup the root user account +according to the credentials given by the secret. If the secret doesn't exist +the operator creates a secret with a random password. + +There are two magic values for the secret name: +- `None` specifies no action. This disables root password randomization. This is the default value. (Thus the root password is empty - not recommended) +- `Auto` specifies automatic name generation, which is `-root-password`. + +### `spec.metrics.enabled: bool` + +If this is set to `true`, the operator runs a sidecar container for +every Agent, DB-Server, Coordinator and Single server. + +In addition to the sidecar containers the operator will deploy a service +to access the exporter ports (from within the k8s cluster), and a +resource of type `ServiceMonitor`, provided the corresponding custom +resource definition is deployed in the k8s cluster. If you are running +Prometheus in the same k8s cluster with the Prometheus operator, this +will be the case. The `ServiceMonitor` will have the following labels +set: + +- `app: arangodb` +- `arango_deployment: YOUR_DEPLOYMENT_NAME` +- `context: metrics` +- `metrics: prometheus` + +This makes it possible that you configure your Prometheus deployment to +automatically start monitoring on the available Prometheus feeds. To +this end, you must configure the `serviceMonitorSelector` in the specs +of your Prometheus deployment to match these labels. For example: + +```yaml + serviceMonitorSelector: + matchLabels: + metrics: prometheus +``` + +would automatically select all pods of all ArangoDB cluster deployments +which have metrics enabled. + +### `spec.metrics.image: string` + +Deprecated in: v1.2.0 (kube-arangodb) + +See above, this is the name of the Docker image for the ArangoDB +exporter to expose metrics. If empty, the same image as for the main +deployment is used. + +### `spec.metrics.resources: ResourceRequirements` + +Introduced in: v0.4.3 (kube-arangodb) + +This setting specifies the resources required by the metrics container. +This includes requests and limits. +See [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container). + +### `spec.metrics.mode: string` + +Introduced in: v1.0.2 (kube-arangodb) + +Defines metrics exporter mode. + +Possible values: +- `exporter` (default): add sidecar to pods (except Agency pods) and exposes + metrics collected by exporter from ArangoDB Container. Exporter in this mode + exposes metrics which are accessible without authentication. +- `sidecar`: add sidecar to all pods and expose metrics from ArangoDB metrics + endpoint. Exporter in this mode exposes metrics which are accessible without + authentication. +- `internal`: configure ServiceMonitor to use internal ArangoDB metrics endpoint + (proper JWT token is generated for this endpoint). + +### `spec.metrics.tls: bool` + +Introduced in: v1.1.0 (kube-arangodb) + +Defines if TLS should be enabled on Metrics exporter endpoint. +The default is `true`. + +This option will enable TLS only if TLS is enabled on ArangoDeployment, +otherwise `true` value will not take any effect. + +### `spec.lifecycle.resources: ResourceRequirements` + +Introduced in: v0.4.3 (kube-arangodb) + +This setting specifies the resources required by the lifecycle init container. +This includes requests and limits. +See [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container). + +### `spec..count: number` + +This setting specifies the number of servers to start for the given group. +For the Agent group, this value must be a positive, odd number. +The default value is `3` for all groups except `single` (there the default is `1` +for `spec.mode: Single` and `2` for `spec.mode: ActiveFailover`). + +For the `syncworkers` group, it is highly recommended to use the same number +as for the `dbservers` group. + +### `spec..minCount: number` + +Specifies a minimum for the count of servers. If set, a specification is invalid if `count < minCount`. + +### `spec..maxCount: number` + +Specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`. + +### `spec..args: []string` + +This setting specifies additional command-line arguments passed to all servers of this group. +The default value is an empty array. + +### `spec..resources: ResourceRequirements` + +This setting specifies the resources required by pods of this group. This includes requests and limits. + +See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ for details. + +### `spec..overrideDetectedTotalMemory: bool` + +Introduced in: v1.0.1 (kube-arangodb) + +Set additional flag in ArangoDeployment pods to propagate Memory resource limits + +### `spec..volumeClaimTemplate.Spec: PersistentVolumeClaimSpec` + +Specifies a volumeClaimTemplate used by operator to create to volume claims for pods of this group. +This setting is not available for group `coordinators`, `syncmasters` & `syncworkers`. + +The default value describes a volume with `8Gi` storage, `ReadWriteOnce` access mode and volume mode set to `PersistentVolumeFilesystem`. + +If this field is not set and `spec..resources.requests.storage` is set, then a default volume claim +with size as specified by `spec..resources.requests.storage` will be created. In that case `storage` +and `iops` is not forwarded to the pods resource requirements. + +### `spec..pvcResizeMode: string` + +Specifies a resize mode used by operator to resize PVCs and PVs. + +Supported modes: +- runtime (default) - PVC will be resized in Pod runtime (EKS, GKE) +- rotate - Pod will be shutdown and PVC will be resized (AKS) + +### `spec..serviceAccountName: string` + +This setting specifies the `serviceAccountName` for the `Pods` created +for each server of this group. If empty, it defaults to using the +`default` service account. + +Using an alternative `ServiceAccount` is typically used to separate access rights. +The ArangoDB deployments need some very minimal access rights. With the +deployment of the operator, we grant the following rights for the `default` +service account: + +```yaml +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get +``` + +If you are using a different service account, please grant these rights +to that service account. + +### `spec..annotations: map[string]string` + +This setting set annotations overrides for pods in this group. Annotations are merged with `spec.annotations`. + +### `spec..priorityClassName: string` + +Priority class name for pods of this group. Will be forwarded to the pod spec. [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/) + +### `spec..probes.livenessProbeDisabled: bool` + +If set to true, the operator does not generate a liveness probe for new pods belonging to this group. + +### `spec..probes.livenessProbeSpec.initialDelaySeconds: int` + +Number of seconds after the container has started before liveness or readiness probes are initiated. Defaults to 2 seconds. Minimum value is 0. + +### `spec..probes.livenessProbeSpec.periodSeconds: int` + +How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + +### `spec..probes.livenessProbeSpec.timeoutSeconds: int` + +Number of seconds after which the probe times out. Defaults to 2 second. Minimum value is 1. + +### `spec..probes.livenessProbeSpec.failureThreshold: int` + +When a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. +Giving up means restarting the container. Defaults to 3. Minimum value is 1. + +### `spec..probes.readinessProbeDisabled: bool` + +If set to true, the operator does not generate a readiness probe for new pods belonging to this group. + +### `spec..probes.readinessProbeSpec.initialDelaySeconds: int` + +Number of seconds after the container has started before liveness or readiness probes are initiated. Defaults to 2 seconds. Minimum value is 0. + +### `spec..probes.readinessProbeSpec.periodSeconds: int` + +How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + +### `spec..probes.readinessProbeSpec.timeoutSeconds: int` + +Number of seconds after which the probe times out. Defaults to 2 second. Minimum value is 1. + +### `spec..probes.readinessProbeSpec.successThreshold: int` + +Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Minimum value is 1. + +### `spec..probes.readinessProbeSpec.failureThreshold: int` + +When a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. +Giving up means the Pod will be marked Unready. Defaults to 3. Minimum value is 1. + +### `spec..allowMemberRecreation: bool` + +Introduced in: v1.2.1 (kube-arangodb) + +This setting changes the member recreation logic based on group: +- For Sync Masters, Sync Workers, Coordinator and DB-Servers it determines if a member can be recreated in case of failure (default `true`) +- For Agents and Single this value is hardcoded to `false` and the value provided in spec is ignored. + +### `spec..tolerations: []Toleration` + +This setting specifies the `tolerations` for the `Pod`s created +for each server of this group. + +By default, suitable tolerations are set for the following keys with the `NoExecute` effect: + +- `node.kubernetes.io/not-ready` +- `node.kubernetes.io/unreachable` +- `node.alpha.kubernetes.io/unreachable` (will be removed in future version) + +For more information on tolerations, consult the +[Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + +### `spec..nodeSelector: map[string]string` + +This setting specifies a set of labels to be used as `nodeSelector` for Pods of this node. + +For more information on node selectors, consult the +[Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/). + +### `spec..entrypoint: string` +Entrypoint overrides container executable. + +### `spec..antiAffinity: PodAntiAffinity` +Specifies additional `antiAffinity` settings in ArangoDB Pod definitions. + +For more information on `antiAffinity`, consult the +[Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). + +### `spec..affinity: PodAffinity` +Specifies additional `affinity` settings in ArangoDB Pod definitions. + +For more information on `affinity`, consult the +[Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). + +### `spec..nodeAffinity: NodeAffinity` +Specifies additional `nodeAffinity` settings in ArangoDB Pod definitions. + +For more information on `nodeAffinity`, consult the +[Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). + +### `spec..securityContext: ServerGroupSpecSecurityContext` +Specifies additional `securityContext` settings in ArangoDB Pod definitions. +This is similar (but not fully compatible) to k8s SecurityContext definition. + +For more information on `securityContext`, consult the +[Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). + +### `spec..securityContext.addCapabilities: []Capability` +Adds new capabilities to containers. + +### `spec..securityContext.allowPrivilegeEscalation: bool` +Controls whether a process can gain more privileges than its parent process. + +### `spec..securityContext.privileged: bool` +Runs container in privileged mode. Processes in privileged containers are +essentially equivalent to root on the host. + +### `spec..securityContext.readOnlyRootFilesystem: bool` +Mounts the container's root filesystem as read-only. + +### `spec..securityContext.runAsNonRoot: bool` +Indicates that the container must run as a non-root user. + +### `spec..securityContext.runAsUser: integer` +The UID to run the entrypoint of the container process. + +### `spec..securityContext.runAsGroup: integer` +The GID to run the entrypoint of the container process. + +### `spec..securityContext.supplementalGroups: []integer` +A list of groups applied to the first process run in each container, in addition to the container's primary GID, +the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. + +### `spec..securityContext.fsGroup: integer` +A special supplemental group that applies to all containers in a pod. + +### `spec..securityContext.seccompProfile: SeccompProfile` +The seccomp options to use by the containers in this pod. + +### `spec..securityContext.seLinuxOptions: SELinuxOptions` +The SELinux context to be applied to all containers. + +## Image discovery group `spec.id` fields + +Image discovery (`id`) group supports only next subset of fields. +Refer to according field documentation in `spec.` description. + +- `spec.id.entrypoint: string` +- `spec.id.tolerations: []Toleration` +- `spec.id.nodeSelector: map[string]string` +- `spec.id.priorityClassName: string` +- `spec.id.antiAffinity: PodAntiAffinity` +- `spec.id.affinity: PodAffinity` +- `spec.id.nodeAffinity: NodeAffinity` +- `spec.id.serviceAccountName: string` +- `spec.id.securityContext: ServerGroupSpecSecurityContext` +- `spec.id.resources: ResourceRequirements` + +## Deprecated Fields + +### `spec..resources.requests.storage: storageUnit` + +This setting specifies the amount of storage required for each server of this group. +The default value is `8Gi`. + +This setting is not available for group `coordinators`, `syncmasters` & `syncworkers` +because servers in these groups do not need persistent storage. + +Please use VolumeClaimTemplate from now on. This field is not considered if +VolumeClaimTemplate is set. Note however, that the information in requests +is completely handed over to the pod in this case. + +### `spec..storageClassName: string` + +This setting specifies the `storageClass` for the `PersistentVolume`s created +for each server of this group. + +This setting is not available for group `coordinators`, `syncmasters` & `syncworkers` +because servers in these groups do not need persistent storage. + +Please use VolumeClaimTemplate from now on. This field is not considered if +VolumeClaimTemplate is set. Note however, that the information in requests +is completely handed over to the pod in this case. diff --git a/docs/design/README.md b/docs/design/README.md index d50fb3fbb..094bf8fcc 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1,4 +1,4 @@ -# ArangoDB operator architecture details +# ArangoDB operator architecture overview - [Operator API](./api.md) - [Backups](./backup.md) @@ -9,5 +9,4 @@ - [Pod eviction and replacement](./pod_eviction_and_replacement.md) - [Kubernetes Pod name versus cluster ID](./pod_name_versus_cluster_id.md) - [Resources & labels](./resources_and_labels.md) -- [Scaling](./scaling.md) - [Topology awareness](./topology_awareness.md) \ No newline at end of file diff --git a/docs/design/scaling.md b/docs/design/scaling.md deleted file mode 100644 index fe9ddaef2..000000000 --- a/docs/design/scaling.md +++ /dev/null @@ -1,21 +0,0 @@ -# Scaling - -Number of running servers is controlled through `spec..count` field. - -### Scale-up -When increasing the `count`, operator will try to create missing pods. -When scaling up make sure that you have enough computational resources / nodes, otherwise pod will stuck in Pending state. - - -### Scale-down - -Scaling down is always done 1 server at a time. - -Scale down is possible only when all other actions on ArangoDeployment are finished. - -The internal process followed by the ArangoDB operator when scaling up is as follows: -- It chooses a member to be evicted. First it will try to remove unhealthy members or fall-back to the member with highest deletion_priority. -- Making an internal calls, it forces the server to resign leadership. - In case of DB servers it means that all shard leaders will be switched to other servers. -- Wait until server is cleaned out from cluster -- Pod finalized diff --git a/docs/draining-nodes.md b/docs/draining-nodes.md new file mode 100644 index 000000000..0a27e7f2c --- /dev/null +++ b/docs/draining-nodes.md @@ -0,0 +1,453 @@ +# Draining Kubernetes nodes + +**If Kubernetes nodes with ArangoDB pods on them are drained without care +data loss can occur!** +The recommended procedure is described below. + +For maintenance work in k8s it is sometimes necessary to drain a k8s node, +which means removing all pods from it. Kubernetes offers a standard API +for this and our operator supports this - to the best of its ability. + +Draining nodes is easy enough for stateless services, which can simply be +re-launched on any other node. However, for a stateful service this +operation is more difficult, and as a consequence more costly and there +are certain risks involved, if the operation is not done carefully +enough. To put it simply, the operator must first move all the data +stored on the node (which could be in a locally attached disk) to +another machine, before it can shut down the pod gracefully. Moving data +takes time, and even after the move, the distributed system ArangoDB has +to recover from this change, for example by ensuring data synchronicity +between the replicas in their new location. + +Therefore, a systematic drain of all k8s nodes in sequence has to follow +a careful procedure, in particular to ensure that ArangoDB is ready to +move to the next step. This is necessary to avoid catastrophic data +loss, and is simply the price one pays for running a stateful service. + +## Anatomy of a drain procedure in k8s: the grace period + +When a `kubectl drain` operation is triggered for a node, k8s first +checks if there are any pods with local data on disk. Our ArangoDB pods have +this property (the _Coordinators_ do use `EmptyDir` volumes, and _Agents_ +and _DB-Servers_ could have persistent volumes which are actually stored on +a locally attached disk), so one has to override this with the +`--delete-local-data=true` option. + +Furthermore, quite often, the node will contain pods which are managed +by a `DaemonSet` (which is not the case for ArangoDB), which makes it +necessary to override this check with the `--ignore-daemonsets=true` +option. + +Finally, it is checked if the node has any pods which are not managed by +anything, either by k8s itself (`ReplicationController`, `ReplicaSet`, +`Job`, `DaemonSet` or `StatefulSet`) or by an operator. If this is the +case, the drain operation will be refused, unless one uses the option +`--force=true`. Since the ArangoDB operator manages our pods, we do not +have to use this option for ArangoDB, but you might have to use it for +other pods. + +If all these checks have been overcome, k8s proceeds as follows: All +pods are notified about this event and are put into a `Terminating` +state. During this time, they have a chance to take action, or indeed +the operator managing them has. In particular, although the pods get +termination notices, they can keep running until the operator has +removed all _finalizers_. This gives the operator a chance to sort out +things, for example in our case to move data away from the pod. + +However, there is a limit to this tolerance by k8s, and that is the +grace period. If the grace period has passed but the pod has not +actually terminated, then it is killed the hard way. If this happens, +the operator has no chance but to remove the pod, drop its persistent +volume claim and persistent volume. This will obviously lead to a +failure incident in ArangoDB and must be handled by fail-over management. +Therefore, **this event should be avoided**. + +## Things to check in ArangoDB before a node drain + +There are basically two things one should check in an ArangoDB cluster +before a node drain operation can be started: + + 1. All cluster nodes are up and running and healthy. + 2. For all collections and shards all configured replicas are in sync. + +#### Attention: +1) If any cluster node is unhealthy, there is an increased risk that the +system does not have enough resources to cope with a failure situation. +2) If any shard replicas are not currently in sync, then there is a serious +risk that the cluster is currently not as resilient as expected. + +One possibility to verify these two things is via the ArangoDB web interface. +Node health can be monitored in the _Overview_ tab under _NODES_: + +![Cluster Health Screen](images/HealthyCluster.png) + +**Check that all nodes are green** and that there is **no node error** in the +top right corner. + +As to the shards being in sync, see the _Shards_ tab under _NODES_: + +![Shard Screen](images/ShardsInSync.png) + +**Check that all collections have a green check mark** on the right side. +If any collection does not have such a check mark, you can click on the +collection and see the details about shards. Please keep in +mind that this has to be done **for each database** separately! + +Obviously, this might be tedious and calls for automation. Therefore, there +are APIs for this. The first one is [Cluster Health](https://docs.arangodb.com/stable/develop/http/cluster/#get-the-cluster-health): + +``` +POST /_admin/cluster/health +``` + +… which returns a JSON document looking like this: + +```json +{ + "Health": { + "CRDN-rxtu5pku": { + "Endpoint": "ssl://my-arangodb-cluster-coordinator-rxtu5pku.my-arangodb-cluster-int.default.svc:8529", + "LastAckedTime": "2019-02-20T08:09:22Z", + "SyncTime": "2019-02-20T08:09:21Z", + "Version": "3.4.2-1", + "Engine": "rocksdb", + "ShortName": "Coordinator0002", + "Timestamp": "2019-02-20T08:09:22Z", + "Status": "GOOD", + "SyncStatus": "SERVING", + "Host": "my-arangodb-cluster-coordinator-rxtu5pku.my-arangodb-cluster-int.default.svc", + "Role": "Coordinator", + "CanBeDeleted": false + }, + "PRMR-wbsq47rz": { + "LastAckedTime": "2019-02-21T09:14:24Z", + "Endpoint": "ssl://my-arangodb-cluster-dbserver-wbsq47rz.my-arangodb-cluster-int.default.svc:8529", + "SyncTime": "2019-02-21T09:14:24Z", + "Version": "3.4.2-1", + "Host": "my-arangodb-cluster-dbserver-wbsq47rz.my-arangodb-cluster-int.default.svc", + "Timestamp": "2019-02-21T09:14:24Z", + "Status": "GOOD", + "SyncStatus": "SERVING", + "Engine": "rocksdb", + "ShortName": "DBServer0006", + "Role": "DBServer", + "CanBeDeleted": false + }, + "AGNT-wrqmwpuw": { + "Endpoint": "ssl://my-arangodb-cluster-agent-wrqmwpuw.my-arangodb-cluster-int.default.svc:8529", + "Role": "Agent", + "CanBeDeleted": false, + "Version": "3.4.2-1", + "Engine": "rocksdb", + "Leader": "AGNT-oqohp3od", + "Status": "GOOD", + "LastAckedTime": 0.312 + }, + ... [some more entries, one for each instance] + }, + "ClusterId": "210a0536-fd28-46de-b77f-e8882d6d7078", + "error": false, + "code": 200 +} +``` + +Check that each instance has a `Status` field with the value `"GOOD"`. +Here is a shell command which makes this check easy, using the +[`jq` JSON pretty printer](https://stedolan.github.io/jq/): + +```bash +curl -k https://arangodb.9hoeffer.de:8529/_admin/cluster/health --user root: | jq . | grep '"Status"' | grep -v '"GOOD"' +``` + +For the shards being in sync there is the +[Cluster Inventory](https://docs.arangodb.com/stable/develop/http/replication/replication-dump#get-the-cluster-collections-and-indexes) + +API call: + +``` +POST /_db/_system/_api/replication/clusterInventory +``` + +… which returns a JSON body like this: + +```json +{ + "collections": [ + { + "parameters": { + "cacheEnabled": false, + "deleted": false, + "globallyUniqueId": "c2010061/", + "id": "2010061", + "isSmart": false, + "isSystem": false, + "keyOptions": { + "allowUserKeys": true, + "type": "traditional" + }, + "name": "c", + "numberOfShards": 6, + "planId": "2010061", + "replicationFactor": 2, + "shardKeys": [ + "_key" + ], + "shardingStrategy": "hash", + "shards": { + "s2010066": [ + "PRMR-vzeebvwf", + "PRMR-e6hbjob1" + ], + "s2010062": [ + "PRMR-e6hbjob1", + "PRMR-vzeebvwf" + ], + "s2010065": [ + "PRMR-e6hbjob1", + "PRMR-vzeebvwf" + ], + "s2010067": [ + "PRMR-vzeebvwf", + "PRMR-e6hbjob1" + ], + "s2010064": [ + "PRMR-vzeebvwf", + "PRMR-e6hbjob1" + ], + "s2010063": [ + "PRMR-e6hbjob1", + "PRMR-vzeebvwf" + ] + }, + "status": 3, + "type": 2, + "waitForSync": false + }, + "indexes": [], + "planVersion": 132, + "isReady": true, + "allInSync": true + }, + ... [more collections following] + ], + "views": [], + "tick": "38139421", + "state": "unused" +} +``` + +Check that for all collections the attributes `"isReady"` and `"allInSync"` +both have the value `true`. Note that it is necessary to do this for all +databases! + +Here is a shell command which makes this check easy: + +```bash +curl -k https://arangodb.9hoeffer.de:8529/_db/_system/_api/replication/clusterInventory --user root: | jq . | grep '"isReady"\|"allInSync"' | sort | uniq -c +``` + +If all these checks are performed and are okay, then it is safe to +continue with the clean out and drain procedure as described below. + + +#### Attention: +If there are some collections with `replicationFactor` set to +1, the system is not resilient and cannot tolerate the failure of even a +single server! One can still perform a drain operation in this case, but +if anything goes wrong, in particular if the grace period is chosen too +short and a pod is killed the hard way, data loss can happen. + +If all `replicationFactor`s of all collections are at least 2, then the +system can tolerate the failure of a single _DB-Server_. If you have set +the `Environment` to `Production` in the specs of the ArangoDB +deployment, you will only ever have one _DB-Server_ on each k8s node and +therefore the drain operation is relatively safe, even if the grace +period is chosen too small. + +Furthermore, we recommend to have one k8s node more than _DB-Servers_ in +you cluster, such that the deployment of a replacement _DB-Server_ can +happen quickly and not only after the maintenance work on the drained +node has been completed. However, with the necessary care described +below, the procedure should also work without this. + +Finally, one should **not run a rolling upgrade or restart operation** +at the time of a node drain. + +## Clean out a DB-Server manually + +In this step we clean out a _DB-Server_ manually, **before issuing the +`kubectl drain` command**. Previously, we have denoted this step as optional, +but for safety reasons, we consider it mandatory now, since it is near +impossible to choose the grace period long enough in a reliable way. + +Furthermore, if this step is not performed, we must choose +the grace period long enough to avoid any risk, as explained in the +previous section. However, this has a disadvantage which has nothing to +do with ArangoDB: We have observed, that some k8s internal services like +`fluentd` and some DNS services will always wait for the full grace +period to finish a node drain. Therefore, the node drain operation will +always take as long as the grace period. Since we have to choose this +grace period long enough for ArangoDB to move all data on the _DB-Server_ +pod away to some other node, this can take a considerable amount of +time, depending on the size of the data you keep in ArangoDB. + +Therefore it is more time-efficient to perform the clean-out operation +beforehand. One can observe completion and as soon as it is completed +successfully, we can then issue the drain command with a relatively +small grace period and still have a nearly risk-free procedure. + +To clean out a _DB-Server_ manually, we have to use this API: + +``` +POST /_admin/cluster/cleanOutServer +``` + +… and send as body a JSON document like this: + +```json +{"server":"DBServer0006"} +``` + +The value of the `"server"` attribute should be the name of the DB-Server +which is the one in the pod which resides on the node that shall be +drained next. This uses the UI short name (`ShortName` in the +`/_admin/cluster/health` API), alternatively one can use the +internal name, which corresponds to the pod name. In our example, the +pod name is: + +``` +my-arangodb-cluster-prmr-wbsq47rz-5676ed +``` + +… where `my-arangodb-cluster` is the ArangoDB deployment name, therefore +the internal name of the _DB-Server_ is `PRMR-wbsq47rz`. Note that `PRMR` +must be all capitals since pod names are always all lower case. So, we +could use the body: + +```json +{"server":"PRMR-wbsq47rz"} +``` + +You can use this command line to achieve this: + +```bash +curl -k https://arangodb.9hoeffer.de:8529/_admin/cluster/cleanOutServer --user root: -d '{"server":"PRMR-wbsq47rz"}' +``` + +The API call will return immediately with a body like this: + +```json +{"error":false,"id":"38029195","code":202} +``` + +The given `id` in this response can be used to query the outcome or +completion status of the clean out server job with this API: + +``` +GET /_admin/cluster/queryAgencyJob?id=38029195 +``` + +… which will return a body like this: + +```json +{ + "error": false, + "id": "38029195", + "status": "Pending", + "job": { + "timeCreated": "2019-02-21T10:42:14.727Z", + "server": "PRMR-wbsq47rz", + "timeStarted": "2019-02-21T10:42:15Z", + "type": "cleanOutServer", + "creator": "CRDN-rxtu5pku", + "jobId": "38029195" + }, + "code": 200 +} +``` + +Use this command line to check progress: + +```bash +curl -k https://arangodb.9hoeffer.de:8529/_admin/cluster/queryAgencyJob?id=38029195 --user root: +``` + +It indicates that the job is still ongoing (`"Pending"`). As soon as +the job has completed, the answer will be: + +```json +{ + "error": false, + "id": "38029195", + "status": "Finished", + "job": { + "timeCreated": "2019-02-21T10:42:14.727Z", + "server": "PRMR-e6hbjob1", + "jobId": "38029195", + "timeStarted": "2019-02-21T10:42:15Z", + "timeFinished": "2019-02-21T10:45:39Z", + "type": "cleanOutServer", + "creator": "CRDN-rxtu5pku" + }, + "code": 200 +} +``` + +From this moment on the _DB-Server_ can no longer be used to move +shards to. At the same time, it will no longer hold any data of the +cluster. + +Now the drain operation involving a node with this pod on it is +completely risk-free, even with a small grace period. + +## Performing the drain + +After all above [checks before a node drain](#things-to-check-in-arangodb-before-a-node-drain) +and the [manual clean out of the DB-Server](#clean-out-a-db-server-manually) +have been done successfully, it is safe to perform the drain operation, similar to this command: + +```bash +kubectl drain gke-draintest-default-pool-394fe601-glts --delete-local-data --ignore-daemonsets --grace-period=300 +``` + +As described above, the options `--delete-local-data` for ArangoDB and +`--ignore-daemonsets` for other services have been added. A `--grace-period` of +300 seconds has been chosen because for this example we are confident that all the data on our _DB-Server_ pod +can be moved to a different server within 5 minutes. Note that this is +**not saying** that 300 seconds will always be enough. Regardless of how +much data is stored in the pod, your mileage may vary, moving a terabyte +of data can take considerably longer! + +If the highly recommended step of +[cleaning out a DB-Server manually](#clean-out-a-db-server-manually) +has been performed beforehand, the grace period can easily be reduced to 60 +seconds - at least from the perspective of ArangoDB, since the server is already +cleaned out, so it can be dropped readily and there is still no risk. + +At the same time, this guarantees now that the drain is completed +approximately within a minute. + +## Things to check after a node drain + +After a node has been drained, there will usually be one of the +_DB-Servers_ gone from the cluster. As a replacement, another _DB-Server_ has +been deployed on a different node, if there is a different node +available. If not, the replacement can only be deployed when the +maintenance work on the drained node has been completed and it is +uncordoned again. In this latter case, one should wait until the node is +back up and the replacement pod has been deployed there. + +After that, one should perform the same checks as described in +[things to check before a node drain](#things-to-check-in-arangodb-before-a-node-drain) +above. + +Finally, it is likely that the shard distribution in the "new" cluster +is not balanced out. In particular, the new _DB-Server_ is not automatically +used to store shards. We recommend to +[re-balance](https://docs.arangodb.com/stable/deploy/deployment/cluster/administration/#movingrebalancing-_shards_) the shard distribution, +either manually by moving shards or by using the _Rebalance Shards_ +button in the _Shards_ tab under _NODES_ in the web interface. This redistribution can take +some time again and progress can be monitored in the UI. + +After all this has been done, **another round of checks should be done** +before proceeding to drain the next node. diff --git a/docs/driver-configuration.md b/docs/driver-configuration.md new file mode 100644 index 000000000..cfea7dfb4 --- /dev/null +++ b/docs/driver-configuration.md @@ -0,0 +1,132 @@ +# Configuring your driver for ArangoDB access + +In this chapter you'll learn how to configure a driver for accessing +an ArangoDB deployment in Kubernetes. + +The exact methods to configure a driver are specific to that driver. + +## Database endpoint(s) + +The endpoint(s) (or URLs) to communicate with is the most important +parameter your need to configure in your driver. + +Finding the right endpoints depend on whether your client application is running in +the same Kubernetes cluster as the ArangoDB deployment or not. + +### Client application in same Kubernetes cluster + +If your client application is running in the same Kubernetes cluster as +the ArangoDB deployment, you should configure your driver to use the +following endpoint: + +``` +https://..svc:8529 +``` + +Only if your deployment has set `spec.tls.caSecretName` to `None`, should +you use `http` instead of `https`. + +### Client application outside Kubernetes cluster + +If your client application is running outside the Kubernetes cluster in which +the ArangoDB deployment is running, your driver endpoint depends on the +external-access configuration of your ArangoDB deployment. + +If the external-access of the ArangoDB deployment is of type `LoadBalancer`, +then use the IP address of that `LoadBalancer` like this: + +``` +https://:8529 +``` + +If the external-access of the ArangoDB deployment is of type `NodePort`, +then use the IP address(es) of the `Nodes` of the Kubernetes cluster, +combined with the `NodePort` that is used by the external-access service. + +For example: + +``` +https://:30123 +``` + +You can find the type of external-access by inspecting the external-access `Service`. +To do so, run the following command: + +```bash +kubectl get service -n -ea +``` + +The output looks like this: + +```bash +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR +example-simple-cluster-ea LoadBalancer 10.106.175.38 192.168.10.208 8529:31890/TCP 1s app=arangodb,arango_deployment=example-simple-cluster,role=coordinator +``` + +In this case the external-access is of type `LoadBalancer` with a load-balancer IP address +of `192.168.10.208`. +This results in an endpoint of `https://192.168.10.208:8529`. + +## TLS settings + +As mentioned before the ArangoDB deployment managed by the ArangoDB operator +will use a secure (TLS) connection unless you set `spec.tls.caSecretName` to `None` +in your `ArangoDeployment`. + +When using a secure connection, you can choose to verify the server certificates +provides by the ArangoDB servers or not. + +If you want to verify these certificates, configure your driver with the CA certificate +found in a Kubernetes `Secret` found in the same namespace as the `ArangoDeployment`. + +The name of this `Secret` is stored in the `spec.tls.caSecretName` setting of +the `ArangoDeployment`. If you don't set this setting explicitly, it will be +set automatically. + +Then fetch the CA secret using the following command (or use a Kubernetes client library to fetch it): + +```bash +kubectl get secret -n --template='{{index .data "ca.crt"}}' | base64 -D > ca.crt +``` + +This results in a file called `ca.crt` containing a PEM encoded, x509 CA certificate. + +## Query requests + +For most client requests made by a driver, it does not matter if there is any +kind of load-balancer between your client application and the ArangoDB +deployment. + +#### Note: +Even a simple `Service` of type `ClusterIP` already behaves as a load-balancer. + +The exception to this is cursor-related requests made to an ArangoDB `Cluster` +deployment. The Coordinator that handles an initial query request (that results +in a `Cursor`) will save some in-memory state in that Coordinator, if the result +of the query is too big to be transfer back in the response of the initial +request. + +Follow-up requests have to be made to fetch the remaining data. These follow-up +requests must be handled by the same Coordinator to which the initial request +was made. As soon as there is a load-balancer between your client application +and the ArangoDB cluster, it is uncertain which Coordinator will receive the +follow-up request. + +ArangoDB will transparently forward any mismatched requests to the correct +Coordinator, so the requests can be answered correctly without any additional +configuration. However, this incurs a small latency penalty due to the extra +request across the internal network. + +To prevent this uncertainty client-side, make sure to run your client +application in the same Kubernetes cluster and synchronize your endpoints before +making the initial query request. This will result in the use (by the driver) of +internal DNS names of all Coordinators. A follow-up request can then be sent to +exactly the same Coordinator. + +If your client application is running outside the Kubernetes cluster the easiest +way to work around it is by making sure that the query results are small enough +to be returned by a single request. When that is not feasible, it is also +possible to resolve this when the internal DNS names of your Kubernetes cluster +are exposed to your client application and the resulting IP addresses are +routable from your client application. To expose internal DNS names of your +Kubernetes cluster, your can use [CoreDNS](https://coredns.io). diff --git a/docs/helm.md b/docs/helm.md new file mode 100644 index 000000000..f0c29b79e --- /dev/null +++ b/docs/helm.md @@ -0,0 +1,156 @@ +# Using the ArangoDB Kubernetes Operator with Helm + +[`Helm`](https://www.helm.sh/) is a package manager for Kubernetes, which enables +you to install various packages (include the ArangoDB Kubernetes Operator) +into your Kubernetes cluster. + +The benefit of `helm` (in the context of the ArangoDB Kubernetes Operator) +is that it allows for a lot of flexibility in how you install the operator. +For example you can install the operator in a namespace other than +`default`. + +## Charts + +The ArangoDB Kubernetes Operator is contained in `helm` chart `kube-arangodb` which contains the operator for the +`ArangoDeployment`, `ArangoLocalStorage` and `ArangoDeploymentReplication` resource types. + +## Configurable values for ArangoDB Kubernetes Operator + +The following values can be configured when installing the +ArangoDB Kubernetes Operator with `helm`. + +Values are passed to `helm` using an `--set==` argument passed +to the `helm install` or `helm upgrade` command. + +### `operator.image` + +Image used for the ArangoDB Operator. + +Default: `arangodb/kube-arangodb:latest` + +### `operator.imagePullPolicy` + +Image pull policy for Operator images. + +Default: `IfNotPresent` + +### `operator.imagePullSecrets` + +List of the Image Pull Secrets for Operator images. + +Default: `[]string` + +### `operator.service.type` + +Type of the Operator service. + +Default: `ClusterIP` + +### `operator.annotations` + +Annotations passed to the Operator Deployment definition. + +Default: `[]string` + +### `operator.resources.limits.cpu` + +CPU limits for operator pods. + +Default: `1` + +### `operator.resources.limits.memory` + +Memory limits for operator pods. + +Default: `256Mi` + +### `operator.resources.requested.cpu` + +Requested CPI by Operator pods. + +Default: `250m` + +### `operator.resources.requested.memory` + +Requested memory for operator pods. + +Default: `256Mi` + +### `operator.replicaCount` + +Replication count for Operator deployment. + +Default: `2` + +### `operator.updateStrategy` + +Update strategy for operator pod. + +Default: `Recreate` + +### `operator.features.deployment` + +Define if ArangoDeployment Operator should be enabled. + +Default: `true` + +### `operator.features.deploymentReplications` + +Define if ArangoDeploymentReplications Operator should be enabled. + +Default: `true` + +### `operator.features.storage` + +Define if ArangoLocalStorage Operator should be enabled. + +Default: `false` + +### `operator.features.backup` + +Define if ArangoBackup Operator should be enabled. + +Default: `false` + +### `operator.enableCRDManagement` + +If true and operator has enough access permissions, it will try to install missing CRDs. + +Default: `true` + +### `rbac.enabled` + +Define if RBAC should be enabled. + +Default: `true` + +## Alternate namespaces + +The `kube-arangodb` chart supports deployment into a non-default namespace. + +To install the `kube-arangodb` chart is a non-default namespace, use the `--namespace` +argument like this. + +```bash +helm install --namespace=mynamespace kube-arangodb.tgz +``` + +Note that since the operators claim exclusive access to a namespace, you can +install the `kube-arangodb` chart in a namespace once. +You can install the `kube-arangodb` chart in multiple namespaces. To do so, run: + +```bash +helm install --namespace=namespace1 kube-arangodb.tgz +helm install --namespace=namespace2 kube-arangodb.tgz +``` + +The `kube-arangodb-storage` chart is always installed in the `kube-system` namespace. + +## Common problems + +### Error: no available release name found + +This error is given by `helm install ...` in some cases where it has +insufficient permissions to install charts. + +For various ways to work around this problem go to [this Stackoverflow article](https://stackoverflow.com/questions/43499971/helm-error-no-available-release-name-found). diff --git a/docs/how-to/README.md b/docs/how-to/README.md index 775268386..8af03fff8 100644 --- a/docs/how-to/README.md +++ b/docs/how-to/README.md @@ -1,12 +1,12 @@ ## How-to... +- [How to set a license key](./set_license.md) - [Pass additional params to operator](additional_configuration.md) - [Change architecture / enable ARM support](arch_change.md) - [Configure timezone for cluster](configuring_tz.md) - [Collect debug data for support case](debugging.md) - [Configure logging](logging.md) - [Enable maintenance mode](maintenance.md) -- [Start metrics collection and monitoring](metrics.md) - [Override detected total memory](override_detected_memory.md) - [Manually recover cluster if you still have volumes with data](recovery.md) - [How to rotate Pod](rotate-pod.md) diff --git a/docs/how-to/set_license.md b/docs/how-to/set_license.md new file mode 100644 index 000000000..83a78abb4 --- /dev/null +++ b/docs/how-to/set_license.md @@ -0,0 +1,17 @@ +# How to set a license key + +After deploying the ArangoDB Kubernetes operator, use the command below to deploy your [license key](https://docs.arangodb.com/stable/operations/administration/license-management/) +as a secret which is required for the Enterprise Edition starting with version 3.9: + +```bash +kubectl create secret generic arango-license-key --from-literal=token-v2="" +``` + + +Then specify the newly created secret in the ArangoDeploymentSpec: +```yaml +spec: + # [...] + license: + secretName: arango-license-key +``` diff --git a/docs/images/HealthyCluster.png b/docs/images/HealthyCluster.png new file mode 100644 index 0000000000000000000000000000000000000000..2670e5bd2d7726649cf8cd187b230e95fa24b168 GIT binary patch literal 116745 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

Jc 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 literal 0 HcmV?d00001 diff --git a/docs/images/ShardsInSync.png b/docs/images/ShardsInSync.png new file mode 100644 index 0000000000000000000000000000000000000000..f013ba30a6def66416aada4cad27b7046ef4faea GIT binary patch literal 85868 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 literal 0 HcmV?d00001 diff --git a/docs/metrics.md b/docs/metrics.md new file mode 100644 index 000000000..f89fc8000 --- /dev/null +++ b/docs/metrics.md @@ -0,0 +1,152 @@ +# Metrics collection + +Operator provides metrics of its operations in a format supported by [Prometheus](https://prometheus.io/). + +The metrics are exposed through HTTPS on port `8528` under path `/metrics`. + +For a full list of available metrics, see [here](generated/metrics/README.md). + +Check out examples directory [examples/metrics](https://github.com/arangodb/kube-arangodb/tree/master/examples/metrics) +for `Services` and `ServiceMonitors` definitions you can use to integrate +with Prometheus through the [Prometheus-Operator by CoreOS](https://github.com/coreos/prometheus-operator). + + +#### Contents +- [Integration with standard Prometheus installation (no TLS)](#Integration-with-standard-Prometheus-installation-no-TLS) +- [Integration with standard Prometheus installation (TLS)](#Integration-with-standard-Prometheus-installation-TLS) +- [Integration with Prometheus Operator](#Integration-with-Prometheus-Operator) +- [Exposing ArangoDB metrics](#ArangoDB-metrics) + + +## Integration with standard Prometheus installation (no TLS) + +After creating operator deployment, you must configure Prometheus using a configuration file that instructs it +about which targets to scrape. +To do so, add a new scrape job to your prometheus.yaml config: +```yaml +scrape_configs: + - job_name: 'arangodb-operator' + + scrape_interval: 10s # scrape every 10 seconds. + + scheme: 'https' + tls_config: + insecure_skip_verify: true + + static_configs: + - targets: + - ":8528" +``` + +## Integration with standard Prometheus installation (TLS) + +By default, the operator uses self-signed certificate for its server API. +To use your own certificate, you need to create k8s secret containing certificate and provide secret name to operator. + +Create k8s secret (in same namespace where the operator is running): +```shell +kubectl create secret tls my-own-certificate --cert ./cert.crt --key ./cert.key +``` +Then edit the operator deployment definition (`kubectl edit deployments.apps`) to use your secret for its server API: +``` +spec: + # ... + containers: + # ... + args: + - --server.tls-secret-name=my-own-certificate + # ... +``` +Wait for operator pods to restart. + +Now update Prometheus config to use your certificate for operator scrape job: +```yaml +tls_config: + # if you are using self-signed certificate, just specify CA certificate: + ca_file: /etc/prometheus/rootCA.crt + + # otherwise, specify the generated client certificate and key: + cert_file: /etc/prometheus/cert.crt + key_file: /etc/prometheus/cert.key +``` + +## Integration with Prometheus Operator + +Assuming that you have [Prometheus Operator](https://prometheus-operator.dev/) installed in your cluster (`monitoring` namespace), +and kube-arangodb installed in `default` namespace, you can easily configure the integration with ArangoDB operator. + +The easiest way to do that is to create new a ServiceMonitor: +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: arango-deployment-operator + namespace: monitoring + labels: + prometheus: kube-prometheus +spec: + selector: + matchLabels: + app.kubernetes.io/name: kube-arangodb + namespaceSelector: + matchNames: + - default + endpoints: + - port: server + scheme: https + tlsConfig: + insecureSkipVerify: true +``` + +You also can see the example of Grafana dashboard at `examples/metrics` folder of this repo. + + +## ArangoDB metrics + +The operator can run [sidecar containers](./design/exporter.md) for ArangoDB deployments of type `Cluster` which expose metrics in Prometheus format. +Edit your `ArangoDeployment` resource, setting `spec.metrics.enabled` to true to enable ArangoDB metrics: +```yaml +spec: + metrics: + enabled: true +``` + +The operator will run a sidecar container for every cluster component. +In addition to the sidecar containers the operator will deploy a `Service` to access the exporter ports (from within the k8s cluster), +and a resource of type `ServiceMonitor`, provided the corresponding custom resource definition is deployed in the k8s cluster. +If you are running Prometheus in the same k8s cluster with the Prometheus operator, this will be the case. +The ServiceMonitor will have the following labels set: +```yaml +app: arangodb +arango_deployment: YOUR_DEPLOYMENT_NAME +context: metrics +metrics: prometheus +``` +This makes it possible to configure your Prometheus deployment to automatically start monitoring on the available Prometheus feeds. +To this end, you must configure the `serviceMonitorSelector` in the specs of your Prometheus deployment to match these labels. For example: +```yaml +serviceMonitorSelector: + matchLabels: + metrics: prometheus +``` +would automatically select all pods of all ArangoDB cluster deployments which have metrics enabled. + +By default, the sidecar metrics exporters are using TLS for all connections. You can disable the TLS by specifying +```yaml +spec: + metrics: + enabled: true + tls: false +``` + +You can fine-tune the monitored metrics by specifying `ArangoDeployment` annotations. Example: +```yaml +spec: + annotations: + prometheus.io/scrape: 'true' + prometheus.io/port: '9101' + prometheus.io/scrape_interval: '5s' +``` + +See the [Metrics HTTP API documentation](https://docs.arangodb.com/stable/develop/http/monitoring/#metrics) +for the metrics exposed by ArangoDB deployments. diff --git a/docs/scaling.md b/docs/scaling.md new file mode 100644 index 000000000..a80a39d95 --- /dev/null +++ b/docs/scaling.md @@ -0,0 +1,42 @@ +# Scaling your ArangoDB deployment + +The ArangoDB Kubernetes Operator supports up and down scaling of +the number of DB-Servers & Coordinators. + +The scale up or down, change the number of servers in the custom +resource. + +E.g. change `spec.dbservers.count` from `3` to `4`. + +Then apply the updated resource using: + +```bash +kubectl apply -f yourCustomResourceFile.yaml +``` + +Inspect the status of the custom resource to monitor the progress of the scaling operation. + +**Note: It is not possible to change the number of Agency servers after creating a cluster**. +Make sure to specify the desired number when creating CR first time. + + +## Overview + +### Scale-up + +When increasing the `count`, operator will try to create missing pods. +When scaling up, make sure that you have enough computational resources / nodes, otherwise pod will stuck in Pending state. + + +### Scale-down + +Scaling down is always done 1 server at a time. + +Scale down is possible only when all other actions on ArangoDeployment are finished. + +The internal process followed by the ArangoDB operator when scaling up is as follows: +- It chooses a member to be evicted. First it will try to remove unhealthy members or fall-back to the member with highest deletion_priority. +- Making an internal calls, it forces the server to resign leadership. + In case of DB servers it means that all shard leaders will be switched to other servers. +- Wait until server is cleaned out from cluster. +- Pod finalized. diff --git a/docs/services-and-load-balancer.md b/docs/services-and-load-balancer.md new file mode 100644 index 000000000..264fdc014 --- /dev/null +++ b/docs/services-and-load-balancer.md @@ -0,0 +1,125 @@ +# Services & Load balancer + +The ArangoDB Kubernetes Operator will create services that can be used to +reach the ArangoDB servers from inside the Kubernetes cluster. + +By default, the ArangoDB Kubernetes Operator will also create an additional +service to reach the ArangoDB deployment from outside the Kubernetes cluster. + +For exposing the ArangoDB deployment to the outside, there are 2 options: + +- Using a `NodePort` service. This will expose the deployment on a specific port (above 30.000) + on all nodes of the Kubernetes cluster. +- Using a `LoadBalancer` service. This will expose the deployment on a load-balancer + that is provisioned by the Kubernetes cluster. + +The `LoadBalancer` option is the most convenient, but not all Kubernetes clusters +are able to provision a load-balancer. Therefore we offer a third (and default) option: `Auto`. +In this option, the ArangoDB Kubernetes Operator tries to create a `LoadBalancer` +service. It then waits for up to a minute for the Kubernetes cluster to provision +a load-balancer for it. If that has not happened after a minute, the service +is replaced by a service of type `NodePort`. + +To inspect the created service, run: + +```bash +kubectl get services -ea +``` + +To use the ArangoDB servers from outside the Kubernetes cluster +you have to add another service as explained below. + +## Services + +If you do not want the ArangoDB Kubernetes Operator to create an external-access +service for you, set `spec.externalAccess.Type` to `None`. + +If you want to create external access services manually, follow the instructions below. + +### Single server + +For a single server deployment, the operator creates a single +`Service` named ``. This service has a normal cluster IP +address. + +### Full cluster + +For a full cluster deployment, the operator creates two `Services`. + +- `-int` a headless `Service` intended to provide + DNS names for all pods created by the operator. + It selects all ArangoDB & ArangoSync servers in the cluster. + +- `` a normal `Service` that selects only the Coordinators + of the cluster. This `Service` is configured with `ClientIP` session + affinity. This is needed for cursor requests, since they are bound to + a specific Coordinator. + +When the Coordinators are asked to provide endpoints of the cluster +(e.g. when calling `client.SynchronizeEndpoints()` in the go driver) +the DNS names of the individual `Pods` will be returned +(`.-int..svc`) + +### Full cluster with DC2DC + +For a full cluster with datacenter replication deployment, +the same `Services` are created as for a Full cluster, with the following +additions: + +- `-sync` a normal `Service` that selects only the syncmasters + of the cluster. + +## Load balancer + +If you want full control of the `Services` needed to access the ArangoDB deployment +from outside your Kubernetes cluster, set `spec.externalAccess.type` of the `ArangoDeployment` to `None` +and create a `Service` as specified below. + +Create a `Service` of type `LoadBalancer` or `NodePort`, depending on your +Kubernetes deployment. + +This service should select: + +- `arango_deployment: ` +- `role: coordinator` + +The following example yields a service of type `LoadBalancer` with a specific +load balancer IP address. +With this service, the ArangoDB cluster can now be reached on `https://1.2.3.4:8529`. + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: arangodb-cluster-exposed +spec: + selector: + arango_deployment: arangodb-cluster + role: coordinator + type: LoadBalancer + loadBalancerIP: 1.2.3.4 + ports: + - protocol: TCP + port: 8529 + targetPort: 8529 +``` + +The following example yields a service of type `NodePort` with the ArangoDB +cluster exposed on port 30529 of all nodes of the Kubernetes cluster. + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: arangodb-cluster-exposed +spec: + selector: + arango_deployment: arangodb-cluster + role: coordinator + type: NodePort + ports: + - protocol: TCP + port: 8529 + targetPort: 8529 + nodePort: 30529 +``` diff --git a/docs/storage-resource.md b/docs/storage-resource.md new file mode 100644 index 000000000..fb22dfe66 --- /dev/null +++ b/docs/storage-resource.md @@ -0,0 +1,63 @@ +# ArangoLocalStorage Custom Resource + +The ArangoDB Storage Operator creates and maintains ArangoDB +storage resources in a Kubernetes cluster, given a storage specification. +This storage specification is a `CustomResource` following +a `CustomResourceDefinition` created by the operator. It is not enabled by +default in the operator. + +Example minimal storage definition: + +```yaml +apiVersion: "storage.arangodb.com/v1alpha" +kind: "ArangoLocalStorage" +metadata: + name: "example-arangodb-storage" +spec: + storageClass: + name: my-local-ssd + localPath: + - /mnt/big-ssd-disk +``` + +This definition results in: + +- a `StorageClass` called `my-local-ssd` +- the dynamic provisioning of PersistentVolume's with + a local volume on a node where the local volume starts + in a sub-directory of `/mnt/big-ssd-disk`. +- the dynamic cleanup of PersistentVolume's (created by + the operator) after one is released. + +The provisioned volumes will have a capacity that matches +the requested capacity of volume claims. + +## Specification reference + +Below you'll find all settings of the `ArangoLocalStorage` custom resource. + +### `spec.storageClass.name: string` + +This setting specifies the name of the storage class that +created `PersistentVolume` will use. + +If empty, this field defaults to the name of the `ArangoLocalStorage` +object. + +If a `StorageClass` with given name does not yet exist, it +will be created. + +### `spec.storageClass.isDefault: bool` + +This setting specifies if the created `StorageClass` will +be marked as default storage class. (default is `false`) + +### `spec.localPath: stringList` + +This setting specifies one of more local directories +(on the nodes) used to create persistent volumes in. + +### `spec.nodeSelector: nodeSelector` + +This setting specifies which nodes the operator will +provision persistent volumes on. diff --git a/docs/storage.md b/docs/storage.md new file mode 100644 index 000000000..e09361d00 --- /dev/null +++ b/docs/storage.md @@ -0,0 +1,144 @@ +# Storage configuration + +An ArangoDB cluster relies heavily on fast persistent storage. +The ArangoDB Kubernetes Operator uses `PersistentVolumeClaims` to deliver +the storage to Pods that need them. + +## Requirements + +To use `ArangoLocalStorage` resources, it has to be enabled in the operator +(replace `` with the +[version of the operator](https://github.com/arangodb/kube-arangodb/releases)): + +```bash +helm upgrade --install kube-arangodb \ +https://github.com/arangodb/kube-arangodb/releases/download//kube-arangodb-.tgz \ +--set operator.features.storage=true +``` + +## Storage configuration + +In the `ArangoDeployment` resource, one can specify the type of storage +used by groups of servers using the `spec..volumeClaimTemplate` +setting. + +This is an example of a `Cluster` deployment that stores its Agent & DB-Server +data on `PersistentVolumes` that use the `my-local-ssd` `StorageClass` + +The amount of storage needed is configured using the +`spec..resources.requests.storage` setting. + +```yaml +apiVersion: "database.arangodb.com/v1" +kind: "ArangoDeployment" +metadata: + name: "cluster-using-local-ssh" +spec: + mode: Cluster + agents: + volumeClaimTemplate: + spec: + storageClassName: my-local-ssd + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + volumeMode: Filesystem + dbservers: + volumeClaimTemplate: + spec: + storageClassName: my-local-ssd + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 80Gi + volumeMode: Filesystem +``` + +Note that configuring storage is done per group of servers. +It is not possible to configure storage per individual +server. + +This is an example of a `Cluster` deployment that requests volumes of 80GB +for every DB-Server, resulting in a total storage capacity of 240GB (with 3 DB-Servers). + +## Local storage + +For optimal performance, ArangoDB should be configured with locally attached +SSD storage. + +The easiest way to accomplish this is to deploy an +[`ArangoLocalStorage` resource](storage-resource.md). +The ArangoDB Storage Operator will use it to provide `PersistentVolumes` for you. + +This is an example of an `ArangoLocalStorage` resource that will result in +`PersistentVolumes` created on any node of the Kubernetes cluster +under the directory `/mnt/big-ssd-disk`. + +```yaml +apiVersion: "storage.arangodb.com/v1alpha" +kind: "ArangoLocalStorage" +metadata: + name: "example-arangodb-storage" +spec: + storageClass: + name: my-local-ssd + localPath: + - /mnt/big-ssd-disk +``` + +Note that using local storage required `VolumeScheduling` to be enabled in your +Kubernetes cluster. ON Kubernetes 1.10 this is enabled by default, on version +1.9 you have to enable it with a `--feature-gate` setting. + +### Manually creating `PersistentVolumes` + +The alternative is to create `PersistentVolumes` manually, for all servers that +need persistent storage (single, Agents & DB-Servers). +E.g. for a `Cluster` with 3 Agents and 5 DB-Servers, you must create 8 volumes. + +Note that each volume must have a capacity that is equal to or higher than the +capacity needed for each server. + +To select the correct node, add a required node-affinity annotation as shown +in the example below. + +```yaml +apiVersion: v1 +kind: PersistentVolume +metadata: + name: volume-agent-1 +spec: + capacity: + storage: 100Gi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Delete + storageClassName: local-ssd + local: + path: /mnt/disks/ssd1 + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - "node-1 +``` + +For Kubernetes 1.9 and up, you should create a `StorageClass` which is configured +to bind volumes on their first use as shown in the example below. +This ensures that the Kubernetes scheduler takes all constraints on a `Pod` +that into consideration before binding the volume to a claim. + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: local-ssd +provisioner: kubernetes.io/no-provisioner +volumeBindingMode: WaitForFirstConsumer +``` diff --git a/docs/tls.md b/docs/tls.md new file mode 100644 index 000000000..405823a89 --- /dev/null +++ b/docs/tls.md @@ -0,0 +1,54 @@ +# Secure connections (TLS) + +The ArangoDB Kubernetes Operator will by default create ArangoDB deployments +that use secure TLS connections. + +It uses a single CA certificate (stored in a Kubernetes secret) and +one certificate per ArangoDB server (stored in a Kubernetes secret per server). + +To disable TLS, set `spec.tls.caSecretName` to `None`. + +## Install CA certificate + +If the CA certificate is self-signed, it will not be trusted by browsers, +until you install it in the local operating system or browser. +This process differs per operating system. + +To do so, you first have to fetch the CA certificate from its Kubernetes +secret. + +```bash +kubectl get secret -ca --template='{{index .data "ca.crt"}}' | base64 -D > ca.crt +``` + +### Windows + +To install a CA certificate in Windows, follow the +[procedure described here](http://wiki.cacert.org/HowTo/InstallCAcertRoots). + +### macOS + +To install a CA certificate in macOS, run: + +```bash +sudo /usr/bin/security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.crt +``` + +To uninstall a CA certificate in macOS, run: + +```bash +sudo /usr/bin/security remove-trusted-cert -d ca.crt +``` + +### Linux + +To install a CA certificate in Linux, on Ubuntu, run: + +```bash +sudo cp ca.crt /usr/local/share/ca-certificates/.crt +sudo update-ca-certificates +``` + +## See also + +- [Authentication](authentication.md) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 000000000..eb57445df --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,115 @@ +# Troubleshooting + +While Kubernetes and the ArangoDB Kubernetes operator automatically +resolve a lot of issues, there are always cases where human attention +is needed. + +This chapter gives your tips & tricks to help you troubleshoot deployments. + +## Where to look + +In Kubernetes all resources can be inspected using `kubectl` using either +the `get` or `describe` command. + +To get all details of the resource (both specification & status), +run the following command: + +```bash +kubectl get -n -o yaml +``` + +For example, to get the entire specification and status +of an `ArangoDeployment` resource named `my-arangodb` in the `default` namespace, +run: + +```bash +kubectl get ArangoDeployment my-arango -n default -o yaml +# or shorter +kubectl get arango my-arango -o yaml +``` + +Several types of resources (including all ArangoDB custom resources) support +events. These events show what happened to the resource over time. + +To show the events (and most important resource data) of a resource, +run the following command: + +```bash +kubectl describe -n +``` + +## Getting logs + +Another invaluable source of information is the log of containers being run +in Kubernetes. +These logs are accessible through the `Pods` that group these containers. + +To fetch the logs of the default container running in a `Pod`, run: + +```bash +kubectl logs -n +# or with follow option to keep inspecting logs while they are written +kubectl logs -n -f +``` + +To inspect the logs of a specific container in `Pod`, add `-c `. +You can find the names of the containers in the `Pod`, using `kubectl describe pod ...`. + + +## What if + +### The `Pods` of a deployment stay in `Pending` state + +There are two common causes for this. + +- The `Pods` cannot be scheduled because there are not enough nodes available. + This is usually only the case with a `spec.environment` setting that has a value of `Production`. + + Solution: Add more nodes. + +- There are no `PersistentVolumes` available to be bound to the `PersistentVolumeClaims` + created by the operator. + + Solution: + Use `kubectl get persistentvolumes` to inspect the available `PersistentVolumes` + and if needed, use the [`ArangoLocalStorage` operator](storage-resource.md) + to provision `PersistentVolumes`. + +### When restarting a `Node`, the `Pods` scheduled on that node remain in `Terminating` state + +When a `Node` no longer makes regular calls to the Kubernetes API server, it is +marked as not available. Depending on specific settings in your `Pods`, Kubernetes +will at some point decide to terminate the `Pod`. As long as the `Node` is not +completely removed from the Kubernetes API server, Kubernetes tries to use +the `Node` itself to terminate the `Pod`. + +The `ArangoDeployment` operator recognizes this condition and tries to replace those +`Pods` with `Pods` on different nodes. The exact behavior differs per type of server. + +### What happens when a `Node` with local data is broken + +When a `Node` with `PersistentVolumes` hosted on that `Node` is broken and +cannot be repaired, the data in those `PersistentVolumes` is lost. + +If an `ArangoDeployment` of type `Single` was using one of those `PersistentVolumes` +the database is lost and must be restored from a backup. + +If an `ArangoDeployment` of type `ActiveFailover` or `Cluster` was using one of +those `PersistentVolumes`, it depends on the type of server that was using the volume. + +- If an `Agent` was using the volume, it can be repaired as long as 2 other + Agents are still healthy. +- If a `DBServer` was using the volume, and the replication factor of all database + collections is 2 or higher, and the remaining DB-Servers are still healthy, + the cluster duplicates the remaining replicas to + bring the number of replicas back to the original number. +- If a `DBServer` was using the volume, and the replication factor of a database + collection is 1 and happens to be stored on that DB-Server, the data is lost. +- If a single server of an `ActiveFailover` deployment was using the volume, and the + other single server is still healthy, the other single server becomes leader. + After replacing the failed single server, the new follower synchronizes with + the leader. + + +### See also +- [Collecting debug data](./how-to/debugging.md) \ No newline at end of file diff --git a/docs/upgrading.md b/docs/upgrading.md new file mode 100644 index 000000000..73a3c0e73 --- /dev/null +++ b/docs/upgrading.md @@ -0,0 +1,31 @@ +# Upgrading ArangoDB version + +The ArangoDB Kubernetes Operator supports upgrading an ArangoDB from +one version to the next. + +**Warning!** +It is highly recommended to take a backup of your data before upgrading ArangoDB +using [arangodump](https://docs.arangodb.com/stable/components/tools/arangodump/) or [ArangoBackup CR](backup-resource.md). + +## Upgrade an ArangoDB deployment + +To upgrade a cluster, change the version by changing +the `spec.image` setting and the apply the updated +custom resource using: + +```bash +kubectl apply -f yourCustomResourceFile.yaml +``` + +The ArangoDB operator will perform an sequential upgrade +of all servers in your deployment. Only one server is upgraded +at a time. + +For patch level upgrades (e.g. 3.9.2 to 3.9.3) each server +is stopped and restarted with the new version. + +For minor level upgrades (e.g. 3.9.2 to 3.10.0) each server +is stopped, then the new version is started with `--database.auto-upgrade` +and once that is finish the new version is started with the normal arguments. + +The process for major level upgrades depends on the specific version. diff --git a/docs/using-the-operator.md b/docs/using-the-operator.md new file mode 100644 index 000000000..dc5fdecc4 --- /dev/null +++ b/docs/using-the-operator.md @@ -0,0 +1,298 @@ +# Using the ArangoDB Kubernetes Operator + +## Installation + +The ArangoDB Kubernetes Operator needs to be installed in your Kubernetes +cluster first. Make sure you have access to this cluster and the rights to +deploy resources at cluster level. + +The following cloud provider Kubernetes offerings are officially supported: + +- Amazon Elastic Kubernetes Service (EKS) +- Google Kubernetes Engine (GKE) +- Microsoft Azure Kubernetes Service (AKS) + +If you have `Helm` available, use it for the installation as it is the +recommended installation method. + +### Installation with Helm + +To install the ArangoDB Kubernetes Operator with [`helm`](https://www.helm.sh/), +run the following commands (replace `` with the +[version of the operator](https://github.com/arangodb/kube-arangodb/releases) +that you want to install): + +```bash +export URLPREFIX=https://github.com/arangodb/kube-arangodb/releases/download/ +helm install --generate-name $URLPREFIX/kube-arangodb-.tgz +``` + +This installs operators for the `ArangoDeployment` and `ArangoDeploymentReplication` +resource types, which are used to deploy ArangoDB and ArangoDB Datacenter-to-Datacenter Replication respectively. + +If you want to avoid the installation of the operator for the `ArangoDeploymentReplication` +resource type, add `--set=DeploymentReplication.Create=false` to the `helm install` +command. + +To use `ArangoLocalStorage` resources, also run: + +```bash +helm install --generate-name $URLPREFIX/kube-arangodb-.tgz --set "operator.features.storage=true" +``` + +The default CPU architecture of the operator is `amd64` (x86-64). To enable ARM +support (`arm64`) in the operator, overwrite the following setting: + +```bash +helm install --generate-name $URLPREFIX/kube-arangodb-.tgz --set "operator.architectures={amd64,arm64}" +``` + +Note that you need to set [`spec.architecture`](deployment-resource-reference.md#specarchitecture-string) +in the deployment specification, too, in order to create a deployment that runs +on ARM chips. + +For more information on installing with `Helm` and how to customize an installation, +see [Using the ArangoDB Kubernetes Operator with Helm](helm.md). + +### Installation with Kubectl + +To install the ArangoDB Kubernetes Operator without `Helm`, +run (replace `` with the version of the operator that you want to install): + +```bash +export URLPREFIX=https://raw.githubusercontent.com/arangodb/kube-arangodb//manifests +kubectl apply -f $URLPREFIX/arango-crd.yaml +kubectl apply -f $URLPREFIX/arango-deployment.yaml +``` + +To use `ArangoLocalStorage` resources to provision `PersistentVolumes` on local +storage, also run: + +```bash +kubectl apply -f $URLPREFIX/arango-storage.yaml +``` + +Use this when running on bare-metal or if there is no provisioner for fast +storage in your Kubernetes cluster. + +To use `ArangoDeploymentReplication` resources for ArangoDB +Datacenter-to-Datacenter Replication, also run: + +```bash +kubectl apply -f $URLPREFIX/arango-deployment-replication.yaml +``` + +See [ArangoDeploymentReplication Custom Resource](deployment-replication-resource-reference.md) +for details and an example. + +You can find the latest release of the ArangoDB Kubernetes Operator +in the [kube-arangodb repository](https://github.com/arangodb/kube-arangodb/releases/latest). + +## ArangoDB deployment creation + +After deploying the latest ArangoDB Kubernetes operator, use the command below to deploy your [license key](https://docs.arangodb.com/stable/operations/administration/license-management/) as a secret which is required for the Enterprise Edition starting with version 3.9: + +```bash +kubectl create secret generic arango-license-key --from-literal=token-v2="" +``` + +Once the operator is running, you can create your ArangoDB database deployment +by creating a `ArangoDeployment` custom resource and deploying it into your +Kubernetes cluster. + +For example (all examples can be found in the [kube-arangodb repository](https://github.com/arangodb/kube-arangodb/tree/master/examples)): + +```bash +kubectl apply -f examples/simple-cluster.yaml +``` +Additionally, you can specify the license key required for the Enterprise Edition starting with version 3.9 as seen below: + +```yaml +spec: + # [...] + image: arangodb/enterprise:3.9.1 + license: + secretName: arango-license-key +``` + +## Connecting to your database + +Access to ArangoDB deployments from outside the Kubernetes cluster is provided +using an external-access service. By default, this service is of type +`LoadBalancer`. If this type of service is not supported by your Kubernetes +cluster, it is replaced by a service of type `NodePort` after a minute. + +To see the type of service that has been created, run (replace `` +with the `metadata.name` you set in the deployment configuration, e.g. +`example-simple-cluster`): + +```bash +kubectl get service -ea +``` + +When the service is of the `LoadBalancer` type, use the IP address +listed in the `EXTERNAL-IP` column with port 8529. +When the service is of the `NodePort` type, use the IP address +of any of the nodes of the cluster, combine with the high (>30000) port listed +in the `PORT(S)` column. + +Point your browser to `https://:/` (note the `https` protocol). +Your browser shows a warning about an unknown certificate. Accept the +certificate for now. Then log in using the username `root` and an empty password. + +## Deployment removal + +To remove an existing ArangoDB deployment, delete the custom resource. +The operator deletes all created resources. + +For example: + +```bash +kubectl delete -f examples/simple-cluster.yaml +``` + +**Note that this will also delete all data in your ArangoDB deployment!** + +If you want to keep your data, make sure to create a backup before removing the deployment. + +## Operator removal + +To remove the entire ArangoDB Kubernetes Operator, remove all +clusters first and then remove the operator by running: + +```bash +helm delete +# If `ArangoLocalStorage` operator is installed +helm delete +``` + +or when you used `kubectl` to install the operator, run: + +```bash +kubectl delete deployment arango-deployment-operator +# If `ArangoLocalStorage` operator is installed +kubectl delete deployment -n kube-system arango-storage-operator +# If `ArangoDeploymentReplication` operator is installed +kubectl delete deployment arango-deployment-replication-operator +``` + +## Example deployment using `minikube` + +If you want to get your feet wet with ArangoDB and Kubernetes, you can deploy +your first ArangoDB instance with `minikube`, which lets you easily set up a +local Kubernetes cluster. + +Visit the [`minikube` website](https://minikube.sigs.k8s.io/) +and follow the installation instructions and start the cluster with +`minikube start`. + +Next, go to +to find out the latest version of the ArangoDB Kubernetes Operator. Then run the +following commands, with `` replaced by the version you looked up: + +```bash +minikube kubectl -- apply -f https://raw.githubusercontent.com/arangodb/kube-arangodb//manifests/arango-crd.yaml +minikube kubectl -- apply -f https://raw.githubusercontent.com/arangodb/kube-arangodb//manifests/arango-deployment.yaml +minikube kubectl -- apply -f https://raw.githubusercontent.com/arangodb/kube-arangodb//manifests/arango-storage.yaml +``` + +To deploy a single server, create a file called `single-server.yaml` with the +following content: + +```yaml +apiVersion: "database.arangodb.com/v1" +kind: "ArangoDeployment" +metadata: + name: "single-server" +spec: + mode: Single +``` + +Insert this resource in your Kubernetes cluster using: + +```bash +minikube kubectl -- apply -f single-server.yaml +``` + +To deploy an ArangoDB cluster instead, create a file called `cluster.yaml` with +the following content: + +```yaml +apiVersion: "database.arangodb.com/v1" +kind: "ArangoDeployment" +metadata: + name: "cluster" +spec: + mode: Cluster +``` + +The same commands used in the single server deployment can be used to inspect +your cluster. Just use the correct deployment name (`cluster` instead of +`single-server`). + +The `ArangoDeployment` operator in `kube-arangodb` inspects the resource you +just deployed and starts the process to run ArangoDB. + +To inspect the current status of your deployment, run: + +```bash +minikube kubectl -- describe ArangoDeployment single-server +# or shorter +minikube kubectl -- describe arango single-server +``` + +To inspect the pods created for this deployment, run: + +```bash +minikube kubectl -- get pods --selector=arango_deployment=single-server +``` + +The result looks similar to this: + +``` +NAME READY STATUS RESTARTS AGE +single-server-sngl-cjtdxrgl-fe06f0 1/1 Running 0 1m +``` + +Once the pod reports that it is has a `Running` status and is ready, +your ArangoDB instance is available. + +To access ArangoDB, run: + +```bash +minikube service single-server-ea +``` + +This creates a temporary tunnel for the `single-server-ea` service and opens +your browser. You need change the URL to start with `https://`. By default, +it is `http://`, but the deployment uses TLS encryption for the connection. +For example, if the address is `http://127.0.0.1:59050`, you need to change it +to `https://127.0.0.1:59050`. + +Your browser warns about an unknown certificate. This is because a self-signed +certificate is used. Continue anyway. The exact steps for this depend on your +browser. + +You should see the login screen of ArangoDB's web interface. Enter `root` as the +username, leave the password field empty, and log in. Select the default +`_system` database. You should see the dashboard and be able to interact with +ArangoDB. + +If you want to delete your single server ArangoDB database, just run: + +```bash +minikube kubectl -- delete ArangoDeployment single-server +``` + +To shut down `minikube`, run: + +```bash +minikube stop +``` + +## See also + +- [Driver configuration](driver-configuration.md) +- [Scaling](scaling.md) +- [Upgrading](upgrading.md) +- [Using the ArangoDB Kubernetes Operator with Helm](helm.md)