Add a CockroachDB PetSet example
The example starts a simple five-node cluster with otherwise default setting (in particular, 3x replication).
This commit is contained in:
parent
afb4d74fe5
commit
abc07f328e
|
@ -0,0 +1,97 @@
|
||||||
|
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
|
||||||
|
|
||||||
|
<!-- BEGIN STRIP_FOR_RELEASE -->
|
||||||
|
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
|
||||||
|
<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>
|
||||||
|
|
||||||
|
If you are using a released version of Kubernetes, you should
|
||||||
|
refer to the docs that go with that version.
|
||||||
|
|
||||||
|
Documentation for other releases can be found at
|
||||||
|
[releases.k8s.io](http://releases.k8s.io).
|
||||||
|
</strong>
|
||||||
|
--
|
||||||
|
|
||||||
|
<!-- END STRIP_FOR_RELEASE -->
|
||||||
|
|
||||||
|
<!-- END MUNGE: UNVERSIONED_WARNING -->
|
||||||
|
|
||||||
|
# CockroachDB on Kubernetes as a PetSet
|
||||||
|
|
||||||
|
This example deploys [CockroachDB](https://cockroachlabs.com) on Kubernetes as
|
||||||
|
a PetSet. CockroachDB is a distributed, scalable NewSQL database. Please see
|
||||||
|
[the homepage](https://cockroachlabs.com) and the
|
||||||
|
[documentation](https://www.cockroachlabs.com/docs/) for details.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
### PetSet limitations
|
||||||
|
|
||||||
|
Standard PetSet limitations apply: There is currently no possibility to use
|
||||||
|
node-local storage (outside of single-node tests), and so there is likely
|
||||||
|
a performance hit associated with running CockroachDB on some external storage.
|
||||||
|
Note that CockroachDB already does replication and thus should not be deployed on
|
||||||
|
a persistent volume which already replicates internally.
|
||||||
|
High-performance use cases on a private Kubernetes cluster should consider
|
||||||
|
a DaemonSet deployment.
|
||||||
|
|
||||||
|
### Recovery after persistent storage failure
|
||||||
|
|
||||||
|
A persistent storage failure (e.g. losing the hard drive) is gracefully handled
|
||||||
|
by CockroachDB as long as enough replicas survive (two out of three by
|
||||||
|
default). Due to the bootstrapping in this deployment, a storage failure of the
|
||||||
|
first node is special in that the administrator must manually prepopulate the
|
||||||
|
"new" storage medium by running an instance of CockroachDB with the `--join`
|
||||||
|
parameter. If this is not done, the first node will bootstrap a new cluster,
|
||||||
|
which will lead to a lot of trouble.
|
||||||
|
|
||||||
|
### Dynamic provisioning
|
||||||
|
|
||||||
|
The deployment is written for a use case in which dynamic provisioning is
|
||||||
|
available. When that is not the case, the persistent volume claims need
|
||||||
|
to be created manually. See [minikube.sh](minikube.sh) for the necessary
|
||||||
|
steps.
|
||||||
|
|
||||||
|
## Testing locally on minikube
|
||||||
|
|
||||||
|
Follow the steps in [minikube.sh](minikube.sh) (or simply run that file).
|
||||||
|
|
||||||
|
## Simulating failures
|
||||||
|
|
||||||
|
When all (or enough) nodes are up, simulate a failure like this:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl exec cockroachdb-0 -- /bin/bash -c "while true; do kill 1; done"
|
||||||
|
```
|
||||||
|
|
||||||
|
On one of the other pods, run `./cockroach sql --host $(hostname)` and use
|
||||||
|
(mostly) Postgres-flavor SQL. 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.
|
||||||
|
|
||||||
|
There is also a [demo script](demo.sh).
|
||||||
|
|
||||||
|
## Scaling up or down
|
||||||
|
|
||||||
|
Simply edit the PetSet (but note that you may need to create a new persistent
|
||||||
|
volume claim first). If you ran `minikube.sh`, there's a spare volume so you
|
||||||
|
can immediately scale up by one. Convince yourself that the new node
|
||||||
|
immediately serves reads and writes.
|
||||||
|
|
||||||
|
|
||||||
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
|
[]()
|
||||||
|
<!-- END MUNGE: GENERATED_ANALYTICS -->
|
|
@ -0,0 +1,96 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
||||||
|
name: cockroachdb
|
||||||
|
labels:
|
||||||
|
app: cockroachdb
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
# The main port, served by gRPC, serves Postgres-flavor SQL, internode
|
||||||
|
# traffic and the cli.
|
||||||
|
- port: 26257
|
||||||
|
targetPort: 26257
|
||||||
|
name: grpc
|
||||||
|
# The secondary port serves the UI as well as health and debug endpoints.
|
||||||
|
- port: 8080
|
||||||
|
targetPort: 8080
|
||||||
|
name: http
|
||||||
|
clusterIP: None
|
||||||
|
selector:
|
||||||
|
app: cockroachdb
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1alpha1
|
||||||
|
kind: PetSet
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb
|
||||||
|
spec:
|
||||||
|
serviceName: "cockroachdb"
|
||||||
|
replicas: 5
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: cockroachdb
|
||||||
|
annotations:
|
||||||
|
pod.alpha.kubernetes.io/initialized: "true"
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
# Runs the master branch. Not recommended for production, but since
|
||||||
|
# CockroachDB is in Beta, you don't want to run it in production
|
||||||
|
# anyway. See
|
||||||
|
# https://hub.docker.com/r/cockroachdb/cockroach/tags/
|
||||||
|
# if you prefer to run a beta release.
|
||||||
|
image: cockroachdb/cockroach
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- containerPort: 26257
|
||||||
|
name: grpc
|
||||||
|
- containerPort: 8080
|
||||||
|
name: http
|
||||||
|
volumeMounts:
|
||||||
|
- name: datadir
|
||||||
|
mountPath: /cockroach/cockroach-data
|
||||||
|
command:
|
||||||
|
- "/bin/bash"
|
||||||
|
- "-ecx"
|
||||||
|
- |
|
||||||
|
# The use of qualified `hostname -f` is crucial:
|
||||||
|
# Other nodes aren't able to look up the unqualified hostname.
|
||||||
|
CRARGS=("start" "--logtostderr" "--insecure" "--host" "$(hostname -f)")
|
||||||
|
# TODO(tschottdorf): really want to use an init container to do
|
||||||
|
# the bootstrapping. The idea is that the container would know
|
||||||
|
# whether it's on the first node and could check whether there's
|
||||||
|
# already a data directory. If not, it would bootstrap the cluster.
|
||||||
|
# We will need some version of `cockroach init` back for this to
|
||||||
|
# work. For now, just do the same in a shell snippet.
|
||||||
|
# Of course this isn't without danger - if node0 loses its data,
|
||||||
|
# upon restarting it will simply bootstrap a new cluster and smack
|
||||||
|
# it into our existing cluster.
|
||||||
|
# There are likely ways out. For example, the init container could
|
||||||
|
# query the kubernetes API and see whether any other nodes are
|
||||||
|
# around, etc. Or, of course, the admin can pre-seed the lost
|
||||||
|
# volume somehow (and in that case we should provide a better way,
|
||||||
|
# for example a marker file).
|
||||||
|
if [ ! "$(hostname)" == "cockroachdb-0" ] || \
|
||||||
|
[ -e "/cockroach/cockroach-data/COCKROACHDB_VERSION" ]
|
||||||
|
then
|
||||||
|
CRARGS+=("--join" "cockroachdb")
|
||||||
|
fi
|
||||||
|
/cockroach/cockroach ${CRARGS[*]}
|
||||||
|
volumes:
|
||||||
|
- name: datadir
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: datadir
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: datadir
|
||||||
|
annotations:
|
||||||
|
volume.alpha.kubernetes.io/storage-class: anything
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- "ReadWriteOnce"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
|
@ -0,0 +1,47 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright 2016 The Kubernetes Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
function sql() {
|
||||||
|
# TODO(knz): Why does the more idiomatic read from stdin not produce any
|
||||||
|
# output?
|
||||||
|
kubectl exec "cockroachdb-${1}" -- /cockroach/cockroach sql \
|
||||||
|
--host "cockroachdb-${1}.cockroachdb" \
|
||||||
|
-e "$(cat /dev/stdin)"
|
||||||
|
}
|
||||||
|
|
||||||
|
function kill() {
|
||||||
|
! kubectl exec -t "cockroachdb-${1}" -- /bin/bash -c "while true; do kill 1; done" &> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create database on second node (idempotently for convenience).
|
||||||
|
cat <<EOF | sql 1
|
||||||
|
CREATE DATABASE IF NOT EXISTS foo;
|
||||||
|
CREATE TABLE IF NOT EXISTS foo.bar (k STRING PRIMARY KEY, v STRING);
|
||||||
|
UPSERT INTO foo.bar VALUES ('Kuber', 'netes'), ('Cockroach', 'DB');
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Kill the node we just created the table on.
|
||||||
|
kill 1
|
||||||
|
|
||||||
|
# Read the data from all other nodes (we could also read from the one we just
|
||||||
|
# killed, but it's awkward to wait for it to respawn).
|
||||||
|
for i in 0 2 3 4; do
|
||||||
|
cat <<EOF | sql "${i}"
|
||||||
|
SELECT CONCAT(k, v) FROM foo.bar;
|
||||||
|
EOF
|
||||||
|
done
|
|
@ -0,0 +1,66 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright 2016 The Kubernetes Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# Run the CockroachDB PetSet example on a minikube instance.
|
||||||
|
#
|
||||||
|
# For a fresh start, run the following first:
|
||||||
|
# minikube delete
|
||||||
|
# minikube start
|
||||||
|
#
|
||||||
|
# To upgrade minikube & kubectl on OSX, the following should suffice:
|
||||||
|
# brew reinstall kubernetes-cli --devel
|
||||||
|
# url -Lo minikube \
|
||||||
|
# https://storage.googleapis.com/minikube/releases/v0.4.0/minikube-darwin-amd64 && \
|
||||||
|
# chmod +x minikube && sudo mv minikube /usr/local/bin/
|
||||||
|
|
||||||
|
set -exuo pipefail
|
||||||
|
|
||||||
|
# Make persistent volumes and (correctly named) claims. We must create the
|
||||||
|
# claims here manually even though that sounds counter-intuitive. For details
|
||||||
|
# see https://github.com/kubernetes/contrib/pull/1295#issuecomment-230180894.
|
||||||
|
# Note that we make an extra volume here so you can manually test scale-up.
|
||||||
|
for i in $(seq 0 5); do
|
||||||
|
cat <<EOF | kubectl create -f -
|
||||||
|
kind: PersistentVolume
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: pv${i}
|
||||||
|
labels:
|
||||||
|
type: local
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 1Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
hostPath:
|
||||||
|
path: "/tmp/${i}"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF | kubectl create -f -
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: datadir-cockroachdb-${i}
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
|
EOF
|
||||||
|
done;
|
||||||
|
|
||||||
|
kubectl create -f cockroachdb-petset.yaml
|
Loading…
Reference in New Issue