mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 10:18:13 +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
	 Alex Robinson
					Alex Robinson