Skip to content

Commit 26d14b6

Browse files
authored
Merge pull request #17995 from sftim/20191208_update_cassandra_statefulset_tutorial
Update Cassandra StatefulSet tutorial
2 parents f4dc270 + ded8bdb commit 26d14b6

File tree

1 file changed

+94
-80
lines changed

1 file changed

+94
-80
lines changed

content/en/docs/tutorials/stateful-application/cassandra.md

Lines changed: 94 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,72 @@
11
---
2-
title: "Example: Deploying Cassandra with Stateful Sets"
2+
title: "Example: Deploying Cassandra with a StatefulSet"
33
reviewers:
44
- ahmetb
55
content_template: templates/tutorial
66
weight: 30
77
---
88

99
{{% capture overview %}}
10-
This tutorial shows you how to develop a native cloud [Cassandra](http://cassandra.apache.org/) deployment on Kubernetes. In this example, a custom Cassandra *SeedProvider* enables Cassandra to discover new Cassandra nodes as they join the cluster.
10+
This tutorial shows you how to run [Apache Cassandra](http://cassandra.apache.org/) on Kubernetes. Cassandra, a database, needs persistent storage to provide data durability (application _state_). In this example, a custom Cassandra seed provider lets the database discover new Cassandra instances as they join the Cassandra cluster.
1111

12-
*StatefulSets* make it easier to deploy stateful applications within a clustered environment. For more information on the features used in this tutorial, see the [*StatefulSet*](/docs/concepts/workloads/controllers/statefulset/) documentation.
13-
14-
**Cassandra on Docker**
15-
16-
The *Pods* in this tutorial use the [`gcr.io/google-samples/cassandra:v13`](https://github.com/kubernetes/examples/blob/master/cassandra/image/Dockerfile)
17-
image from Google's [container registry](https://cloud.google.com/container-registry/docs/).
18-
The Docker image above is based on [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base)
19-
and includes OpenJDK 8.
20-
21-
This image includes a standard Cassandra installation from the Apache Debian repo.
22-
By using environment variables you can change values that are inserted into `cassandra.yaml`.
23-
24-
| ENV VAR | DEFAULT VALUE |
25-
| ------------- |:-------------: |
26-
| `CASSANDRA_CLUSTER_NAME` | `'Test Cluster'` |
27-
| `CASSANDRA_NUM_TOKENS` | `32` |
28-
| `CASSANDRA_RPC_ADDRESS` | `0.0.0.0` |
12+
*StatefulSets* make it easier to deploy stateful applications into your Kubernetes cluster. For more information on the features used in this tutorial, see [StatefulSet](/docs/concepts/workloads/controllers/statefulset/).
2913

14+
{{< note >}}
15+
Cassandra and Kubernetes both use the term _node_ to mean a member of a cluster. In this
16+
tutorial, the Pods that belong to the StatefulSet are Cassandra nodes and are members
17+
of the Cassandra cluster (called a _ring_). When those Pods run in your Kubernetes cluster,
18+
the Kubernetes control plane schedules those Pods onto Kubernetes
19+
{{< glossary_tooltip text="Nodes" term_id="node" >}}.
20+
21+
When a Cassandra node starts, it uses a _seed list_ to bootstrap discovery of other
22+
nodes in the ring.
23+
This tutorial deploys a custom Cassandra seed provider that lets the database discover
24+
new Cassandra Pods as they appear inside your Kubernetes cluster.
25+
{{< /note >}}
3026
{{% /capture %}}
3127

3228
{{% capture objectives %}}
33-
* Create and validate a Cassandra headless [*Service*](/docs/concepts/services-networking/service/).
34-
* Use a [StatefulSet](/docs/concepts/workloads/controllers/statefulset/) to create a Cassandra ring.
35-
* Validate the [StatefulSet](/docs/concepts/workloads/controllers/statefulset/).
36-
* Modify the [StatefulSet](/docs/concepts/workloads/controllers/statefulset/).
37-
* Delete the [StatefulSet](/docs/concepts/workloads/controllers/statefulset/) and its [Pods](/docs/concepts/workloads/pods/pod/).
29+
* Create and validate a Cassandra headless {{< glossary_tooltip text="Service" term_id="service" >}}.
30+
* Use a {{< glossary_tooltip term_id="StatefulSet" >}} to create a Cassandra ring.
31+
* Validate the StatefulSet.
32+
* Modify the StatefulSet.
33+
* Delete the StatefulSet and its {{< glossary_tooltip text="Pods" term_id="pod" >}}.
3834
{{% /capture %}}
3935

4036
{{% capture prerequisites %}}
41-
To complete this tutorial, you should already have a basic familiarity with [Pods](/docs/concepts/workloads/pods/pod/), [Services](/docs/concepts/services-networking/service/), and [StatefulSets](/docs/concepts/workloads/controllers/statefulset/). In addition, you should:
42-
43-
* [Install and Configure](/docs/tasks/tools/install-kubectl/) the *kubectl* command-line tool
37+
{{< include "task-tutorial-prereqs.md" >}}
4438

45-
* Download [`cassandra-service.yaml`](/examples/application/cassandra/cassandra-service.yaml)
46-
and [`cassandra-statefulset.yaml`](/examples/application/cassandra/cassandra-statefulset.yaml)
39+
To complete this tutorial, you should already have a basic familiarity with {{< glossary_tooltip text="Pods" term_id="pod" >}}, {{< glossary_tooltip text="Services" term_id="service" >}}, and {{< glossary_tooltip text="StatefulSets" term_id="StatefulSet" >}}.
4740

48-
* Have a supported Kubernetes cluster running
49-
50-
{{< note >}}
51-
Please read the [setup](/docs/setup/) if you do not already have a cluster.
52-
{{< /note >}}
53-
54-
### Additional Minikube Setup Instructions
41+
### Additional Minikube setup instructions
5542

5643
{{< caution >}}
57-
[Minikube](/docs/getting-started-guides/minikube/) defaults to 1024MB of memory and 1 CPU. Running Minikube with the default resource configuration results in insufficient resource errors during this tutorial. To avoid these errors, start Minikube with the following settings:
44+
[Minikube](/docs/getting-started-guides/minikube/) defaults to 1024MiB of memory and 1 CPU. Running Minikube with the default resource configuration results in insufficient resource errors during this tutorial. To avoid these errors, start Minikube with the following settings:
5845

5946
```shell
6047
minikube start --memory 5120 --cpus=4
6148
```
6249
{{< /caution >}}
63-
50+
6451
{{% /capture %}}
6552

6653
{{% capture lessoncontent %}}
67-
## Creating a Cassandra Headless Service
54+
## Creating a headless Service for Cassandra {#creating-a-cassandra-headless-service}
6855

69-
A Kubernetes [Service](/docs/concepts/services-networking/service/) describes a set of [Pods](/docs/concepts/workloads/pods/pod/) that perform the same task.
56+
In Kubernetes, a {{< glossary_tooltip text="Service" term_id="service" >}} describes a set of {{< glossary_tooltip text="Pods" term_id="pod" >}} that perform the same task.
7057

71-
The following `Service` is used for DNS lookups between Cassandra Pods and clients within the Kubernetes cluster.
58+
The following Service is used for DNS lookups between Cassandra Pods and clients within your cluster:
7259

7360
{{< codenew file="application/cassandra/cassandra-service.yaml" >}}
7461

75-
1. Launch a terminal window in the directory you downloaded the manifest files.
76-
1. Create a Service to track all Cassandra StatefulSet nodes from the `cassandra-service.yaml` file:
62+
Create a Service to track all Cassandra StatefulSet members from the `cassandra-service.yaml` file:
7763

78-
```shell
79-
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-service.yaml
80-
```
64+
```shell
65+
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-service.yaml
66+
```
8167

82-
### Validating (optional)
68+
69+
### Validating (optional) {#validating}
8370

8471
Get the Cassandra Service.
8572

@@ -94,9 +81,9 @@ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
9481
cassandra ClusterIP None <none> 9042/TCP 45s
9582
```
9683

97-
Service creation failed if anything else is returned. Read [Debug Services](/docs/tasks/debug-application-cluster/debug-service/) for common issues.
84+
If you don't see a Service named `cassandra`, that means creation failed. Read [Debug Services](/docs/tasks/debug-application-cluster/debug-service/) for help troubleshooting common issues.
9885

99-
## Using a StatefulSet to Create a Cassandra Ring
86+
## Using a StatefulSet to create a Cassandra ring
10087

10188
The StatefulSet manifest, included below, creates a Cassandra ring that consists of three Pods.
10289

@@ -106,60 +93,71 @@ This example uses the default provisioner for Minikube. Please update the follow
10693

10794
{{< codenew file="application/cassandra/cassandra-statefulset.yaml" >}}
10895

109-
1. Update the StatefulSet if necessary.
110-
1. Create the Cassandra StatefulSet from the `cassandra-statefulset.yaml` file:
96+
Create the Cassandra StatefulSet from the `cassandra-statefulset.yaml` file:
11197

112-
```shell
113-
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-statefulset.yaml
114-
```
98+
```shell
99+
# Use this if you are able to apply cassandra-statefulset.yaml unmodified
100+
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-statefulset.yaml
101+
```
102+
103+
If you need to modify `cassandra-statefulset.yaml` to suit your cluster, download
104+
https://k8s.io/examples/application/cassandra/cassandra-statefulset.yaml and then apply
105+
that manifest, from the folder you saved the modified version into:
106+
```shell
107+
# Use this if you needed to modify cassandra-statefulset.yaml locally
108+
kubectl apply -f cassandra-statefulset.yaml
109+
```
115110

116-
## Validating The Cassandra StatefulSet
111+
112+
## Validating the Cassandra StatefulSet
117113

118114
1. Get the Cassandra StatefulSet:
119115

120116
```shell
121117
kubectl get statefulset cassandra
122118
```
123119

124-
The response should be:
120+
The response should be similar to:
125121

126122
```
127123
NAME DESIRED CURRENT AGE
128124
cassandra 3 0 13s
129125
```
130126

131-
The `StatefulSet` resource deploys Pods sequentially.
127+
The `StatefulSet` resource deploys Pods sequentially.
132128

133129
1. Get the Pods to see the ordered creation status:
134130

135131
```shell
136132
kubectl get pods -l="app=cassandra"
137133
```
138-
139-
The response should be:
140-
134+
135+
The response should be similar to:
136+
141137
```shell
142138
NAME READY STATUS RESTARTS AGE
143139
cassandra-0 1/1 Running 0 1m
144140
cassandra-1 0/1 ContainerCreating 0 8s
145141
```
146-
147-
It can take several minutes for all three Pods to deploy. Once they are deployed, the same command returns:
148-
142+
143+
It can take several minutes for all three Pods to deploy. Once they are deployed, the same command
144+
returns output similar to:
145+
149146
```
150147
NAME READY STATUS RESTARTS AGE
151148
cassandra-0 1/1 Running 0 10m
152149
cassandra-1 1/1 Running 0 9m
153150
cassandra-2 1/1 Running 0 8m
154151
```
155152

156-
3. Run the Cassandra [nodetool](https://wiki.apache.org/cassandra/NodeTool) to display the status of the ring.
153+
3. Run the Cassandra [nodetool](https://cwiki.apache.org/confluence/display/CASSANDRA2/NodeTool) inside the first Pod, to
154+
display the status of the ring.
157155

158156
```shell
159157
kubectl exec -it cassandra-0 -- nodetool status
160158
```
161159

162-
The response should look something like this:
160+
The response should look something like:
163161

164162
```
165163
Datacenter: DC1-K8Demo
@@ -174,22 +172,22 @@ This example uses the default provisioner for Minikube. Please update the follow
174172

175173
## Modifying the Cassandra StatefulSet
176174

177-
Use `kubectl edit` to modify the size of a Cassandra StatefulSet.
175+
Use `kubectl edit` to modify the size of a Cassandra StatefulSet.
178176

179177
1. Run the following command:
180178

181179
```shell
182180
kubectl edit statefulset cassandra
183181
```
184182

185-
This command opens an editor in your terminal. The line you need to change is the `replicas` field. The following sample is an excerpt of the `StatefulSet` file:
183+
This command opens an editor in your terminal. The line you need to change is the `replicas` field. The following sample is an excerpt of the StatefulSet file:
186184

187185
```yaml
188186
# Please edit the object below. Lines beginning with a '#' will be ignored,
189187
# and an empty file will abort the edit. If an error occurs while saving this file will be
190188
# reopened with the relevant failures.
191189
#
192-
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
190+
apiVersion: apps/v1
193191
kind: StatefulSet
194192
metadata:
195193
creationTimestamp: 2016-08-13T18:40:58Z
@@ -204,50 +202,66 @@ Use `kubectl edit` to modify the size of a Cassandra StatefulSet.
204202
replicas: 3
205203
```
206204

207-
1. Change the number of replicas to 4, and then save the manifest.
205+
1. Change the number of replicas to 4, and then save the manifest.
208206

209-
The `StatefulSet` now contains 4 Pods.
207+
The StatefulSet now scales to run with 4 Pods.
210208

211-
1. Get the Cassandra StatefulSet to verify:
209+
1. Get the Cassandra StatefulSet to verify your change:
212210

213211
```shell
214212
kubectl get statefulset cassandra
215213
```
216214

217-
The response should be
215+
The response should be similar to:
218216

219217
```
220218
NAME DESIRED CURRENT AGE
221219
cassandra 4 4 36m
222220
```
223-
221+
224222
{{% /capture %}}
225223

226224
{{% capture cleanup %}}
227-
Deleting or scaling a StatefulSet down does not delete the volumes associated with the StatefulSet. This setting is for your safety because your data is more valuable than automatically purging all related StatefulSet resources.
225+
Deleting or scaling a StatefulSet down does not delete the volumes associated with the StatefulSet. This setting is for your safety because your data is more valuable than automatically purging all related StatefulSet resources.
228226

229227
{{< warning >}}
230228
Depending on the storage class and reclaim policy, deleting the *PersistentVolumeClaims* may cause the associated volumes to also be deleted. Never assume you’ll be able to access data if its volume claims are deleted.
231229
{{< /warning >}}
232230

233-
1. Run the following commands (chained together into a single command) to delete everything in the Cassandra `StatefulSet`:
231+
1. Run the following commands (chained together into a single command) to delete everything in the Cassandra StatefulSet:
234232

235233
```shell
236-
grace=$(kubectl get po cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}') \
234+
grace=$(kubectl get pod cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}') \
237235
&& kubectl delete statefulset -l app=cassandra \
238-
&& echo "Sleeping $grace" \
236+
&& echo "Sleeping ${grace} seconds" 1>&2 \
239237
&& sleep $grace \
240-
&& kubectl delete pvc -l app=cassandra
238+
&& kubectl delete persistentvolumeclaim -l app=cassandra
241239
```
242240

243-
1. Run the following command to delete the Cassandra Service.
241+
1. Run the following command to delete the Service you set up for Cassandra:
244242

245243
```shell
246244
kubectl delete service -l app=cassandra
247245
```
248246

249-
{{% /capture %}}
247+
## Cassandra container environment variables
248+
249+
The Pods in this tutorial use the [`gcr.io/google-samples/cassandra:v13`](https://github.com/kubernetes/examples/blob/master/cassandra/image/Dockerfile)
250+
image from Google's [container registry](https://cloud.google.com/container-registry/docs/).
251+
The Docker image above is based on [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base)
252+
and includes OpenJDK 8.
250253
254+
This image includes a standard Cassandra installation from the Apache Debian repo.
255+
By using environment variables you can change values that are inserted into `cassandra.yaml`.
256+
257+
| Environment variable | Default value |
258+
| ------------------------ |:---------------: |
259+
| `CASSANDRA_CLUSTER_NAME` | `'Test Cluster'` |
260+
| `CASSANDRA_NUM_TOKENS` | `32` |
261+
| `CASSANDRA_RPC_ADDRESS` | `0.0.0.0` |
262+
263+
264+
{{% /capture %}}
251265
{{% capture whatsnext %}}
252266
253267
* Learn how to [Scale a StatefulSet](/docs/tasks/run-application/scale-stateful-set/).

0 commit comments

Comments
 (0)