Switch branches/tags
v2.2.0-alpha.00000000 v2.1.0-beta.20181015 v2.1.0-beta.20181008 v2.1.0-beta.20181001 v2.1.0-beta.20180924 v2.1.0-beta.20180917 v2.1.0-beta.20180910 v2.1.0-beta.20180904 v2.1.0-beta.20180827 v2.1.0-alpha.20180730 v2.1.0-alpha.20180702 v2.1.0-alpha.20180604 v2.1.0-alpha.20180507 v2.1.0-alpha.20180416 v2.1.0-alpha.00000000 v2.0.6 v2.0.6-rc.1 v2.0.5 v2.0.4 v2.0.3 v2.0.2 v2.0.1 v2.0.0 v2.0-rc.1 v2.0-beta.20180326 v2.0-beta.20180319 v2.0-beta.20180312 v2.0-beta.20180305 v2.0-alpha.20180212 v2.0-alpha.20180129 v2.0-alpha.20180122 v2.0-alpha.20180116 v2.0-alpha.20171218 v2.0-alpha.20171218-plus-left-join-fix v1.2-alpha.20171211 v1.2-alpha.20171204 v1.2-alpha.20171113 v1.2-alpha.20171026 v1.2-alpha.20170901 v1.1.9 v1.1.9-rc.1 v1.1.8 v1.1.7 v1.1.6 v1.1.5 v1.1.4 v1.1.3 v1.1.2 v1.1.1 v1.1.0 v1.1.0-rc.1 v1.1-beta.20170928 v1.1-beta.20170921 v1.1-beta.20170907 v1.1-alpha.20170817 v1.1-alpha.20170810 v1.1-alpha.20170803 v1.1-alpha.20170720 v1.1-alpha.20170713 v1.1-alpha.20170629 v1.1-alpha.20170622 v1.1-alpha.20170608 v1.1-alpha.20170601 v1.0.7 v1.0.6 v1.0.5 v1.0.4 v1.0.3 v1.0.2 v1.0.1 v1.0 v1.0-rc.3 v1.0-rc.2 v1.0-rc.1 v0.1-alpha beta-20170420 beta-20170413 beta-20170406 beta-20170330 beta-20170323 beta-20170309 beta-20170223 beta-20170216 beta-20170209 beta-20170126 beta-20170112 beta-20170105 beta-20161215 beta-20161208 beta-20161201 beta-20161110 beta-20161103 beta-20161027 beta-20161013 beta-20161006 beta-20160929 beta-20160915 beta-20160908 beta-20160829 beta-20160728
Nothing to show
Find file History
3 authors Merge #31216 #31219
31216: sql: add merge joiner benchmark and bytes usage optimization r=changangela a=changangela

Reverted #30924 for now to compare different approaches (discussed in #31191). This PR is mainly for adding some merge joiner benchmarks as well a small change in `BoundAccount.Shrink()` that significantly improves the merge joiner performance. This way, we can safely backport this change.

MergeJoinerBenchmark against `release-2.1`:

