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  ```