mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Improve CockroachDB example
* Use an init container to eliminate potential edge case where losing the first pet's could cause it to start a second logical cluster * Exec the cockroach binary so that it runs as PID 1 in the container * Make some small improvements to the README
This commit is contained in:
		@@ -12,10 +12,11 @@ a PetSet. CockroachDB is a distributed, scalable NewSQL database. Please see
 | 
				
			|||||||
Standard PetSet limitations apply: There is currently no possibility to use
 | 
					Standard PetSet limitations apply: There is currently no possibility to use
 | 
				
			||||||
node-local storage (outside of single-node tests), and so there is likely
 | 
					node-local storage (outside of single-node tests), and so there is likely
 | 
				
			||||||
a performance hit associated with running CockroachDB on some external storage.
 | 
					a performance hit associated with running CockroachDB on some external storage.
 | 
				
			||||||
Note that CockroachDB already does replication and thus should not be deployed on
 | 
					Note that CockroachDB already does replication and thus it is unnecessary to
 | 
				
			||||||
a persistent volume which already replicates internally.
 | 
					deploy it onto persistent volumes which already replicate internally.
 | 
				
			||||||
High-performance use cases on a private Kubernetes cluster should consider
 | 
					For this reason, high-performance use cases on a private Kubernetes cluster
 | 
				
			||||||