```
name                           old time/op    new time/op    delta
MergeJoiner/InputSize=0-8        4.31µs ±10%    4.33µs ±15%      ~     (p=0.968 n=10+9)
MergeJoiner/InputSize=4-8        8.34µs ± 3%    8.10µs ± 4%      ~     (p=0.074 n=8+9)
MergeJoiner/InputSize=16-8       16.3µs ± 2%    11.1µs ± 5%   -31.87%  (p=0.000 n=9+9)
MergeJoiner/InputSize=256-8       190µs ± 2%      85µs ± 2%   -55.04%  (p=0.000 n=10+8)
MergeJoiner/InputSize=4096-8     2.96ms ± 2%    1.28ms ± 2%   -56.86%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8    49.0ms ± 5%    20.6ms ± 1%   -57.88%  (p=0.000 n=10+10)

name                           old alloc/op   new alloc/op   delta
MergeJoiner/InputSize=0-8        6.42kB ± 0%    6.65kB ± 0%    +3.49%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4-8        9.50kB ± 0%    9.72kB ± 0%    +2.36%  (p=0.000 n=10+10)
MergeJoiner/InputSize=16-8       9.50kB ± 0%    9.72kB ± 0%    +2.36%  (p=0.000 n=10+10)
MergeJoiner/InputSize=256-8      32.5kB ± 0%    32.8kB ± 0%    +0.69%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4096-8      401kB ± 0%     401kB ± 0%    +0.06%  (p=0.000 n=9+10)
MergeJoiner/InputSize=65536-8    6.30MB ± 0%    6.30MB ± 0%    +0.00%  (p=0.000 n=9+10)

name                           old allocs/op  new allocs/op  delta
MergeJoiner/InputSize=0-8          14.0 ± 0%      15.0 ± 0%    +7.14%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4-8          16.0 ± 0%      17.0 ± 0%    +6.25%  (p=0.000 n=10+10)
MergeJoiner/InputSize=16-8         16.0 ± 0%      17.0 ± 0%    +6.25%  (p=0.000 n=10+10)
MergeJoiner/InputSize=256-8        46.0 ± 0%      47.0 ± 0%    +2.17%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4096-8        526 ± 0%       527 ± 0%    +0.19%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8     8.21k ± 0%     8.21k ± 0%    +0.01%  (p=0.000 n=10+10)

name                           old speed      new speed      delta
MergeJoiner/InputSize=4-8      7.67MB/s ± 3%  7.91MB/s ± 4%      ~     (p=0.070 n=8+9)
MergeJoiner/InputSize=16-8     15.7MB/s ± 2%  23.0MB/s ± 5%   +46.89%  (p=0.000 n=9+9)
MergeJoiner/InputSize=256-8    21.6MB/s ± 2%  48.0MB/s ± 2%  +122.41%  (p=0.000 n=10+8)
MergeJoiner/InputSize=4096-8   22.1MB/s ± 2%  51.3MB/s ± 2%  +131.81%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8  21.4MB/s ± 5%  50.8MB/s ± 1%  +137.16%  (p=0.000 n=10+10)
```

