diff --git a/README.md b/README.md index 1b390a5d..f1f029e8 100644 --- a/README.md +++ b/README.md @@ -20,396 +20,26 @@ Join us on the [#solr-operator](https://kubernetes.slack.com/messages/solr-opera ## Menu -- [Getting Started](#getting-started) - - [Solr Cloud](#running-a-solr-cloud) - - [Solr Collections](#solr-collections) - - [Solr Backups](#solr-backups) - - [Solr Metrics](#solr-prometheus-exporter) -- [Contributions](#contributions) +- [Documentation](#documentation) - [Version Compatibility and Upgrade Notes](#version-compatability--upgrade-notes) +- [Contributions](#contributions) - [License](#license) - [Code of Conduct](#code-of-conduct) - [Security Vulnerability Reporting](#security-vulnerability-reporting) -# Getting Started - -Install the Zookeeper & Etcd Operators, which this operator depends on by default. -Each is optional, as described in the [Zookeeper](#zookeeper-reference) section. - -```bash -$ kubectl apply -f example/dependencies -``` - -Install necessary dependencies for building and deploying the operator. -```bash -$ export PATH="$PATH:$GOPATH/bin" # You likely want to add this line to your ~/.bashrc or ~/.bash_aliases -$ ./hack/install_dependencies.sh -``` - -Install the Solr CRDs & Operator - -```bash -$ make install deploy -``` - -You can also deploy the Solr Operator by using our provided [Helm Chart](helm/solr-operator/README.md). - - -## Running a Solr Cloud - -### Creating - -Make sure that the solr-operator and a zookeeper-operator are running. - -Create an example Solr cloud, with the following configuration. - -```bash -$ cat example/test_solrcloud.yaml - -apiVersion: solr.bloomberg.com/v1beta1 -kind: SolrCloud -metadata: - name: example -spec: - replicas: 4 - solrImage: - tag: 8.1.1 -``` - -Apply it to your Kubernetes cluster. - -```bash -$ kubectl apply -f example/test_solrcloud.yaml -$ kubectl get solrclouds - -NAME VERSION DESIREDNODES NODES READYNODES AGE -example 8.1.1 4 2 1 2m - -$ kubectl get solrclouds - -NAME VERSION DESIREDNODES NODES READYNODES AGE -example 8.1.1 4 4 4 8m -``` - -### Scaling - -Increase the number of Solr nodes in your cluster. - -```bash -$ kubectl scale --replicas=5 solrcloud/example -``` - -### Deleting - -Decrease the number of Solr nodes in your cluster. - -```bash -$ kubectl delete solrcloud example -``` - -### Dependent Kubernetes Resources - -What actually gets created when the Solr Cloud is spun up? - -```bash -$ kubectl get all - -NAME READY STATUS RESTARTS AGE -pod/example-solrcloud-0 1/1 Running 7 47h -pod/example-solrcloud-1 1/1 Running 6 47h -pod/example-solrcloud-2 1/1 Running 0 47h -pod/example-solrcloud-3 1/1 Running 6 47h -pod/example-solrcloud-zk-0 1/1 Running 0 49d -pod/example-solrcloud-zk-1 1/1 Running 0 49d -pod/example-solrcloud-zk-2 1/1 Running 0 49d -pod/example-solrcloud-zk-3 1/1 Running 0 49d -pod/example-solrcloud-zk-4 1/1 Running 0 49d -pod/solr-operator-8449d4d96f-cmf8p 1/1 Running 0 47h -pod/zk-operator-674676769c-gd4jr 1/1 Running 0 49d - -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -service/example-solrcloud-0 ClusterIP ##.###.###.## 80/TCP 47h -service/example-solrcloud-1 ClusterIP ##.###.##.# 80/TCP 47h -service/example-solrcloud-2 ClusterIP ##.###.###.## 80/TCP 47h -service/example-solrcloud-3 ClusterIP ##.###.##.### 80/TCP 47h -service/example-solrcloud-common ClusterIP ##.###.###.### 80/TCP 47h -service/example-solrcloud-headless ClusterIP None 8983/TCP 47h -service/example-solrcloud-zk-client ClusterIP ##.###.###.### 21210/TCP 49d -service/example-solrcloud-zk-headless ClusterIP None 22210/TCP,23210/TCP 49d - -NAME READY UP-TO-DATE AVAILABLE AGE -deployment.apps/solr-operator 1/1 1 1 49d -deployment.apps/zk-operator 1/1 1 1 49d - -NAME DESIRED CURRENT READY AGE -replicaset.apps/solr-operator-8449d4d96f 1 1 1 2d1h -replicaset.apps/zk-operator-674676769c 1 1 1 49d - -NAME READY AGE -statefulset.apps/example-solrcloud 4/4 47h -statefulset.apps/example-solrcloud-zk 5/5 49d - -NAME HOSTS PORTS AGE -ingress.extensions/example-solrcloud-common default-example-solrcloud.test.domain,default-example-solrcloud-0.test.domain + 3 more... 80 2d2h - -NAME VERSION DESIREDNODES NODES READYNODES AGE -solrcloud.solr.bloomberg.com/example 8.1.1 4 4 4 47h -``` - -## Zookeeper Reference - -Solr Clouds require an Apache Zookeeper to connect to. - -The Solr operator gives a few options. - -**Note** - Both options below come with options to specify a `chroot`, or a ZNode path for solr to use as it's base "directory" in Zookeeper. Before the operator creates or updates a StatefulSet with a given `chroot`, it will first ensure that the given ZNode path exists and if it doesn't the operator will create all necessary ZNodes in the path. If no chroot is given, a default of `/` will be used, which doesn't require the existence check previously mentioned. If a chroot is provided without a prefix of `/`, the operator will add the prefix, as it is required by Zookeeper. - -### ZK Connection Info - -This is an external/internal connection string as well as an optional chRoot to an already running Zookeeeper ensemble. -If you provide an external connection string, you do not _have_ to provide an internal one as well. - -### Provided Instance - -If you do not require the Solr cloud to run cross-kube cluster, and do not want to manage your own Zookeeper ensemble, -the solr-operator can manage Zookeeper ensemble(s) for you. - -#### Zookeeper - -Using the [zookeeper-operator](https://github.com/pravega/zookeeper-operator), a new Zookeeper ensemble can be spun up for -each solrCloud that has this option specified. - -The startup parameter `zookeeper-operator` must be provided on startup of the solr-operator for this parameter to be available. - -#### Zetcd - -Using [etcd-operator](https://github.com/coreos/etcd-operator), a new Etcd ensemble can be spun up for each solrCloud that has this option specified. -A [Zetcd](https://github.com/etcd-io/zetcd) deployment is also created so that Solr can interact with Etcd as if it were a Zookeeper ensemble. - -The startup parameter `etcd-operator` must be provided on startup of the solr-operator for this parameter to be available. - -### Solr Collections - -Solr-operator can manage the creation, deletion and modification of Solr collections. - -Collection creation requires a Solr Cloud to apply against. Presently, SolrCollection supports both implicit and compositeId router types, with some of the basic configuration options including `autoAddReplicas`. - -Create an example set of collections against on the "example" solr cloud - -```bash -$ cat example/test_solrcollection.yaml - -apiVersion: solr.bloomberg.com/v1beta1 -kind: SolrCollection -metadata: - name: example-collection-1 -spec: - solrCloud: example - collection: example-collection - routerName: compositeId - autoAddReplicas: false - numShards: 2 - replicationFactor: 1 - maxShardsPerNode: 1 - collectionConfigName: "_default" ---- -apiVersion: solr.bloomberg.com/v1beta1 -kind: SolrCollection -metadata: - name: example-collection-2-compositeid-autoadd -spec: - solrCloud: example - collection: example-collection-2 - routerName: compositeId - autoAddReplicas: true - numShards: 2 - replicationFactor: 1 - maxShardsPerNode: 1 - collectionConfigName: "_default" ---- -apiVersion: solr.bloomberg.com/v1beta1 -kind: SolrCollection -metadata: - name: example-collection-3-implicit -spec: - solrCloud: example - collection: example-collection-3-implicit - routerName: implicit - autoAddReplicas: true - numShards: 2 - replicationFactor: 1 - maxShardsPerNode: 1 - shards: "fooshard1,fooshard2" - collectionConfigName: "_default" -``` - -```bash -$ kubectl apply -f examples/test_solrcollections.yaml -``` - -#### Solr Collection Alias - -The solr-operator supports the full lifecycle of standard aliases. Here is an example pointing an alias to 2 collections - -``` -apiVersion: solr.bloomberg.com/v1beta1 -kind: SolrCollectionAlias -metadata: - name: collection-alias-example -spec: - solrCloud: example - aliasType: standard - collections: - - example-collection-1 - - example-collection-2 -``` - -Aliases can be useful when migrating from one collection to another without having to update application endpoint configurations. - -Routed aliases are presently not supported - - -## Solr Backups - -Solr backups require 3 things: -- A solr cloud running in kubernetes to backup -- The list of collections to backup -- A shared volume reference that can be written to from many clouds - - This could be a NFS volume, a persistent volume claim (that has `ReadWriteMany` access), etc. - - The same volume can be used for many solr clouds in the same namespace, as the data stored within the volume is namespaced. -- A way to persist the data. The currently supported persistence methods are: - - A volume reference (this does not have to be `ReadWriteMany`) - - An S3 endpoint. - -Backups will be tarred before they are persisted. - -There is no current way to restore these backups, but that is in the roadmap to implement. - - -## Solr Prometheus Exporter - -Solr metrics can be collected from solr clouds/standalone solr both residing within the kubernetes cluster and outside. -To use the Prometheus exporter, the easiest thing to do is just provide a reference to a Solr instance. That can be any of the following: -- The name and namespace of the Solr Cloud CRD -- The Zookeeper connection information of the Solr Cloud -- The address of the standalone Solr instance - -You can also provide a custom Prometheus Exporter config, Solr version, and exporter options as described in the -[Solr ref-guide](https://lucene.apache.org/solr/guide/monitoring-solr-with-prometheus-and-grafana.html#command-line-parameters). - -Note that a few of the official Solr docker images do not enable the Prometheus Exporter. -Versions `6.6` - `7.x` and `8.2` - `master` should have the exporter available. - - -## Solr Images - -### Official Solr Images - -The solr-operator will work with any of the [official Solr images](https://hub.docker.com/_/solr) currently available. - -### Build Your Own Private Solr Images - -The solr-operator supports private Docker repo access for Solr images you may want to store in a private Docker repo. It is recommended to source your image from the official Solr images. - -Using a private image requires you have a K8s secret preconfigured with appropreiate access to the image. (type: kubernetes.io/dockerconfigjson) - -``` -apiVersion: solr.bloomberg.com/v1beta1 -kind: SolrCloud -metadata: - name: example-private-repo-solr-image -spec: - replicas: 3 - solrImage: - repository: myprivate-repo.jfrog.io/solr - tag: 8.2.0 - imagePullSecret: "k8s-docker-registry-secret" -``` - -## Solr Operator - -### Solr Operator Input Args - -* **-zookeeper-operator** Whether or not to use the Zookeeper Operator to create dependent Zookeeepers. - Required to use the `ProvidedZookeeper.Zookeeper` option within the Spec. - If _true_, then a Zookeeper Operator must be running for the cluster. - ( _true_ | _false_ , defaults to _false_) -* **-etcd-operator** Whether or not to use the Etcd Operator to create dependent Zetcd clusters. - Required to use the `ProvidedZookeeper.Zetcd` option within the Spec. - If _true_, then an Etcd Operator must be running for the cluster. - ( _true_ | _false_ , defaults to _false_) -* **-ingress-base-domain** If you desire to make solr externally addressable via ingresses, a base ingress domain is required. - Solr Clouds will be created with ingress rules at `*.(ingress-base-domain)`. - ( _optional_ , e.g. `ing.base.domain` ) -## Development - -### Before you create a PR - -The CRD should be updated anytime you update the API. - -```bash -$ make manifests -``` - -Beware that you must be running an updated version of `controller-gen`. To update to a compatible version, run: - -```bash -$ go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.2 -``` - -Make sure that you have updated the go.mod file: - -```bash -$ make mod-tidy -``` - -### Docker - -#### Docker Images - -Two Docker images are published to [DockerHub](https://hub.docker.com/r/bloomberg/solr-operator), both based off of the same base image. - -- [Builder Image](build/Dockerfile.build) - Downloads gomod dependencies, builds operator executable (This is not published, only used to build the following images) -- [Slim Image](build/Dockerfile.slim) - Contains only the operator executable -- [Vendor Image](build/Dockerfile.slim) - Contains the operator executable as well as all dependencies (at `/solr-operator-vendor-sources`) - -#### Building - -Building and releasing a test operator image with a custom Docker namespace. - -```bash -$ NAMESPACE=your-namespace/ make docker-build docker-push -``` - -You can test the vendor docker container by running - -```bash -$ NAMESPACE=your-namespace/ make docker-vendor-build docker-vendor-push -``` - -### Docker for Mac Local Development Setup - -#### Install and configure on Docker for Mac - -1. (Download and install latest stable version)[https://docs.docker.com/docker-for-mac/install/] -2. Enable K8s under perferences -3. Ensure you have kubectl installed on your Mac (if using Brew: `brew install kubernetes-cli` -3. Run through [Getting Started](#getting-started) -3. Install nginx-ingress configuration - -``` -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml -``` - -4. Ensure your /etc/hosts file is setup to use the ingress for your SolrCloud. Here is what you need if you name your SolrCloud 'example' with 3 replicas - -``` -127.0.0.1 localhost default-example-solrcloud.ing.local.domain ing.local.domain default-example-solrcloud-0.ing.local.domain default-example-solrcloud-1.ing.local.domain default-example-solrcloud-2.ing.local.domain dinghy-ping.localhost -``` +## Documentation -5. Navigate to your browser: http://default-example-solrcloud.ing.local.domain/solr/#/ to validate everything is working +Please visit the following pages for documentation on using and developing the Solr Operator: +- [Local Tutorial](docs/local_tutorial.md) +- [Running the Solr Operator](docs/running-the-operator.md) +- Available Solr Resources + - [Solr Clouds](docs/solr-cloud) + - [Solr Collections](docs/solr-collection) + - [Solr Backups](docs/solr-backup) + - [Solr Metrics](docs/solr-prometheus-exporter) + - [Solr Collection Aliases](docs/solr-collection-alias) +- [Development](docs/development.md) ## Version Compatibility & Upgrade Notes diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..0664b3fb --- /dev/null +++ b/docs/README.md @@ -0,0 +1,14 @@ +# Documentation + +Please visit the following pages for documentation on using and developing the Solr Operator: + +- [Local Tutorial](local_tutorial.md) +- [Running the Solr Operator](running-the-operator.md) +- Available Solr Resources + - [Solr Clouds](solr-cloud) + - [Solr Collections](solr-collection) + - [Solr Backups](solr-backup) + - [Solr Metrics](solr-prometheus-exporter) + - [Solr Collection Aliases](solr-collection-alias) +- [Development](development.md) +- [TODO: Architecture Overview](architecture-overview.md) \ No newline at end of file diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 00000000..6883637f --- /dev/null +++ b/docs/development.md @@ -0,0 +1,139 @@ +# Developing the Solr Operator + +This page details the steps for developing the Solr Operator, and all necessary steps to follow before creating a PR to the repo. + + - [Setup](#setup) + - [Setup Docker for Mac with K8S](#setup-docker-for-mac-with-k8s-with-an-ingress-controller) + - [Install the necessary Dependencies](#installing-the-necessary-dependencies) + - [Build the Solr CRDs](#build-the-solr-crds) + - [Build and Run the Solr Operator](#build-and-run-the-solr-operator) + - [Build the Solr Operator](#) + - [Running the Solr Operator](#R) + - [Steps to take before creating a PR](#before-you-create-a-pr) + +## Setup + +### Setup Docker for Mac with K8S with an Ingress Controller + +Please follow the instructions from the [local tutorial](local_tutorial.md#setup-docker-for-mac-with-k8s). + +### Install the necessary dependencies + +Install the Zookeeper & Etcd Operators, which this operator depends on by default. +Each is optional, as described in the [Zookeeper](#zookeeper-reference) section. + +```bash +$ kubectl apply -f example/dependencies +``` + +Install necessary dependencies for building and deploying the operator. +```bash +$ export PATH="$PATH:$GOPATH/bin" # You likely want to add this line to your ~/.bashrc or ~/.bash_aliases +$ ./hack/install_dependencies.sh +``` + +Beware that you must be running an updated version of `controller-gen`. To update to a compatible version, run: + +```bash +$ go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.2 +``` + +## Build the Solr CRDs + +If you have changed anything in the [APIs directory](/api/v1beta1), you will need to run the following command to regenerate all Solr CRDs. + +```bash +$ make manifests +``` + +In order to apply these CRDs to your kube cluster, merely run the following: + +```bash +$ make install +``` + +## Build and Run local versions + +It is very useful to build and run your local version of the operator to test functionality. + +### Building the Solr Operator + +#### Building a Go binary + +Building the Go binary files is quite straightforward: + +```bash +$ go build +``` + +This is useful for testing that your code builds correctly, as well as using the `make run` command detailed below. + +#### Building the Docker image + +Building and releasing a test operator image with a custom Docker namespace. + +```bash +$ NAMESPACE=your-namespace/ make docker-build docker-push +``` + +You can test the vendor docker container by running + +```bash +$ NAMESPACE=your-namespace/ make docker-vendor-build docker-vendor-push +``` + +You can control the namespace and version for your solr-operator docker image via the ENV variables: +- `NAMESPACE`, defaults to `bloomberg/`. **This must end with a forward slash.** This can also include the docker repository information for private repos. +- `NAME`, defaults to `solr-operator`. +- `VERSION`, defaults to the git HEAD tag. (e.g. `v0.2.5-1-g06f4e2a`). +You can check what version you are using by running `make version`. + +The image will be created under the tag `$(NAMESPACE)$(NAME):$(VERSION)` as well as `$(NAMESPACE)$(NAME):latest`. + + +### Running the Solr Operator + +There are a few options for running the Solr Operator version you are developing. + +- You can deploy the Solr Operator by using our provided [Helm Chart](/helm/solr-operator/README.md). +You will need to [build a docker image](#building-the-docker-image) for your version of the operator. +Then update the values for the helm chart to use the version that you have built. +- There are two useful `make` commands provided to help with running development versions of the operator: + - `make run` - This command will start the solr-operator process locally (not within kubernetes). + This does not require building a docker image. + - `make deploy` - This command will apply the docker image with your local version to your kubernetes cluster. + This requires [building a docker image](#building-the-docker-image). + +**Warning**: If you are running kubernetes locally and do not want to push your image to docker hub or a private repository, you will need to set the `imagePullPolicy: Never` on your Solr Operator Deployment. +That way Kubernetes does not try to pull your image from whatever repo it is listed under (or docker hub by default). + +## Testing + +If you are creating new functionality for the operator, please include that functionality in an existing test or a new test before creating a PR. +Most tests can be found in the [controller](/controllers) directory, with names that end in `_test.go`. + +PRs will automatically run the unit tests, and will block merging if the tests fail. + +You can run these tests locally via the following make command: + +```bash +$ make test +``` + +## Before you create a PR + +The CRD should be updated anytime you update the API. + +```bash +$ make manifests +``` + + +Make sure that you have updated the go.mod file: + +```bash +$ make mod-tidy +``` + +Finally, as mentioned on the Repo's README, you will need to sign all commits included in the PR. +More information can be found on the [organization's contibutions documentation](https://github.com/bloomberg/.github/blob/master/CONTRIBUTING.md#contribution-licensing). \ No newline at end of file diff --git a/docs/local_tutorial.md b/docs/local_tutorial.md new file mode 100644 index 00000000..d0d1cfe8 --- /dev/null +++ b/docs/local_tutorial.md @@ -0,0 +1,233 @@ +# Solr on Kubernetes on local Mac + +This tutorial shows how to setup Solr under Kubernetes on your local mac. The plan is as follows: + + 1. [Setup Docker for Mac with K8S](#setup-docker-for-mac-with-k8s) + 2. [Install an Ingress Controller to reach the cluster on localhost](#install-an-ingress-controller) + 3. [Install Solr Operator](#install-solr-operator) + 4. [Start your Solr cluster](#start-your-solr-cluster) + 5. [Create a collection and index some documents](#create-a-collection-and-index-some-documents) + 6. [Scale from 3 to 5 nodes](#scale-from-3-to-5-nodes) + 7. [Upgrade to newer Solr version](#upgrade-to-newer-version) + 8. [Install Kubernetes Dashboard (optional)](#install-kubernetes-dashboard-optional) + 9. [Delete the solrCloud cluster named 'example'](#delete-the-solrcloud-cluster-named-example) + +## Setup Docker for Mac with K8S + +```bash +# Install Homebrew, if you don't have it already +/bin/bash -c "$(curl -fsSL \ + https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" + +# Install Docker Desktop for Mac (use edge version to get latest k8s) +brew cask install docker-edge + +# Enable Kubernetes in Docker Settings, or run the command below: +sed -i -e 's/"kubernetesEnabled" : false/"kubernetesEnabled" : true/g' \ + ~/Library/Group\ Containers/group.com.docker/settings.json + +# Start Docker for mac from Finder, or run the command below +open /Applications/Docker.app + +# Install Helm, which we'll use to install the operator, and 'watch' +brew install helm watch +``` + +## Install an Ingress Controller + +Kubernetes services are by default only accessible from within the k8s cluster. To make them adressable from our laptop, we'll add an ingress controller + +```bash +# Install the nginx ingress controller +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml + +# Inspect that the ingress controller is running by visiting the Kubernetes dashboard +# and selecting namespace `ingress-nginx`, or running this command: +kubectl get all --namespace ingress-nginx + +# Edit your /etc/hosts file (`sudo vi /etc/hosts`) and replace the 127.0.0.1 line with: +127.0.0.1 localhost default-example-solrcloud.ing.local.domain ing.local.domain default-example-solrcloud-0.ing.local.domain default-example-solrcloud-1.ing.local.domain default-example-solrcloud-2.ing.local.domain dinghy-ping.localhost +``` + +Once we have installed Solr to our k8s, this will allow us to address the nodes locally. + +## Install Solr Operator + +Now that we have the prerequisites setup, let us install Solr Operator which will let us easily manage a large Solr cluster: + +```bash +# Download the operator +OPERATOR_VER=0.2.5 +curl https://codeload.github.com/bloomberg/solr-operator/tar.gz/v$OPERATOR_VER | tar xz +ln -s -f solr-operator-$OPERATOR_VER solr-operator + +# Install the Zookeeper operator (and etcd operator even if we don't use it) +kubectl apply -f solr-operator/example/dependencies/ + +# Install the operator (specifying ingressBaseDomain to match our ingressController) +helm install --set-string ingressBaseDomain=ing.local.domain \ + solr-operator solr-operator/helm/solr-operator +``` + +After installing, you can check to see what lives in the cluster to make sure that the Solr and ZooKeeper operators have started correctly. +``` +$ kubectl get all + +NAME READY STATUS RESTARTS AGE +pod/solr-operator-8449d4d96f-cmf8p 1/1 Running 0 47h +pod/zk-operator-674676769c-gd4jr 1/1 Running 0 49d + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/solr-operator 1/1 1 1 49d +deployment.apps/zk-operator 1/1 1 1 49d + +NAME DESIRED CURRENT READY AGE +replicaset.apps/solr-operator-8449d4d96f 1 1 1 2d1h +replicaset.apps/zk-operator-674676769c 1 1 1 49d +``` + +After inspecting the status of you Kube cluster, you should see a deployment for the Solr Operator as well as the Zookeeper Operator. + +## Start an example Solr Cloud cluster + +To start a Solr Cloud cluster, we will create a yaml that will tell the Solr Operator what version of Solr Cloud to run, and how many nodes, with how much memory etc. + +```bash +# Create a spec for a 3-node cluster v8.3 with 300m RAM each: +cat < solrCloud-example.yaml +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCloud +metadata: + name: example +spec: + replicas: 3 + solrImage: + tag: "8.3" + solrJavaMem: "-Xms300m -Xmx300m" +EOF + +# Install Solr from that spec +kubectl apply -f solrCloud-example.yaml + +# The solr-operator has created a new resource type 'solrclouds' which we can query +# Check the status live with the 'watch' command. Hit Control-C when done +watch -dc kubectl get solrclouds + +# Open a web browser to see a solr node: +# Note that this is the service level, so will round-robin between the nodes +open "http://default-example-solrcloud.ing.local.domain/solr/#/~cloud?view=nodes" +``` + +## Create a collection and index some documents + +We'll use the Operator's built in collection creation option + +```bash +# Create the spec +cat < collection.yaml +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCollection +metadata: + name: mycoll +spec: + solrCloud: example + collection: mycoll + autoAddReplicas: true + routerName: compositeId + numShards: 1 + replicationFactor: 3 + maxShardsPerNode: 2 + collectionConfigName: "_default" +EOF + +# Execute the command and check in Admin UI that it succeeds +kubectl apply -f collection.yaml + +# Check in Admin UI that collection is created +open "http://default-example-solrcloud.ing.local.domain/solr/#/~cloud?view=graph" +``` + +Now index some documents into the empty collection. +```bash +curl -XPOST -H "Content-Type: application/json" \ + -d '[{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}, {id: 7}, {id: 8}]' \ + "http://default-example-solrcloud.ing.local.domain/solr/mycoll/update/" +``` + +## Scale from 3 to 5 nodes + +So we wish to add more capacity. Scaling the cluster is a breeze. + +``` +# Issue the scale command +kubectl scale --replicas=5 solrcloud/example +``` + +After issuing the scale command, start hitting the "Refresh" button in the Admin UI. +You will see how the new Solr nodes are added. +You can also watch the status via the `kubectl get solrclouds` command: + +```bash +watch -dc kubectl get solrclouds + +# Hit Control-C when done +``` + +## Upgrade to newer version + +So we wish to upgrade to a newer Solr version: + +``` +# Take note of the current version, which is 8.3.1 +curl -s http://default-example-solrcloud.ing.local.domain/solr/admin/info/system | grep solr-i + +# Update the solrCloud configuratin with the new version, keeping 5 nodes +cat < solrCloud-example.yaml +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCloud +metadata: + name: example +spec: + replicas: 5 + solrImage: + tag: "8.4" + solrJavaMem: "-Xms300m -Xmx300m" +EOF + +# Apply the new config +# Click the 'Show all details" button in Admin UI and start hitting the "Refresh" button +# See how the operator upgrades one pod at a time. Solr version is in the 'node' column +# You can also watch the status with the 'kubectl get solrclouds' command +kubectl apply -f solrCloud-example.yaml +watch -dc kubectl get solrclouds + +# Hit Control-C when done +``` + +## Install Kubernetes Dashboard (optional) + +Kubernetes Dashboard is a web interface that gives a better overview of your k8s cluster than only running command-line commands. This step is optional, you don't need it if you're comfortable with the cli. + +``` +# Install the Dashboard +kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml + +# You need to authenticate with the dashboard. Get a token: +kubectl -n kubernetes-dashboard describe secret \ + $(kubectl -n kubernetes-dashboard get secret | grep default-token | awk '{print $1}') \ + | grep "token:" | awk '{print $2}' + +# Start a kube-proxy in the background (it will listein on localhost:8001) +kubectl proxy & + +# Open a browser to the dashboard (note, this is one long URL) +open "http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/overview?namespace=default" + +# Select 'Token' in the UI and paste the token from last step (starting with 'ey...') +``` + +## Delete the solrCloud cluster named 'example' + +``` +kubectl delete solrcloud example +``` \ No newline at end of file diff --git a/docs/running-the-operator.md b/docs/running-the-operator.md new file mode 100644 index 00000000..b5a8daba --- /dev/null +++ b/docs/running-the-operator.md @@ -0,0 +1,70 @@ +# Running the Solr Operator + +## Using the Solr Operator Helm Chart + +The easiest way to run the Solr Operator is via the [provided Helm Chart](/helm/solr-operator). + +The helm chart provides abstractions over the Input Arguments described below, and should work with any official images in docker hub. + +### How to install via Helm + +Currently you need a local version of the Helm chart downloaded before you can install the operator. + +```bash +# Download the operator +OPERATOR_VER=0.2.5 +curl https://codeload.github.com/bloomberg/solr-operator/tar.gz/v$OPERATOR_VER | tar xz +ln -s -f solr-operator-$OPERATOR_VER solr-operator + +# Install the Zookeeper operator (and etcd operator even if we don't use it) +kubectl apply -f solr-operator/example/dependencies/ + +# Install the operator (specifying ingressBaseDomain to match our ingressController) +helm install --set-string ingressBaseDomain=ing.local.domain \ + solr-operator solr-operator/helm/solr-operator +``` + +After installing, you can check to see what lives in the cluster to make sure that the Solr and ZooKeeper operators have started correctly. +``` +$ kubectl get all + +NAME READY STATUS RESTARTS AGE +pod/solr-operator-8449d4d96f-cmf8p 1/1 Running 0 47h +pod/zk-operator-674676769c-gd4jr 1/1 Running 0 49d + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/solr-operator 1/1 1 1 49d +deployment.apps/zk-operator 1/1 1 1 49d + +NAME DESIRED CURRENT READY AGE +replicaset.apps/solr-operator-8449d4d96f 1 1 1 2d1h +replicaset.apps/zk-operator-674676769c 1 1 1 49d +``` + +After inspecting the status of you Kube cluster, you should see a deployment for the Solr Operator as well as the Zookeeper Operator. + +## Solr Operator Docker Images + +Two Docker images are published to [DockerHub](https://hub.docker.com/r/bloomberg/solr-operator), both based off of the same base image. + +- [Builder Image](build/Dockerfile.build) - Downloads gomod dependencies, builds operator executable (This is not published, only used to build the following images) +- [Slim Image](build/Dockerfile.slim) - Contains only the operator executable, with the operator as the entry point +- [Vendor Image](build/Dockerfile.slim) - Contains the operator executable as well as all dependencies (at `/solr-operator-vendor-sources`) + +In order to run the Solr Operator, you will only need the Slim Image. + +## Solr Operator Input Args + +* **-zookeeper-operator** Whether or not to use the Zookeeper Operator to create dependent Zookeeepers. + Required to use the `ProvidedZookeeper.Zookeeper` option within the Spec. + If _true_, then a Zookeeper Operator must be running for the cluster. + ( _true_ | _false_ , defaults to _false_) +* **-etcd-operator** Whether or not to use the Etcd Operator to create dependent Zetcd clusters. + Required to use the `ProvidedZookeeper.Zetcd` option within the Spec. + If _true_, then an Etcd Operator must be running for the cluster. + ( _true_ | _false_ , defaults to _false_) +* **-ingress-base-domain** If you desire to make solr externally addressable via ingresses, a base ingress domain is required. + Solr Clouds will be created with ingress rules at `*.(ingress-base-domain)`. + ( _optional_ , e.g. `ing.base.domain` ) + + \ No newline at end of file diff --git a/docs/solr-backup/README.md b/docs/solr-backup/README.md new file mode 100644 index 00000000..3cd6a29d --- /dev/null +++ b/docs/solr-backup/README.md @@ -0,0 +1,15 @@ +# Solr Backups + +Solr backups require 3 things: +- A solr cloud running in kubernetes to backup +- The list of collections to backup +- A shared volume reference that can be written to from many clouds + - This could be a NFS volume, a persistent volume claim (that has `ReadWriteMany` access), etc. + - The same volume can be used for many solr clouds in the same namespace, as the data stored within the volume is namespaced. +- A way to persist the data. The currently supported persistence methods are: + - A volume reference (this does not have to be `ReadWriteMany`) + - An S3 endpoint. + +Backups will be tarred before they are persisted. + +There is no current way to restore these backups, but that is in the roadmap to implement. diff --git a/docs/solr-cloud/README.md b/docs/solr-cloud/README.md new file mode 100644 index 00000000..0c85b477 --- /dev/null +++ b/docs/solr-cloud/README.md @@ -0,0 +1,103 @@ +# Solr Clouds + +The Solr Operator supports creating and managing Solr Clouds. + +A reference on the available options for the SolrCloud CRD can be found [here](solr-cloud-crd.md). + +This page outlines how to create, update and delete a SolrCloud in Kubernetes. + +- [Creation](#creating-an-example-solrcloud) +- [Scaling](#scaling-a-solrcloud) +- [Deletion](#deleting-the-example-solrcloud) +- [Solr Images](#solr-images) + - [Official Images](#official-solr-images) + - [Custom Images](#build-your-own-private-solr-images) + +## Creating an example SolrCloud + +Make sure that the solr-operator and a zookeeper-operator are running. + +Create an example Solr cloud, with the following configuration. + +```bash +$ cat example/test_solrcloud.yaml + +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCloud +metadata: + name: example +spec: + replicas: 4 + solrImage: + tag: 8.1.1 +``` + +Apply it to your Kubernetes cluster. + +```bash +$ kubectl apply -f example/test_solrcloud.yaml +$ kubectl get solrclouds + +NAME VERSION DESIREDNODES NODES READYNODES AGE +example 8.1.1 4 2 1 2m + +$ kubectl get solrclouds + +NAME VERSION DESIREDNODES NODES READYNODES AGE +example 8.1.1 4 4 4 8m +``` + +What actually gets created when you start a Solr Cloud though? +Refer to the [dependencies outline](dependencies.md) to see what dependent Kuberenetes resources are created in order to run a Solr Cloud. + +## Scaling a SolrCloud + +The SolrCloud CRD support the Kubernetes `scale` operation, to increase and decrease the number of Solr Nodes that are running within the cloud. + +``` +# Issue the scale command +kubectl scale --replicas=5 solrcloud/example +``` + +After issuing the scale command, start hitting the "Refresh" button in the Admin UI. +You will see how the new Solr nodes are added. +You can also watch the status via the `kubectl get solrclouds` command: + +```bash +watch -dc kubectl get solrclouds + +# Hit Control-C when done +``` + +### Deleting the example SolrCloud + +Delete the example SolrCloud + +```bash +$ kubectl delete solrcloud example +``` + +## Solr Images + +### Official Solr Images + +The solr-operator will work with any of the [official Solr images](https://hub.docker.com/_/solr) currently available. + +### Build Your Own Private Solr Images + +The solr-operator supports private Docker repo access for Solr images you may want to store in a private Docker repo. It is recommended to source your image from the official Solr images. + +Using a private image requires you have a K8s secret preconfigured with appropriate access to the image. (type: kubernetes.io/dockerconfigjson) + +``` +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCloud +metadata: + name: example-private-repo-solr-image +spec: + replicas: 3 + solrImage: + repository: myprivate-repo.jfrog.io/solr + tag: 8.2.0 + imagePullSecret: "k8s-docker-registry-secret" +``` \ No newline at end of file diff --git a/docs/solr-cloud/dependencies.md b/docs/solr-cloud/dependencies.md new file mode 100644 index 00000000..66d9499d --- /dev/null +++ b/docs/solr-cloud/dependencies.md @@ -0,0 +1,48 @@ +## Dependent Kubernetes Resources + +What actually gets created when the Solr Cloud is spun up? + +```bash +$ kubectl get all + +NAME READY STATUS RESTARTS AGE +pod/example-solrcloud-0 1/1 Running 7 47h +pod/example-solrcloud-1 1/1 Running 6 47h +pod/example-solrcloud-2 1/1 Running 0 47h +pod/example-solrcloud-3 1/1 Running 6 47h +pod/example-solrcloud-zk-0 1/1 Running 0 49d +pod/example-solrcloud-zk-1 1/1 Running 0 49d +pod/example-solrcloud-zk-2 1/1 Running 0 49d +pod/example-solrcloud-zk-3 1/1 Running 0 49d +pod/example-solrcloud-zk-4 1/1 Running 0 49d +pod/solr-operator-8449d4d96f-cmf8p 1/1 Running 0 47h +pod/zk-operator-674676769c-gd4jr 1/1 Running 0 49d + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/example-solrcloud-0 ClusterIP ##.###.###.## 80/TCP 47h +service/example-solrcloud-1 ClusterIP ##.###.##.# 80/TCP 47h +service/example-solrcloud-2 ClusterIP ##.###.###.## 80/TCP 47h +service/example-solrcloud-3 ClusterIP ##.###.##.### 80/TCP 47h +service/example-solrcloud-common ClusterIP ##.###.###.### 80/TCP 47h +service/example-solrcloud-headless ClusterIP None 8983/TCP 47h +service/example-solrcloud-zk-client ClusterIP ##.###.###.### 21210/TCP 49d +service/example-solrcloud-zk-headless ClusterIP None 22210/TCP,23210/TCP 49d + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/solr-operator 1/1 1 1 49d +deployment.apps/zk-operator 1/1 1 1 49d + +NAME DESIRED CURRENT READY AGE +replicaset.apps/solr-operator-8449d4d96f 1 1 1 2d1h +replicaset.apps/zk-operator-674676769c 1 1 1 49d + +NAME READY AGE +statefulset.apps/example-solrcloud 4/4 47h +statefulset.apps/example-solrcloud-zk 5/5 49d + +NAME HOSTS PORTS AGE +ingress.extensions/example-solrcloud-common default-example-solrcloud.test.domain,default-example-solrcloud-0.test.domain + 3 more... 80 2d2h + +NAME VERSION DESIREDNODES NODES READYNODES AGE +solrcloud.solr.bloomberg.com/example 8.1.1 4 4 4 47h +``` \ No newline at end of file diff --git a/docs/solr-cloud/solr-cloud-crd.md b/docs/solr-cloud/solr-cloud-crd.md new file mode 100644 index 00000000..ace75c56 --- /dev/null +++ b/docs/solr-cloud/solr-cloud-crd.md @@ -0,0 +1,36 @@ +# The SolrCloud CRD + +The SolrCloud CRD allows users to spin up a Solr cloud in a very configurable way. +Those configuration options are layed out on this page. + +## Zookeeper Reference + +Solr Clouds require an Apache Zookeeper to connect to. + +The Solr operator gives a few options. + +**Note** - Both options below come with options to specify a `chroot`, or a ZNode path for solr to use as it's base "directory" in Zookeeper. Before the operator creates or updates a StatefulSet with a given `chroot`, it will first ensure that the given ZNode path exists and if it doesn't the operator will create all necessary ZNodes in the path. If no chroot is given, a default of `/` will be used, which doesn't require the existence check previously mentioned. If a chroot is provided without a prefix of `/`, the operator will add the prefix, as it is required by Zookeeper. + +### ZK Connection Info + +This is an external/internal connection string as well as an optional chRoot to an already running Zookeeeper ensemble. +If you provide an external connection string, you do not _have_ to provide an internal one as well. + +### Provided Instance + +If you do not require the Solr cloud to run cross-kube cluster, and do not want to manage your own Zookeeper ensemble, +the solr-operator can manage Zookeeper ensemble(s) for you. + +#### Zookeeper + +Using the [zookeeper-operator](https://github.com/pravega/zookeeper-operator), a new Zookeeper ensemble can be spun up for +each solrCloud that has this option specified. + +The startup parameter `zookeeper-operator` must be provided on startup of the solr-operator for this parameter to be available. + +#### Zetcd + +Using [etcd-operator](https://github.com/coreos/etcd-operator), a new Etcd ensemble can be spun up for each solrCloud that has this option specified. +A [Zetcd](https://github.com/etcd-io/zetcd) deployment is also created so that Solr can interact with Etcd as if it were a Zookeeper ensemble. + +The startup parameter `etcd-operator` must be provided on startup of the solr-operator for this parameter to be available. diff --git a/docs/solr-collection-alias/README.md b/docs/solr-collection-alias/README.md new file mode 100644 index 00000000..708cddde --- /dev/null +++ b/docs/solr-collection-alias/README.md @@ -0,0 +1,20 @@ +# Solr Collection Alias + +The solr-operator supports the full lifecycle of standard aliases. Here is an example pointing an alias to 2 collections + +``` +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCollectionAlias +metadata: + name: collection-alias-example +spec: + solrCloud: example + aliasType: standard + collections: + - example-collection-1 + - example-collection-2 +``` + +Aliases can be useful when migrating from one collection to another without having to update application endpoint configurations. + +Routed aliases are presently not supported \ No newline at end of file diff --git a/docs/solr-collection/README.md b/docs/solr-collection/README.md new file mode 100644 index 00000000..5207191c --- /dev/null +++ b/docs/solr-collection/README.md @@ -0,0 +1,58 @@ +# Solr Collections + +Solr-operator can manage the creation, deletion and modification of Solr collections. + +Collection creation requires a Solr Cloud to apply against. Presently, SolrCollection supports both implicit and compositeId router types, with some of the basic configuration options including `autoAddReplicas`. + +Create an example set of collections against on the "example" solr cloud + +```bash +$ cat example/test_solrcollection.yaml + +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCollection +metadata: + name: example-collection-1 +spec: + solrCloud: example + collection: example-collection + routerName: compositeId + autoAddReplicas: false + numShards: 2 + replicationFactor: 1 + maxShardsPerNode: 1 + collectionConfigName: "_default" +--- +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCollection +metadata: + name: example-collection-2-compositeid-autoadd +spec: + solrCloud: example + collection: example-collection-2 + routerName: compositeId + autoAddReplicas: true + numShards: 2 + replicationFactor: 1 + maxShardsPerNode: 1 + collectionConfigName: "_default" +--- +apiVersion: solr.bloomberg.com/v1beta1 +kind: SolrCollection +metadata: + name: example-collection-3-implicit +spec: + solrCloud: example + collection: example-collection-3-implicit + routerName: implicit + autoAddReplicas: true + numShards: 2 + replicationFactor: 1 + maxShardsPerNode: 1 + shards: "fooshard1,fooshard2" + collectionConfigName: "_default" +``` + +```bash +$ kubectl apply -f examples/test_solrcollections.yaml +``` \ No newline at end of file diff --git a/docs/solr-prometheus-exporter/README.md b/docs/solr-prometheus-exporter/README.md new file mode 100644 index 00000000..287237a1 --- /dev/null +++ b/docs/solr-prometheus-exporter/README.md @@ -0,0 +1,13 @@ +# Solr Prometheus Exporter + +Solr metrics can be collected from solr clouds/standalone solr both residing within the kubernetes cluster and outside. +To use the Prometheus exporter, the easiest thing to do is just provide a reference to a Solr instance. That can be any of the following: +- The name and namespace of the Solr Cloud CRD +- The Zookeeper connection information of the Solr Cloud +- The address of the standalone Solr instance + +You can also provide a custom Prometheus Exporter config, Solr version, and exporter options as described in the +[Solr ref-guide](https://lucene.apache.org/solr/guide/monitoring-solr-with-prometheus-and-grafana.html#command-line-parameters). + +Note that a few of the official Solr docker images do not enable the Prometheus Exporter. +Versions `6.6` - `7.x` and `8.2` - `master` should have the exporter available. \ No newline at end of file