a DaemonSet deployment.
 | 
					may want to consider a DaemonSet deployment until PetSets support node-local
 | 
				
			||||||
 | 
					storage (see #7562).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Recovery after persistent storage failure
 | 
					### Recovery after persistent storage failure
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,17 +28,25 @@ first node is special in that the administrator must manually prepopulate the
 | 
				
			|||||||
parameter. If this is not done, the first node will bootstrap a new cluster,
 | 
					parameter. If this is not done, the first node will bootstrap a new cluster,
 | 
				
			||||||
which will lead to a lot of trouble.
 | 
					which will lead to a lot of trouble.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Dynamic provisioning
 | 
					### Dynamic volume provisioning
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The deployment is written for a use case in which dynamic provisioning is
 | 
					The deployment is written for a use case in which dynamic volume provisioning is
 | 
				
			||||||
available. When that is not the case, the persistent volume claims need
 | 
					available. When that is not the case, the persistent volume claims need
 | 
				
			||||||
to be created manually. See [minikube.sh](minikube.sh) for the necessary
 | 
					to be created manually. See [minikube.sh](minikube.sh) for the necessary
 | 
				
			||||||
steps.
 | 
					steps. If you're on GCE or AWS, where dynamic provisioning is supported, no
 | 
				
			||||||
 | 
					manual work is needed to create the persistent volumes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Testing locally on minikube
 | 
					## Testing locally on minikube
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Follow the steps in [minikube.sh](minikube.sh) (or simply run that file).
 | 
					Follow the steps in [minikube.sh](minikube.sh) (or simply run that file).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Testing in the cloud on GCE or AWS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once you have a Kubernetes cluster running, just run
 | 
				
			||||||
 | 
					`kubectl create -f cockroachdb-petset.yaml` to create your cockroachdb cluster.
 | 
				
			||||||
 | 
					This works because GCE and AWS support dynamic volume provisioning by default,
 | 
				
			||||||
 | 
					so persistent volumes will be created for the CockroachDB pods as needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Accessing the database
 | 
					## Accessing the database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Along with our PetSet configuration, we expose a standard Kubernetes service
 | 
					Along with our PetSet configuration, we expose a standard Kubernetes service
 | 
				
			||||||
@@ -48,8 +57,7 @@ Start up a client pod and open up an interactive, (mostly) Postgres-flavor
 | 
				
			|||||||
SQL shell using:
 | 
					SQL shell using:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```console
 | 
					```console
 | 
				
			||||||
$ kubectl run -it cockroach-client --image=cockroachdb/cockroach --restart=Never --command -- bash
 | 
					$ kubectl run -it --rm cockroach-client --image=cockroachdb/cockroach --restart=Never --command -- ./cockroach sql --host cockroachdb-public
 | 
				
			||||||
root@cockroach-client # ./cockroach sql --host cockroachdb-public
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can see example SQL statements for inserting and querying data in the
 | 
					You can see example SQL statements for inserting and querying data in the
 | 
				
			||||||
@@ -57,6 +65,19 @@ included [demo script](demo.sh), but can use almost any Postgres-style SQL
 | 
				
			|||||||
commands. Some more basic examples can be found within
 | 
					commands. Some more basic examples can be found within
 | 
				
			||||||
[CockroachDB's documentation](https://www.cockroachlabs.com/docs/learn-cockroachdb-sql.html).
 | 
					[CockroachDB's documentation](https://www.cockroachlabs.com/docs/learn-cockroachdb-sql.html).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```shell
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Simulating failures
 | 
					## Simulating failures
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When all (or enough) nodes are up, simulate a failure like this:
 | 
					When all (or enough) nodes are up, simulate a failure like this:
 | 
				
			||||||
@@ -77,10 +98,17 @@ database and ensuring the other replicas have all data that was written.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Scaling up or down
 | 
					## Scaling up or down
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Simply edit the PetSet (but note that you may need to create a new persistent
 | 
					Simply patch the PetSet by running
 | 
				
			||||||
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
 | 
					```shell
 | 
				
			||||||
immediately serves reads and writes.
 | 
					kubectl patch petset cockroachdb -p '{"spec":{"replicas":4}}'
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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. If you're running on GCE or AWS, you can scale up by as many as you want
 | 
				
			||||||
 | 
					because new volumes will automatically be created for you. Convince yourself
 | 
				
			||||||
 | 
					that the new node immediately serves reads and writes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Cleaning up when you're done
 | 
					## Cleaning up when you're done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,17 +23,25 @@ spec:
 | 
				
			|||||||
apiVersion: v1
 | 
					apiVersion: v1
 | 
				
			||||||
kind: Service
 | 
					kind: Service
 | 
				
			||||||
metadata:
 | 
					metadata:
 | 
				
			||||||
 | 
					  # This service only exists to create DNS entries for each pet in the petset
 | 
				
			||||||
 | 
					  # such that they can resolve each other's IP addresses. It does not create a
 | 
				
			||||||
 | 
					  # load-balanced ClusterIP and should not be used directly by clients in most
 | 
				
			||||||
 | 
					  # circumstances.
 | 
				
			||||||
 | 
					  name: cockroachdb
 | 
				
			||||||
 | 
					  labels:
 | 
				
			||||||
 | 
					    app: cockroachdb
 | 
				
			||||||
  annotations:
 | 
					  annotations:
 | 
				
			||||||
 | 
					    # This is needed to make the peer-finder work properly and to help avoid
 | 
				
			||||||
 | 
					    # edge cases where instance 0 comes up after losing its data and needs to
 | 
				
			||||||
 | 
					    # decide whether it should create a new cluster or try to join an existing
 | 
				
			||||||
 | 
					    # one. If it creates a new cluster when it should have joined an existing
 | 
				
			||||||
 | 
					    # one, we'd end up with two separate clusters listening at the same service
 | 
				
			||||||
 | 
					    # endpoint, which would be very bad.
 | 
				
			||||||
 | 
					    service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
 | 
				
			||||||
    # Enable automatic monitoring of all instances when Prometheus is running in the cluster.
 | 
					    # Enable automatic monitoring of all instances when Prometheus is running in the cluster.
 | 
				
			||||||
    prometheus.io/scrape: "true"
 | 
					    prometheus.io/scrape: "true"
 | 
				
			||||||
    prometheus.io/path: "_status/vars"
 | 
					    prometheus.io/path: "_status/vars"
 | 
				
			||||||
    prometheus.io/port: "8080"
 | 
					    prometheus.io/port: "8080"
 | 
				
			||||||
  # This service only exists to create DNS entries for each pet in the petset such that they can resolve
 | 
					 | 
				
			||||||
  # each other's IP addresses. It does not create a load-balanced ClusterIP and should not be used
 | 
					 | 
				
			||||||
  # directly by clients in most circumstances.
 | 
					 | 
				
			||||||
  name: cockroachdb
 | 
					 | 
				
			||||||
  labels:
 | 
					 | 
				
			||||||
    app: cockroachdb
 | 
					 | 
				
			||||||
spec:
 | 
					spec:
 | 
				
			||||||
  ports:
 | 
					  ports:
 | 
				
			||||||
  - port: 26257
 | 
					  - port: 26257
 | 
				
			||||||
@@ -52,13 +60,50 @@ metadata:
 | 
				
			|||||||
  name: cockroachdb
 | 
					  name: cockroachdb
 | 
				
			||||||
spec:
 | 
					spec:
 | 
				
			||||||
  serviceName: "cockroachdb"
 | 
					  serviceName: "cockroachdb"
 | 
				
			||||||
  replicas: 5
 | 
					  replicas: 3
 | 
				
			||||||
  template:
 | 
					  template:
 | 
				
			||||||
    metadata:
 | 
					    metadata:
 | 
				
			||||||
      labels:
 | 
					      labels:
 | 
				
			||||||
        app: cockroachdb
 | 
					        app: cockroachdb
 | 
				
			||||||
      annotations:
 | 
					      annotations:
 | 
				
			||||||
        pod.alpha.kubernetes.io/initialized: "true"
 | 
					        pod.alpha.kubernetes.io/initialized: "true"
 | 
				
			||||||
 | 
					        # Init containers are run only once in the lifetime of a pod, before
 | 
				
			||||||
 | 
					        # it's started up for the first time. It has to exit successfully
 | 
				
			||||||
 | 
					        # before the pod's main containers are allowed to start.
 | 
				
			||||||
 | 
					        # This particular init container does a DNS lookup for other pods in
 | 
				
			||||||
 | 
					        # the petset to help determine whether or not a cluster already exists.
 | 
				
			||||||
 | 
					        # If any other pets exist, it creates a file in the cockroach-data
 | 
				
			||||||
 | 
					        # directory to pass that information along to the primary container that
 | 
				
			||||||
 | 
					        # has to decide what command-line flags to use when starting CockroachDB.
 | 
				
			||||||
 | 
					        # This only matters when a pod's persistent volume is empty - if it has
 | 
				
			||||||
 | 
					        # data from a previous execution, that data will always be used.
 | 
				
			||||||
 | 
					        pod.alpha.kubernetes.io/init-containers: '[
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "name": "bootstrap",
 | 
				
			||||||
 | 
					                "image": "cockroachdb/cockroach-k8s-init:0.1",
 | 
				
			||||||
 | 
					                "args": [
 | 
				
			||||||
 | 
					                  "-on-start=/on-start.sh",
 | 
				
			||||||
 | 
					                  "-service=cockroachdb"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "env": [
 | 
				
			||||||
 | 
					                  {
 | 
				
			||||||
 | 
					                      "name": "POD_NAMESPACE",
 | 
				
			||||||
 | 
					                      "valueFrom": {
 | 
				
			||||||
 | 
					                          "fieldRef": {
 | 
				
			||||||
 | 
					                              "apiVersion": "v1",
 | 
				
			||||||
 | 
					                              "fieldPath": "metadata.namespace"
 | 
				
			||||||
 | 
					                          }
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                   }
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "volumeMounts": [
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        "name": "datadir",
 | 
				
			||||||
 | 
					                        "mountPath": "/cockroach/cockroach-data"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]'
 | 
				
			||||||
    spec:
 | 
					    spec:
 | 
				
			||||||
      containers:
 | 
					      containers:
 | 
				
			||||||
      - name: cockroachdb
 | 
					      - name: cockroachdb
 | 
				
			||||||
@@ -93,27 +138,23 @@ spec:
 | 
				
			|||||||
          - |
 | 
					          - |
 | 
				
			||||||
            # The use of qualified `hostname -f` is crucial:
 | 
					            # The use of qualified `hostname -f` is crucial:
 | 
				
			||||||
            # Other nodes aren't able to look up the unqualified hostname.
 | 
					            # Other nodes aren't able to look up the unqualified hostname.
 | 
				
			||||||
            CRARGS=("start" "--logtostderr" "--insecure" "--host" "$(hostname -f)")
 | 
					            CRARGS=("start" "--logtostderr" "--insecure" "--host" "$(hostname -f)" "--http-host" "0.0.0.0")
 | 
				
			||||||
            # TODO(tschottdorf): really want to use an init container to do
 | 
					            # We only want to initialize a new cluster (by omitting the join flag)
 | 
				
			||||||
            # the bootstrapping. The idea is that the container would know
 | 
					            # if we're sure that we're the first node (i.e. index 0) and that
 | 
				
			||||||
            # whether it's on the first node and could check whether there's
 | 
					            # there aren't any other nodes running as part of the cluster that
 | 
				
			||||||
            # already a data directory. If not, it would bootstrap the cluster.
 | 
					            # this is supposed to be a part of (which indicates that a cluster
 | 
				
			||||||
            # We will need some version of `cockroach init` back for this to
 | 
					            # already exists and we should make sure not to create a new one).
 | 
				
			||||||
            # work. For now, just do the same in a shell snippet.
 | 
					            # It's fine to run without --join on a restart if there aren't any
 | 
				
			||||||
            # Of course this isn't without danger - if node0 loses its data,
 | 
					            # other nodes.
 | 
				
			||||||
            # 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" ] || \
 | 
					            if [ ! "$(hostname)" == "cockroachdb-0" ] || \
 | 
				
			||||||
               [ -e "/cockroach/cockroach-data/COCKROACHDB_VERSION" ]
 | 
					               [ -e "/cockroach/cockroach-data/cluster_exists_marker" ]
 | 
				
			||||||
            then
 | 
					            then
 | 
				
			||||||
              CRARGS+=("--join" "cockroachdb")
 | 
					              # We don't join cockroachdb in order to avoid a node attempting
 | 
				
			||||||
 | 
					              # to join itself, which currently doesn't work
 | 
				
			||||||
 | 
					              # (https://github.com/cockroachdb/cockroach/issues/9625).
 | 
				
			||||||
 | 
					              CRARGS+=("--join" "cockroachdb-public")
 | 
				
			||||||
            fi
 | 
					            fi
 | 
				
			||||||
            /cockroach/cockroach ${CRARGS[*]}
 | 
					            exec /cockroach/cockroach ${CRARGS[*]}
 | 
				
			||||||
      # No pre-stop hook is required, a SIGTERM plus some time is all that's
 | 
					      # No pre-stop hook is required, a SIGTERM plus some time is all that's
 | 
				
			||||||
      # needed for graceful shutdown of a node.
 | 
					      # needed for graceful shutdown of a node.
 | 
				
			||||||
      terminationGracePeriodSeconds: 60
 | 
					      terminationGracePeriodSeconds: 60
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ kubectl delete petsets,pods,persistentvolumes,persistentvolumeclaims,services -l
 | 
				
			|||||||
# claims here manually even though that sounds counter-intuitive. For details
 | 
					# claims here manually even though that sounds counter-intuitive. For details
 | 
				
			||||||
# see https://github.com/kubernetes/contrib/pull/1295#issuecomment-230180894.
 | 
					# 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.
 | 
					# Note that we make an extra volume here so you can manually test scale-up.
 | 
				
			||||||
for i in $(seq 0 5); do
 | 
					for i in $(seq 0 3); do
 | 
				
			||||||
  cat <<EOF | kubectl create -f -
 | 
					  cat <<EOF | kubectl create -f -
 | 
				
			||||||
kind: PersistentVolume
 | 
					kind: PersistentVolume
 | 
				
			||||||
apiVersion: v1
 | 
					apiVersion: v1
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user