github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/cloud/kubernetes/README.md (about) 1 # CockroachDB on Kubernetes as a StatefulSet 2 3 This example deploys CockroachDB on [Kubernetes](https://kubernetes.io) as a 4 [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/). 5 Kubernetes is an open source system for managing containerized applications 6 across multiple hosts, providing basic mechanisms for deployment, maintenance, 7 and scaling of applications. 8 9 This is a copy of the [similar example stored in the Kubernetes 10 repository](https://github.com/kubernetes/kubernetes/tree/master/examples/cockroachdb). 11 We keep a copy here as well for faster iteration, since merging things into 12 Kubernetes can be quite slow, particularly during the code freeze before 13 releases. The copy here will typically be more up-to-date. 14 15 Note that if all you want to do is run a single cockroachdb instance for 16 testing and don't care about data persistence, you can do so with just a single 17 command instead of following this guide (which sets up a more reliable cluster): 18 19 ```shell 20 kubectl run cockroachdb --image=cockroachdb/cockroach --restart=Never -- start-single-node --insecure --logtostderr 21 ``` 22 23 ## Limitations 24 25 ### Kubernetes version 26 27 The minimum Kubernetes version to successfully run the examples in this 28 directory without modification is `1.8`. If you want to run them on an older 29 version of Kubernetes, use the files from the appropriate subdirectory (e.g. the 30 `v1.7` directory for Kubernetes 1.7 or the `v1.6` directory for Kubernetes 1.6). 31 Older Kubernetes versions that don't have their own directory are no longer 32 supported. 33 34 For secure mode, the controller must enable `certificatesigningrequests`. 35 You can check if this is enabled by looking at the controller logs: 36 ``` 37 # On cloud platform: 38 # Find the controller: 39 $ kubectl get pods --all-namespaces | grep controller 40 kube-system po/kube-controller-manager-k8s-master-5ef244d4-0 1/1 Running 0 7m 41 42 # Check the logs: 43 $ kubectl logs kube-controller-manager-k8s-master-5ef244d4-0 -n kube-system | grep certificate 44 I0628 12:38:23.471365 1 controllermanager.go:427] Starting "certificatesigningrequests" 45 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 46 W0628 12:38:23.473106 1 controllermanager.go:434] Skipping "certificatesigningrequests" 47 # This shows that the certificate controller is not running, approved CSRs will not trigger a certificate. 48 49 # On minikube: 50 $ minikube logs | grep certificate 51 Jun 28 12:49:00 minikube localkube[3440]: I0628 12:49:00.224903 3440 controllermanager.go:437] Started "certificatesigningrequests" 52 Jun 28 12:49:00 minikube localkube[3440]: I0628 12:49:00.231134 3440 certificate_controller.go:120] Starting certificate controller manager 53 # This shows that the certificate controller is running, approved CSRs will get a certificate. 54 55 ``` 56 57 ### StatefulSet limitations 58 59 Node-local storage for StatefulSets was only recently promoted to beta as a 60 Kubernetes feature (known as [local persistent 61 volumes](https://kubernetes.io/docs/concepts/storage/volumes/#local)), so we 62 don't yet recommend running that way in production. Instead, these examples use 63 dynamically provisioned remote persistent volumes. Note that CockroachDB already 64 replicates its data and thus, for the best performance, should not be deployed 65 on a persistent volume which already replicates internally. High-performance use 66 cases that need the very best performance may want to consider a 67 [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) 68 deployment until node-local storage has been more rigorously hardened. 69 70 ### Secure mode 71 72 Secure mode currently works by requesting node/client certificates from the kubernetes controller at pod initialization time. 73 74 ### Geographically distributed clusters 75 76 The configuration files and instructions in this directory are limited to 77 deployments that exist entirely within a single Kubernetes cluster. If you'd 78 like to deploy CockroachDB across multiple geographically distributed Kubernetes 79 clusters, see the [multiregion subdirectory](multiregion). 80 81 ## Creating your kubernetes cluster 82 83 ### Locally on minikube 84 85 Set up your minikube cluster following the 86 [instructions provided in the Kubernetes docs](https://kubernetes.io/docs/getting-started-guides/minikube/). 87 88 ### On AWS 89 90 Set up your cluster following the 91 [instructions provided in the Kubernetes docs](https://kubernetes.io/docs/getting-started-guides/aws/). 92 93 ### On GCE 94 95 You can either set up your cluster following the 96 [instructions provided in the Kubernetes docs](https://kubernetes.io/docs/getting-started-guides/gce/) 97 or by using the hosted 98 [Google Kubernetes Engine (GKE)](https://cloud.google.com/container-engine/docs) service: 99 100 ```shell 101 gcloud container clusters create NAME 102 ``` 103 104 If you're using GKE and want to run a secure cluster, one extra step is 105 required. A limitation in GKE's Role-Based Access Control (RBAC) integration 106 necessitates running a special command in order to let you create the RBAC 107 roles that CockroachDB needs to manage certificates. 108 109 1. Get the email address associated with your Google Cloud account by running: 110 ```shell 111 `gcloud info | grep Account` 112 ``` 113 2. Run [the following command from the GKE 114 documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#prerequisites_for_using_role-based_access_control) 115 with that email address: 116 ```shell 117 kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=<your.google.cloud.email@example.org> 118 ``` 119 120 ### On Azure 121 122 Set up your cluster following the 123 [instructions provided in the Kubernetes docs](https://kubernetes.io/docs/getting-started-guides/azure/). 124 125 126 ## Creating the cockroach cluster 127 128 Once your kubernetes cluster is up and running, you can launch your cockroach cluster. 129 130 ### Insecure mode 131 132 To create the cluster, run: 133 ```shell 134 kubectl create -f cockroachdb-statefulset.yaml 135 ``` 136 137 Then, to initialize the cluster, run: 138 ```shell 139 kubectl create -f cluster-init.yaml 140 ``` 141 142 ### Secure mode 143 144 #### Prerequisites 145 146 **REQUIRED**: the kubernetes cluster must run with the certificate controller enabled. 147 This is done by passing the `--cluster-signing-cert-file` and `--cluster-signing-key-file` flags. 148 If you are using minikube v0.23.0 or newer (run `minikube version` if you aren't sure), you can 149 tell it to use the minikube-generated CA by specifying: 150 ```shell 151 minikube start --extra-config=controller-manager.ClusterSigningCertFile="/var/lib/localkube/certs/ca.crt" --extra-config=controller-manager.ClusterSigningKeyFile="/var/lib/localkube/certs/ca.key" 152 ``` 153 154 If you're running on an older version of minikube, you can similarly run: 155 ```shell 156 minikube start --extra-config=controller-manager.ClusterSigningCertFile="/var/lib/localkube/ca.crt" --extra-config=controller-manager.ClusterSigningKeyFile="/var/lib/localkube/ca.key" 157 ``` 158 159 #### Creating the cluster 160 161 Run: `kubectl create -f cockroachdb-statefulset-secure.yaml` 162 163 If you get an error saying "attempt to grant extra privileges", you don't have 164 sufficient permissions in the cluster to manage certificates. If this happens 165 and you're running on Google Kubernetes Engine, see [the note above](#on-gce). 166 If not, talk to your cluster administrator. 167 168 Each new node will request a certificate from the kubernetes CA during its initialization phase. 169 We have configured the StatefulSet to bring up all its pods at once, so you can approve all of 170 the pods' certificates in quick succession. 171 172 If a pod is rescheduled, it will reuse the previously-generated certificate. 173 174 You can view pending certificates and approve them using: 175 ``` 176 # List CSRs: 177 $ kubectl get csr 178 NAME AGE REQUESTOR CONDITION 179 default.node.cockroachdb-0 4s system:serviceaccount:default:default Pending 180 default.node.cockroachdb-1 4s system:serviceaccount:default:default Pending 181 default.node.cockroachdb-2 4s system:serviceaccount:default:default Pending 182 183 # Examine the CSR: 184 $ kubectl describe csr default.node.cockroachdb-0 185 Name: default.node.cockroachdb-0 186 Labels: <none> 187 Annotations: <none> 188 CreationTimestamp: Thu, 22 Jun 2017 09:56:49 -0400 189 Requesting User: system:serviceaccount:default:default 190 Status: Pending 191 Subject: 192 Common Name: node 193 Serial Number: 194 Organization: Cockroach 195 Subject Alternative Names: 196 DNS Names: localhost 197 cockroachdb-0.cockroachdb.default.svc.cluster.local 198 cockroachdb-public 199 IP Addresses: 127.0.0.1 200 172.17.0.5 201 Events: <none> 202 203 # If everything checks out, approve the CSR: 204 $ kubectl certificate approve default.node.cockroachdb-0 205 certificatesigningrequest "default.node.cockroachdb-0" approved 206 207 # Otherwise, deny the CSR: 208 $ kubectl certificate deny default.node.cockroachdb-0 209 certificatesigningrequest "default.node.cockroachdb-0" denied 210 ``` 211 212 Once all the pods have started, to initialize the cluster run: 213 ```shell 214 kubectl create -f cluster-init-secure.yaml 215 ``` 216 217 This will create a CSR called "default.client.root", which you can approve by 218 running: 219 ```shell 220 kubectl certificate approve default.client.root 221 ``` 222 223 To confirm that it's done, run: 224 ```shell 225 kubectl get job cluster-init-secure 226 ``` 227 228 The output should look like: 229 ``` 230 NAME DESIRED SUCCESSFUL AGE 231 cluster-init-secure 1 1 5m 232 ``` 233 234 ## Accessing the database 235 236 Along with our StatefulSet configuration, we expose a standard Kubernetes service 237 that offers a load-balanced virtual IP for clients to access the database 238 with. In our example, we've called this service `cockroachdb-public`. 239 240 In insecure mode, start up a client pod and open up an interactive, (mostly) Postgres-flavor 241 SQL shell: 242 243 ```shell 244 kubectl run cockroachdb -it --image=cockroachdb/cockroach --rm --restart=Never \ 245 -- sql --insecure --host=cockroachdb-public 246 ``` 247 248 In secure mode, use our `client-secure.yaml` config to launch a pod that runs indefinitely with the `cockroach` binary inside it: 249 250 ```shell 251 kubectl create -f client-secure.yaml 252 ``` 253 254 Check and approve the CSR for the pod as described above, and then get a shell to the pod and run: 255 256 ```shell 257 kubectl exec -it cockroachdb-client-secure -- ./cockroach sql --certs-dir=/cockroach-certs --host=cockroachdb-public 258 ``` 259 260 You can see example SQL statements for inserting and querying data in the 261 included [demo script](demo.sh), but can use almost any Postgres-style SQL 262 commands. Some more basic examples can be found within 263 [CockroachDB's documentation](https://www.cockroachlabs.com/docs/stable/learn-cockroachdb-sql.html). 264 265 ## Accessing the admin UI 266 267 If you want to see information about how the cluster is doing, you can try 268 pulling up the CockroachDB admin UI by port-forwarding from your local machine 269 to one of the pods: 270 271 ```shell 272 kubectl port-forward cockroachdb-0 8080 273 ``` 274 275 Once you’ve done that, you should be able to access the admin UI by visiting 276 http://localhost:8080/ in your web browser. 277 278 ## Running the example app 279 280 This directory contains the configuration to launch a simple load generator with one pod. 281 282 If you created an insecure cockroach cluster, run: 283 ```shell 284 kubectl create -f example-app.yaml 285 ``` 286 287 If you created a secure cockroach cluster, run: 288 ```shell 289 kubectl create -f example-app-secure.yaml 290 ``` 291 292 When the first pod is being initialized, you will need to approve its client certificate request: 293 ```shell 294 kubectl certificate approve default.client.root 295 ``` 296 297 If more pods are then added through `kubectl scale deployment example-secure --replicas=X`, the generated 298 certificate will be reused. 299 **WARNING**: the example app in secure mode should be started with only one replica, or concurrent and 300 conflicting certificate requests will be sent, causing issues. 301 302 303 ## Secure client apps with other users 304 305 Applications should be run with a user other than `root`. This can be done using the following: 306 307 #### Create the desired user and database 308 309 Connect to the `cockroachdb-client-secure` pod (created in the "Accessing the database" section): 310 ```shell 311 kubectl exec -it cockroachdb-client-secure -- ./cockroach sql --certs-dir=/cockroach-certs --host=cockroachdb-public 312 ``` 313 314 Create the the app user, its database, and grant it privileges: 315 ```shell 316 root@:26257/defaultdb> CREATE USER myapp; 317 CREATE USER 1 318 319 Time: 164.811054ms 320 321 root@:26257/defaultdb> CREATE DATABASE myappdb; 322 CREATE DATABASE 323 324 Time: 153.44247ms 325 326 root@:26257/defaultdb> GRANT ALL ON DATABASE myappdb TO myapp; 327 GRANT 328 329 Time: 90.488168ms 330 ``` 331 332 #### Create the client pod 333 334 Modify [example-app-secure.yaml](example-app-secure.yaml) to match your user and app: 335 336 The init container `init-certs` needs to request a certificate and key for your new user: 337 ```shell 338 "/request-cert -namespace=${POD_NAMESPACE} -certs-dir=/cockroach-certs -type=client -user=myapp -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" 339 ``` 340 341 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: 342 ```shell 343 "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" 344 ``` 345 346 You can now create the client pod: 347 ```shell 348 kubectl create -f example-app-secure.yaml 349 ``` 350 351 #### Approve the client CSR 352 353 The init container sends a CSR and waits for approval. You can approve it using: 354 ```shell 355 kubectl certificate approve default.client.myapp 356 ``` 357 358 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. 359 360 361 ## Simulating failures 362 363 When all (or enough) nodes are up, simulate a failure like this: 364 365 ```shell 366 kubectl exec cockroachdb-0 -- /bin/bash -c "while true; do kill 1; done" 367 ``` 368 369 You can then reconnect to the database as demonstrated above and verify 370 that no data was lost. The example runs with three-fold replication, so 371 it can tolerate one failure of any given node at a time. Note also that 372 there is a brief period of time immediately after the creation of the 373 cluster during which the three-fold replication is established, and during 374 which killing a node may lead to unavailability. 375 376 The [demo script](demo.sh) gives an example of killing one instance of the 377 database and ensuring the other replicas have all data that was written. 378 379 ## Scaling up or down 380 381 Scale the StatefulSet by running 382 383 ```shell 384 kubectl scale statefulset cockroachdb --replicas=4 385 ``` 386 387 You should never scale the StatefulSet down by more than one replica at a time. 388 Doing so could lead to data unavailability. For best practices on safely 389 removing nodes from a safely, see our docs on [node 390 decommissioning](https://www.cockroachlabs.com/docs/stable/remove-nodes.html). 391 392 ## Doing a rolling upgrade to a different CockroachDB version 393 394 Open up the StatefulSet's current configuration in your default text editor 395 using the command below, find the line specifying the `cockroachdb/cockroach` 396 image being used, change the version tag to the new one, save the file, and 397 quit. 398 399 ```shell 400 kubectl edit statefulset cockroachdb 401 ``` 402 403 Kubernetes will then automatically replace the pods in your StatefulSet one by 404 one to run on the newly specified image. For more details on upgrading 405 CockroachDB, see [our 406 docs](https://www.cockroachlabs.com/docs/stable/upgrade-cockroach-version.html). 407 For how to use alternative rolling update commands such as `kubectl patch` and 408 `kubectl replace`, see the [Kubernetes 409 docs](https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#rolling-update). 410 411 ## Cleaning up when you're done 412 413 Because all of the resources in this example have been tagged with the label `app=cockroachdb`, 414 we can clean up everything that we created in one quick command using a selector on that label: 415 416 ```shell 417 kubectl delete statefulsets,pods,persistentvolumes,persistentvolumeclaims,services,poddisruptionbudget,jobs,rolebinding,clusterrolebinding,role,clusterrole,serviceaccount -l app=cockroachdb 418 ``` 419 420 If running in secure mode, you'll want to cleanup old certificate requests: 421 ```shell 422 kubectl delete csr --all 423 ```