MergeJoinerBenchmark compared with `master` (`master` already has this exact optimization, we want to ensure that the performance did not deteriorate)
```
name                                          old time/op    new time/op    delta
MergeJoiner/InputSize=0-8                       4.61µs ± 9%    4.45µs ± 5%     ~     (p=0.060 n=10+10)
MergeJoiner/InputSize=4-8                       8.34µs ± 6%    8.00µs ±10%   -4.09%  (p=0.037 n=9+10)
MergeJoiner/InputSize=16-8                      11.6µs ± 4%    11.4µs ± 5%     ~     (p=0.123 n=10+10)
MergeJoiner/InputSize=256-8                     88.3µs ± 3%    89.8µs ± 6%     ~     (p=0.258 n=9+9)
MergeJoiner/InputSize=4096-8                    1.33ms ± 4%    1.27ms ± 5%   -4.67%  (p=0.001 n=9+10)
MergeJoiner/InputSize=65536-8                   22.4ms ± 6%    21.3ms ±10%     ~     (p=0.052 n=10+10)
MergeJoiner/OneSideRepeatInputSize=0-8          4.57µs ±15%    4.38µs ± 6%     ~     (p=0.353 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4-8          7.71µs ±10%    7.71µs ± 4%     ~     (p=0.549 n=10+9)
MergeJoiner/OneSideRepeatInputSize=16-8         11.8µs ±29%    10.5µs ± 6%  -10.77%  (p=0.043 n=10+10)
MergeJoiner/OneSideRepeatInputSize=256-8        82.8µs ± 4%    80.3µs ± 5%   -2.93%  (p=0.004 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4096-8       1.25ms ± 2%    1.54ms ±13%  +23.09%  (p=0.000 n=9+10)
MergeJoiner/OneSideRepeatInputSize=65536-8      24.2ms ± 3%    26.7ms ± 9%  +10.08%  (p=0.000 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=0-8        4.60µs ±10%    4.36µs ±10%     ~     (p=0.063 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=4-8        7.13µs ± 4%    7.62µs ±17%   +6.84%  (p=0.005 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=16-8       8.66µs ±14%    8.24µs ± 3%     ~     (p=0.549 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=256-8      22.1µs ± 5%    23.2µs ± 9%   +5.06%  (p=0.004 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=4096-8      219µs ± 4%     240µs ±25%     ~     (p=0.065 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=65536-8    1.19ms ± 3%    1.17ms ± 1%   -2.18%  (p=0.001 n=10+9)

name                                          old alloc/op   new alloc/op   delta
MergeJoiner/InputSize=0-8                       6.66kB ± 0%    6.65kB ± 0%   -0.24%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4-8                       9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/InputSize=16-8                      9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/InputSize=256-8                     32.8kB ± 0%    32.8kB ± 0%   -0.05%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4096-8                     401kB ± 0%     401kB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8                   6.30MB ± 0%    6.30MB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=0-8          6.66kB ± 0%    6.65kB ± 0%   -0.24%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4-8          9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=16-8         9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=256-8        42.0kB ± 0%    42.0kB ± 0%   -0.04%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4096-8        751kB ± 0%     751kB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=65536-8      15.5MB ± 0%    15.5MB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=0-8        6.66kB ± 0%    6.65kB ± 0%   -0.24%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=4-8        9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=16-8       9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=256-8      9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=4096-8     14.3kB ± 0%    14.3kB ± 0%   -0.11%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=65536-8    38.9kB ± 0%    38.9kB ± 0%   -0.04%  (p=0.000 n=10+10)

name                                          old allocs/op  new allocs/op  delta
MergeJoiner/InputSize=0-8                         15.0 ± 0%      15.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=4-8                         17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=16-8                        17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=256-8                       47.0 ± 0%      47.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=4096-8                       527 ± 0%       527 ± 0%     ~     (all equal)
MergeJoiner/InputSize=65536-8                    8.21k ± 0%     8.21k ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=0-8            15.0 ± 0%      15.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=4-8            17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=16-8           17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=256-8          49.0 ± 0%      49.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=4096-8          536 ± 0%       536 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=65536-8       8.23k ± 0%     8.23k ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=0-8          15.0 ± 0%      15.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=4-8          17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=16-8         17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=256-8        17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=4096-8       23.0 ± 0%      23.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=65536-8      49.0 ± 0%      49.0 ± 0%     ~     (all equal)

name                                          old speed      new speed      delta
MergeJoiner/InputSize=4-8                     7.68MB/s ± 6%  8.02MB/s ± 9%   +4.43%  (p=0.037 n=9+10)
MergeJoiner/InputSize=16-8                    22.2MB/s ± 4%  22.6MB/s ± 5%     ~     (p=0.123 n=10+10)
MergeJoiner/InputSize=256-8                   46.4MB/s ± 3%  45.6MB/s ± 5%     ~     (p=0.231 n=9+9)
MergeJoiner/InputSize=4096-8                  49.2MB/s ± 4%  51.6MB/s ± 5%   +4.93%  (p=0.001 n=9+10)
MergeJoiner/InputSize=65536-8                 46.8MB/s ± 6%  49.3MB/s ± 9%     ~     (p=0.052 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4-8        8.32MB/s ± 9%  8.31MB/s ± 4%     ~     (p=0.549 n=10+9)
MergeJoiner/OneSideRepeatInputSize=16-8       22.1MB/s ±24%  24.3MB/s ± 6%  +10.32%  (p=0.037 n=10+10)
MergeJoiner/OneSideRepeatInputSize=256-8      49.5MB/s ± 4%  51.0MB/s ± 5%   +3.03%  (p=0.003 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4096-8     52.5MB/s ± 2%  42.8MB/s ±12%  -18.43%  (p=0.000 n=9+10)
MergeJoiner/OneSideRepeatInputSize=65536-8    43.3MB/s ± 3%  39.4MB/s ± 9%   -8.94%  (p=0.000 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=4-8      8.98MB/s ± 4%  8.45MB/s ±15%   -5.96%  (p=0.005 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=16-8     29.7MB/s ±13%  31.1MB/s ± 3%     ~     (p=0.549 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=256-8     186MB/s ± 5%   177MB/s ± 8%   -4.73%  (p=0.004 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=4096-8    299MB/s ± 3%   276MB/s ±21%     ~     (p=0.065 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=65536-8   878MB/s ± 3%   898MB/s ± 1%   +2.22%  (p=0.001 n=10+9)
```

31219: kubernetes: Update request-cert image version to include recent fix r=a-robinson a=a-robinson

See cockroachdb/k8s#14

Release note: None

Co-authored-by: changangela <angelachang27@gmail.com>
Co-authored-by: Alex Robinson <alexdwanerobinson@gmail.com>
Latest commit d1177a3 Oct 11, 2018

