In order to start working with the Couchbase Operator you first need to install Kubernetes. Kubernetes-IN-Docker (KIND) is used for all CI and generally recommended during development. To install KIND follow the official instructions. It has the benefit of allowing running multiple clusters and each can be configured independently with different versions of K8S or other settings.
You will need the following from your favorite package manager:
-
go (1.22.0+)
-
git
-
git-review
-
make
-
docker
Ensure docker is allocated a decent amount of RAM as it defaults to 2GB for some reason, suggest 8GB+: https://kind.sigs.k8s.io/docs/user/quick-start#settings-for-docker-desktop
|
Note
|
Although not needed, we recommend 4 VCPUs and 8 GiB of RAM. When running acceptance tests it’s not uncommon to see up to 8 containers running and Couchbase Server does use a lot of processing power to rebalance. |
Here is an example of using the Brew package manager for macOS. This also sets up an IDE (Visual Studio Code in this case) along with supporting tooling for linting and using Helm charts. Each line is intended to cover a particular aspect (e.g. code then test) to make it clearer in case you want to use other tools.
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew doctor
$ brew install git python repo cmake ccache git-review go@1.22 make
$ brew install --cask docker
$ brew install kind kubectl helm
$ brew install --cask visual-studio-code
$ brew install asciidoc aspell node
$ python3 -m pip install -r scripts/requirements.txtMake sure to explicitly start the graphical elements above (docker particularly) to cover all credentials and permissions.
Ensure docker is allocated a decent amount of RAM as it defaults to 2GiB for some reason currently which will not be enough, suggest 8GiB+: https://kind.sigs.k8s.io/docs/user/quick-start#settings-for-docker-desktop
Ensure you have set up your SSH keys, the GitHub documentation covers it reasonably well. Since we’ll primarily be working with gerrit, ensure your local ssh agent’s config file has the following in addition to github.com host.
Host review.couchbase.org
AddKeysToAgent yes
IdentityFile ~/.ssh/git_ssh_couchbaseTo work with the code, you will need to do the following:
-
Create ssh keys (used for Gerrit authentication) and add to Gerrit.
-
Ensure Gerrit is set up with your email address used by git configuration.
-
Get an account on Gerrit for the
couchbase-operatorrepository (raise a CBIT or contact Couchbase) - this requires addition of the user to theNorthScalegroup. -
Have
gitandgit-reviewinstalled.
Once complete you can clone the repository and ready it for code review.
|
Important
|
Your Depending on your username vs your Couchbase/machine login/git id the git review step may need some additional input.
For example if your local username is $ git config --global user.name "<firstname> <lastname>"
$ git config --global user.email "<email address>"
$ git config --global --add gitreview.username "<gerrit username>" |
Be aware that to build the code you need a certain path structure for the code generator make rules to function.
$ mkdir -p github.com/couchbase
$ git clone ssh://<gerrit username>@review.couchbase.org:29418/couchbase-operator.git github.com/couchbase/couchbase-operator
$ cd github.com/couchbase/couchbase-operator
$ gitdir=$(git rev-parse --git-dir); scp -p -P 29418 -O <gerrit username>@review.couchbase.org:hooks/commit-msg ${gitdir}/hooks/
$ git review -sYour work flow is entirely up to you however we recommend the following process.
-
Before doing anything create an issue in Jira so we have an ID for simple tracking e.g. K8S-836.
-
Create a feature branch
git checkout -b k8s_836_my_change master. -
Do your work and test it.
-
Commit the code with a message in the form:
K8S-836: What My Change Does A detailed description of WHAT you are changing and WHY. The width of lines should be kept to below 80 characters as Gerrit won't display it very nicely otherwise. Some clever editors will automatically do word wrap for you e.g. vim. -
Submit your change to Gerrit
git review(use-Rto prevent automatic rebase). -
To update your patch set do your changes and amend
git commit --amendthen review withgit reviewpreserving theChange-IDwhich was automatically added by the prior commit.
Run make command to build the container images.
$ make imagesThe various make targets are documented below.
| Command | Description |
|---|---|
|
Build all binaries (required to run tests, must pass). |
|
Build docker images ( |
|
Runs unit tests (must pass). |
|
Checks for code standards, style and bugs (must pass). |
|
Detects doc changes and auto-generates Asciidoc from code. |
|
Command used by CI to ensure you’ve auto-generated, checked in, spellchecked and the links aren’t broken (must pass). |
|
Checks all python scripts are standard, not broken and not dubious (must pass). |
You should see something similar to the following with the docker images command.
The make file will automatically tag the image with something sane.
REPOSITORY TAG IMAGE ID CREATED SIZE
couchbase/couchbase-operator-certification v1 c825c3d17788 13 days ago 479MB
couchbase/couchbase-operator-admission v1 375316d73a6e 13 days ago 45.8MB
couchbase/couchbase-operator v1 90a8c4e7a26a 13 days ago 50.4MB|
Note
|
Make sure you tag your container image with something other than ‘latest’ and use that tag while you pull the image.
Otherwise, if you do not specify version of your image, it will be assumed as |
Install the following:
-
kind -
kubectl
Create a cluster: kind create cluster
You need to poke local docker images into kind, if the images are already in the public internet (e.g. DockerHub) you can skip this although it will speed things up and prevent hitting rate limits for pulling from those remote registries.
$ make # create the tools
$ make kind-images # create and install the container imagesNot strictly required but improves caching performance - replace with the server version you want to test.
$ docker pull couchbase/server:7.0.3
$ kind load docker-image couchbase/server:7.0.3It may be helpful to make an alias in your bashrc (or similar profile script - default shell on macOS seems to be ZSH so in the .zshrc) file:
|
Note
|
Depending on your OS, you will need to change the cao path and image tags for the alias. The cao path will start with |
$ alias test-couchbase='./build/bin/<cao path>/cao certify --image couchbase/couchbase-operator-certification:<certification tag> --clean --parallel=1 -- -operator-image couchbase/couchbase-operator:<operator tag> -admission-image couchbase/couchbase-admission-controller:<admission controller tag>'Then you can run some common commands to get you started:
$ test-couchbase -test TestCreateCluster
$ test-couchbase -suite sanityNote that arguments can be passed to the certification binary (cao) before the --, and arguments following it are passed to the underlying test framework.
All available arguments for the cao binary can be found in pkg/certification/certify.go.
All available arguments for the test framework can be found in test/e2e/framework/framework.go.
-
When you submit code, it must be tested sufficiently, either with a unit test or a full-on integration test.
-
When you write a test it must always pass, if it doesn’t and you think it’s a bug, talk to development and submit a fix with the test!
-
Tests should be stable, tests should pass, if they don’t then it just wastes time across the team analyzing the same issues over and over again.
To gather logs from tests, add the --collect-logs flag to your test command.
$ test-couchbase -suite p0 --collect-logsTest runs will place the results of the test run in the base directory, in an archive called couchbase-operator-certification-<TIMESTAMP>.tar.bz2.
Inside there is an artifacts folder, containing the test results.xml and logs folder with logs for every test, plus a cbopinfo archive for any failed test.
You can unzip this with tar -xf <FILE>, and view an individual instances logs via ./namespace/pod/<PODNAME>/
Logify can be used to pull apart the logs collected via cbopinfo.
The assumption is that you have branched from the right upstream branch.
Note if you branch from master then this is unlikely to be correct for the specific version you are targeting.
You may need to re-base from the version you want and also trigger Gerrit to do it:
$ git rebase --onto origin/2.1.x HEAD~ <your branch name>
$ git review 2.1.xThis will target the 2.1.x release.
Similarly to cherry pick changes already submitted from another change set:
$ git checkout -b test origin/2.1.x
$ git cherry-pick <hash>
$ git review 2.1.xTo verify documentation updates a special container can be used which will process it all and serve it locally for you to verify.
$ docker run --rm -ti \
--publish 8080:80 \
--mount type=bind,source=${PWD},target=/src,readonly \
spjmurray/couchbase-antora-preview:latest
2021-11-11 13:50:01.513 INFO Using default repo path /src
2021-11-11 13:50:01.768 INFO Using branch k8s_2520_add_contribution_documentation
2021-11-11 13:50:03.522 INFO Using path ./docs/user
2021-11-11 13:50:03.526 INFO Cloning latest document repository ...
2021-11-11 13:50:07.495 INFO Creating site playbook ...
2021-11-11 13:50:07.552 INFO Generating static content ...
2021-11-11 13:50:16.679 INFO Serving content on http://localhost:8080
2021-11-11 13:50:16.686 INFO Serving repo content on http://localhost:8080/operator/2.3/overview.html
2021-11-11 13:50:16.686 INFO Starting webserver ...
2021-11-11 13:50:17.094 INFO Press Ctl+C to exit ...As you can see it shows you where to go to view the generated documentation. Make sure to change port 8080 if it is already in use locally.
You can set up a set of related changes in Gerrit all under the same topic like so.
-
Create a new branch from where you want the next changeset in the relation chain to start from
-
Make your changes
-
Commit but when triggering a review specify the same topic to use, otherwise it will use the branch name.
When it hits Gerrit, your change will be automatically reviewed by a robot.
|
Important
|
ITS OPINION IS FINAL, DO NOT REMOVE -1 VOTES. |
Using Gerrit is not always intuitive so some useful links are here:
As of 2.1 EVERY commit must go through validation/sanity to ensure you haven’t broken the code for anyone else.
For documentation changes, there is no need to run the tests but for everything else you must.
If you are adding tests to P0 or P1, then run them too. You may choose to run an explicit set of targeted individual tests, this is described in the UI. Note that running tests is a good thing but target the effort at the areas changed - consuming the cluster for the whole test suite unnecessarily will slow down other builds and therefore productivity.
To run tests:
-
In Gerrit click
Downloadand copy the git reference that looks likerefs/changes/88/136688/2. -
Navigate to Jenkins CICD job
-
Select
build with parametersand replace therefspecwith the one you have just copied from Gerrit. -
Add any other parameters (especially suites), and click
build.
At the end you should navigate to the test results page, see if you have broken anything (and then fix it repeating the above), if not post the link to Gerrit.
Finally reviewers should:
-
Check the code is decent!
-
Ensure that validation hasn’t been overridden
-
Ensure that the code has decent test coverage where applicable
-
Ensure the test has been run and passes
-
Only then may you bless with a +2 and submit the change.
-
Once reviewed, the author then submits.
-
Create a kind cluster
-
kubectl apply -f example/crd.yaml -
make debug-
build all containers
-
load them into kind
-
select the debug image as the operator image and set the command to run dlv
-
-
Port forward 30123 from the operator pod i.e
kubectl port-forward couchbase-operator-8bbc65c4f-q5l8d 30123:30123 -
Attach a delve client, e.g. Visual Studio Code configuration is
launch.json:{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Remote debug in Kubernetes", "type": "go", "request": "attach", "mode":"remote", "remotePath": "/go/src/github.com/couchbase/couchbase-operator", "port": 30123, "host": "127.0.0.1", "showLog": true } ] }
If you pause on a breakpoint for longer than 15 seconds, the operator lease will time expire.
This can be extended by kubectl edit lease and changing leaseDurationSeconds to something more appropriate.
Please consult the user documentation for instructions on how to deploy the Operator and a Couchbase cluster in Kubernetes, view cluster status and logs etc.
|
Important
|
The main documentation refers to .yaml paths which are distributed in the main package.
Typically in development we will use the examples in the |
The containers used by couchbase-operator are hosted on Docker Hub.
You can modify the version to install by editing example/couchbase-cluster.yaml and altering the /spec/version value.
Valid container version tags are available on the Couchbase Server Docker Hub.
This guide assumes the usage of KIND but there are other options available, most notably MiniKube which we will cover here. MiniKube handles deploying a single node Kubernetes cluster by using VirtualBox. To install minikube follow the official instructions for various operating systems.
|
Note
|
The default version of Kubernetes installed is hard coded in Minikube. You can always use the |
Once MiniKube is installed you can run the command below to start MiniKube.
$ minikube start --cpus 4 --memory 8192To run this operator on minikube you first need to build a container image which can be deployed into the Kubernetes environment. Normally you would need to push your container image to a container registry (e.g. DockerHub) and then pull it into Kubernetes, but since you are using MiniKube you can build the image using the same container host as the Minikube VM. That way the images are automatically present. To do this, make sure you are using the Minikube Docker daemon:
$ eval $(minikube docker-env)Later when you no longer want to use the Docker host in the MiniKube VM you can undo this change by running the command below.
$ eval $(minikube docker-env -u)By default all make actions assume you are working for the same target as your host machine.
To build a different image target override IMAGE_TARGET in the Makefile. e.g.
- To build AMD64 images on an ARM64 machine, run make images -e IMAGE_TARGET=kubernetes-linux-amd64.
- To build ARM64 images on an AMD64 machine, run make images -e IMAGE_TARGET=kubernetes-linux-arm64.
For more information on what variables exist and overwriting them, the Makefile is fairly well documented.