README.md

CockroachDB on Kubernetes as a StatefulSet

This example deploys CockroachDB on Kubernetes as a StatefulSet. Kubernetes is an open source system for managing containerized applications across multiple hosts, providing basic mechanisms for deployment, maintenance, and scaling of applications.

This is a copy of the similar example stored in the Kubernetes repository. We keep a copy here as well for faster iteration, since merging things into Kubernetes can be quite slow, particularly during the code freeze before releases. The copy here will typically be more up-to-date.

Note that if all you want to do is run a single cockroachdb instance for testing and don't care about data persistence, you can do so with just a single command instead of following this guide (which sets up a more reliable cluster):

kubectl run cockroachdb --image=cockroachdb/cockroach --restart=Never -- start --insecure

Limitations

Kubernetes version

The minimum Kubernetes version to successfully run the examples in this directory without modification is 1.8. If you want to run them on an older version of Kubernetes, use the files from the appropriate subdirectory (e.g. the v1.7 directory for Kubernetes 1.7 or the v1.6 directory for Kubernetes 1.6). Older Kubernetes versions that don't have their own directory are no longer supported.

For secure mode, the controller must enable certificatesigningrequests. You can check if this is enabled by looking at the controller logs:

# On cloud platform:
# Find the controller:
$ kubectl get pods --all-namespaces | grep controller
kube-system   po/kube-controller-manager-k8s-master-5ef244d4-0   1/1       Running   0          7m

# Check the logs:
$ kubectl logs kube-controller-manager-k8s-master-5ef244d4-0 -n kube-system | grep certificate
I0628 12:38:23.471365       1 controllermanager.go:427] Starting "certificatesigningrequests"
E0628 12:38:23.473076       1 certificates.go:38] Failed to start certificate controller: open /etc/kubernetes/ca/ca.pem: no such file or directory
W0628 12:38:23.473106       1 controllermanager.go:434] Skipping "certificatesigningrequests"
# This shows that the certificate controller is not running, approved CSRs will not trigger a certificate.

# On minikube:
$ minikube logs | grep certificate
Jun 28 12:49:00 minikube localkube[3440]: I0628 12:49:00.224903    3440 controllermanager.go:437] Started "certificatesigningrequests"
Jun 28 12:49:00 minikube localkube[3440]: I0628 12:49:00.231134    3440 certificate_controller.go:120] Starting certificate controller manager
# This shows that the certificate controller is running, approved CSRs will get a certificate.

StatefulSet limitations

Node-local storage for StatefulSets was only recently promoted to beta as a Kubernetes feature (known as local persistent volumes), so we don't yet recommend running that way in production. Instead, these examples use dynamically provisioned remote persistent volumes. Note that CockroachDB already replicates its data and thus, for the best performance, should not be deployed on a persistent volume which already replicates internally. High-performance use cases that need the very best performance may want to consider a DaemonSet deployment until node-local storage has been more rigorously hardened.

Secure mode

Secure mode currently works by requesting node/client certificates from the kubernetes controller at pod initialization time.

Geographically distributed clusters

The configuration files and instructions in this directory are limited to deployments that exist entirely within a single Kubernetes cluster. If you'd like to deploy CockroachDB across multiple geographically distributed Kubernetes clusters, see the multiregion subdirectory.

Creating your kubernetes cluster

Locally on minikube

Set up your minikube cluster following the instructions provided in the Kubernetes docs.

On AWS

Set up your cluster following the instructions provided in the Kubernetes docs.

On GCE

You can either set up your cluster following the instructions provided in the Kubernetes docs or by using the hosted Google Kubernetes Engine (GKE) service:

gcloud container clusters create NAME

If you're using GKE and want to run a secure cluster, one extra step is required. A limitation in GKE's Role-Based Access Control (RBAC) integration necessitates running a special command in order to let you create the RBAC roles that CockroachDB needs to manage certificates.

  1. Get the email address associated with your Google Cloud account by running:
    `gcloud info | grep Account`
  2. Run the following command from the GKE documentation with that email address:
    kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=<your.google.cloud.email@example.org>

On Azure

Set up your cluster following the instructions provided in the Kubernetes docs.

Creating the cockroach cluster

Once your kubernetes cluster is up and running, you can launch your cockroach cluster.

Insecure mode

To create the cluster, run:

kubectl create -f cockroachdb-statefulset.yaml

Then, to initialize the cluster, run:

kubectl create -f cluster-init.yaml

Secure mode

Prerequisites

REQUIRED: the kubernetes cluster must run with the certificate controller enabled. This is done by passing the --cluster-signing-cert-file and --cluster-signing-key-file flags. If you are using minikube v0.23.0 or newer (run minikube version if you aren't sure), you can tell it to use the minikube-generated CA by specifying:

minikube start --extra-config=controller-manager.ClusterSigningCertFile="/var/lib/localkube/certs/ca.crt" --extra-config=controller-manager.ClusterSigningKeyFile="/var/lib/localkube/certs/ca.key"

If you're running on an older version of minikube, you can similarly run:

minikube start --extra-config=controller-manager.ClusterSigningCertFile="/var/lib/localkube/ca.crt" --extra-config=controller-manager.ClusterSigningKeyFile="/var/lib/localkube/ca.key"

Creating the cluster

Run: kubectl create -f cockroachdb-statefulset-secure.yaml

If you get an error saying "attempt to grant extra privileges", you don't have sufficient permissions in the cluster to manage certificates. If this happens and you're running on Google Kubernetes Engine, see the note above. If not, talk to your cluster administrator.

Each new node will request a certificate from the kubernetes CA during its initialization phase. We have configured the StatefulSet to bring up all its pods at once, so you can approve all of the pods' certificates in quick succession.

If a pod is rescheduled, it will reuse the previously-generated certificate.

You can view pending certificates and approve them using:

# List CSRs:
$ kubectl get csr
NAME                         AGE       REQUESTOR                               CONDITION
default.node.cockroachdb-0   4s        system:serviceaccount:default:default   Pending
default.node.cockroachdb-1   4s        system:serviceaccount:default:default   Pending
default.node.cockroachdb-2   4s        system:serviceaccount:default:default   Pending

# Examine the CSR:
$ kubectl describe csr default.node.cockroachdb-0
Name:                   default.node.cockroachdb-0
Labels:                 <none>
Annotations:            <none>
CreationTimestamp:      Thu, 22 Jun 2017 09:56:49 -0400
Requesting User:        system:serviceaccount:default:default
Status:                 Pending
Subject:
        Common Name:    node
        Serial Number:
        Organization:   Cockroach
Subject Alternative Names:
        DNS Names:      localhost
                        cockroachdb-0.cockroachdb.default.svc.cluster.local
                        cockroachdb-public
        IP Addresses:   127.0.0.1
                        172.17.0.5
Events: <none>

# If everything checks out, approve the CSR:
$ kubectl certificate approve default.node.cockroachdb-0
certificatesigningrequest "default.node.cockroachdb-0" approved

# Otherwise, deny the CSR:
$ kubectl certificate deny default.node.cockroachdb-0
certificatesigningrequest "default.node.cockroachdb-0" denied

Once all the pods have started, to initialize the cluster run:

kubectl create -f cluster-init-secure.yaml

This will create a CSR called "default.client.root", which you can approve by running:

kubectl certificate approve default.client.root

To confirm that it's done, run:

kubectl get job cluster-init-secure

The output should look like:

NAME                  DESIRED   SUCCESSFUL   AGE
cluster-init-secure   1         1            5m

Accessing the database

Along with our StatefulSet configuration, we expose a standard Kubernetes service that offers a load-balanced virtual IP for clients to access the database with. In our example, we've called this service cockroachdb-public.

In insecure mode, start up a client pod and open up an interactive, (mostly) Postgres-flavor SQL shell:

kubectl run cockroachdb -it --image=cockroachdb/cockroach --rm --restart=Never \
    -- sql --insecure --host=cockroachdb-public

In secure mode, use our client-secure.yaml config to launch a pod that runs indefinitely with the cockroach binary inside it:

kubectl create -f client-secure.yaml

Check and approve the CSR for the pod as described above, and then get a shell to the pod and run:

kubectl exec -it cockroachdb-client-secure -- ./cockroach sql --certs-dir=/cockroach-certs --host=cockroachdb-public

You can see example SQL statements for inserting and querying data in the included demo script, but can use almost any Postgres-style SQL commands. Some more basic examples can be found within CockroachDB's documentation.

Accessing the admin UI

If you want to see information about how the cluster is doing, you can try pulling up the CockroachDB admin UI by port-forwarding from your local machine to one of the pods:

kubectl port-forward cockroachdb-0 8080

Once you’ve done that, you should be able to access the admin UI by visiting http://localhost:8080/ in your web browser.

Running the example app

This directory contains the configuration to launch a simple load generator with one pod.

If you created an insecure cockroach cluster, run:

kubectl create -f example-app.yaml

If you created a secure cockroach cluster, run:

kubectl create -f example-app-secure.yaml

When the first pod is being initialized, you will need to approve its client certificate request:

kubectl certificate approve default.client.root

If more pods are then added through kubectl scale deployment example-secure --replicas=X, the generated certificate will be reused. WARNING: the example app in secure mode should be started with only one replica, or concurrent and conflicting certificate requests will be sent, causing issues.

Secure client apps with other users

Applications should be run with a user other than root. This can be done using the following:

Create the desired user and database

Connect to the cockroachdb-client-secure pod (created in the "Accessing the database" section):

kubectl exec -it cockroachdb-client-secure -- ./cockroach sql --certs-dir=/cockroach-certs --host=cockroachdb-public

Create the the app user, its database, and grant it privileges:

root@:26257/defaultdb> CREATE USER myapp;
CREATE USER 1

Time: 164.811054ms

root@:26257/defaultdb> CREATE DATABASE myappdb;
CREATE DATABASE

Time: 153.44247ms

root@:26257/defaultdb> GRANT ALL ON DATABASE myappdb TO myapp;
GRANT

Time: 90.488168ms

Create the client pod

Modify example-app-secure.yaml to match your user and app:

The init container init-certs needs to request a certificate and key for your new user:

"/request-cert -namespace=${POD_NAMESPACE} -certs-dir=/cockroach-certs -type=client -user=myapp -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"

The loadgen container should be modified for your client app docker image and command, and the connection url modified to match the user and database:

"postgres://myapp@cockroachdb-public:26257/myappdb?sslmode=verify-full&sslcert=/cockroach-certs/client.myapp.crt&sslkey=/cockroach-certs/client.myapp.key&sslrootcert=/cockroach-certs/ca.crt"

You can now create the client pod:

kubectl create -f example-app-secure.yaml

Approve the client CSR

The init container sends a CSR and waits for approval. You can approve it using:

kubectl certificate approve default.client.myapp

Once approved, the init container copies the certificate and key to /cockroach-certs and terminates. The app container now starts, using the mounted certificate directory.

Simulating failures

When all (or enough) nodes are up, simulate a failure like this:

kubectl exec cockroachdb-0 -- /bin/bash -c "while true; do kill 1; done"

You can then reconnect to the database as demonstrated above and verify that no data was lost. The example runs with three-fold replication, so it can tolerate one failure of any given node at a time. Note also that there is a brief period of time immediately after the creation of the cluster during which the three-fold replication is established, and during which killing a node may lead to unavailability.

The demo script gives an example of killing one instance of the database and ensuring the other replicas have all data that was written.

Scaling up or down

Scale the StatefulSet by running

kubectl scale statefulset cockroachdb --replicas=4

You should never scale the StatefulSet down by more than one replica at a time. Doing so could lead to data unavailability. For best practices on safely removing nodes from a safely, see our docs on node decommissioning.

Doing a rolling upgrade to a different CockroachDB version

Open up the StatefulSet's current configuration in your default text editor using the command below, find the line specifying the cockroachdb/cockroach image being used, change the version tag to the new one, save the file, and quit.

kubectl edit statefulset cockroachdb

Kubernetes will then automatically replace the pods in your StatefulSet one by one to run on the newly specified image. For more details on upgrading CockroachDB, see our docs. For how to use alternative rolling update commands such as kubectl patch and kubectl replace, see the Kubernetes docs.

Cleaning up when you're done

Because all of the resources in this example have been tagged with the label app=cockroachdb, we can clean up everything that we created in one quick command using a selector on that label:

kubectl delete statefulsets,pods,persistentvolumes,persistentvolumeclaims,services,poddisruptionbudget,jobs,rolebinding,clusterrolebinding,role,clusterrole,serviceaccount -l app=cockroachdb

If running in secure mode, you'll want to cleanup old certificate requests:

kubectl delete csr --all