Skip to content

Commit 487b7b1

Browse files
Tim Bannistertengqmdivya-mohan0209
committed
Revise StatefulSet tutorial
Co-authored-by: Qiming Teng <[email protected]> Co-authored-by: Divya Mohan <[email protected]>
1 parent 9a9038f commit 487b7b1

File tree

1 file changed

+77
-45
lines changed

1 file changed

+77
-45
lines changed

content/en/docs/tutorials/stateful-application/basic-stateful-set.md

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ After this tutorial, you will be familiar with the following.
6868

6969
## Creating a StatefulSet
7070

71-
Begin by creating a StatefulSet using the example below. It is similar to the
72-
example presented in the
71+
Begin by creating a StatefulSet (and the Service that it relies upon) using
72+
the example below. It is similar to the example presented in the
7373
[StatefulSets](/docs/concepts/workloads/controllers/statefulset/) concept.
7474
It creates a [headless Service](/docs/concepts/services-networking/service/#headless-services),
7575
`nginx`, to publish the IP addresses of Pods in the StatefulSet, `web`.
@@ -118,6 +118,8 @@ web 2 1 20s
118118

119119
### Ordered Pod creation
120120

121+
A StatefulSet defaults to creating its Pods in a strict order.
122+
121123
For a StatefulSet with _n_ replicas, when Pods are being deployed, they are
122124
created sequentially, ordered from _{0..n-1}_. Examine the output of the
123125
`kubectl get` command in the first terminal. Eventually, the output will
@@ -144,6 +146,8 @@ Notice that the `web-1` Pod is not launched until the `web-0` Pod is
144146
_Running_ (see [Pod Phase](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase))
145147
and _Ready_ (see `type` in [Pod Conditions](/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions)).
146148

149+
Later in this tutorial you will practice [parallel startup](#parallel-pod-management).
150+
147151
{{< note >}}
148152
To configure the integer ordinal assigned to each Pod in a StatefulSet, see
149153
[Start ordinal](/docs/concepts/workloads/controllers/statefulset/#start-ordinal).
@@ -300,7 +304,8 @@ Address 1: 10.244.2.8
300304
The Pods' ordinals, hostnames, SRV records, and A record names have not changed,
301305
but the IP addresses associated with the Pods may have changed. In the cluster
302306
used for this tutorial, they have. This is why it is important not to configure
303-
other applications to connect to Pods in a StatefulSet by IP address.
307+
other applications to connect to Pods in a StatefulSet by the IP address
308+
of a particular Pod (it is OK to connect to Pods by resolving their hostname).
304309

305310
#### Discovery for specific Pods in a StatefulSet
306311

@@ -317,6 +322,13 @@ liveness and readiness, you can use the SRV records of the Pods (
317322
application will be able to discover the Pods' addresses when they transition
318323
to Running and Ready.
319324

325+
If your application wants to find any healthy Pod in a StatefulSet,
326+
and therefore does not need to track each specific Pod,
327+
you could also connect to the IP address of a `type: ClusterIP` Service,
328+
backed by the Pods in that StatefulSet. You can use the same Service that
329+
tracks the StatefulSet (specified in the `serviceName` of the StatefulSet)
330+
or a separate Service that selects the right set of Pods.
331+
320332
### Writing to stable storage
321333

322334
Get the PersistentVolumeClaims for `web-0` and `web-1`:
@@ -421,13 +433,18 @@ mounted to the appropriate mount points.
421433

422434
## Scaling a StatefulSet
423435

424-
Scaling a StatefulSet refers to increasing or decreasing the number of replicas.
436+
Scaling a StatefulSet refers to increasing or decreasing the number of replicas
437+
(horizontal scaling).
425438
This is accomplished by updating the `replicas` field. You can use either
426439
[`kubectl scale`](/docs/reference/generated/kubectl/kubectl-commands/#scale) or
427440
[`kubectl patch`](/docs/reference/generated/kubectl/kubectl-commands/#patch) to scale a StatefulSet.
428441

429442
### Scaling up
430443

444+
Scaling up means adding more replicas.
445+
Provided that your app is able to distribute work across the StatefulSet, the new
446+
larger set of Pods can perform more of that work.
447+
431448
In one terminal window, watch the Pods in the StatefulSet:
432449

433450
```shell
@@ -481,6 +498,10 @@ subsequent Pod.
481498

482499
### Scaling down
483500

501+
Scaling down means reducing the number of replicas. For example, you
502+
might do this because the level of traffic to a service has decreased,
503+
and at the current scale there are idle resources.
504+
484505
In one terminal, watch the StatefulSet's Pods:
485506

486507
```shell
@@ -521,9 +542,9 @@ web-3 1/1 Terminating 0 42s
521542

522543
### Ordered Pod termination
523544

524-
The controller deleted one Pod at a time, in reverse order with respect to its
525-
ordinal index, and it waited for each to be completely shutdown before
526-
deleting the next.
545+
The control plane deleted one Pod at a time, in reverse order with respect
546+
to its ordinal index, and it waited for each Pod to be completely shut down
547+
before deleting the next one.
527548

528549
Get the StatefulSet's PersistentVolumeClaims:
529550

@@ -541,7 +562,10 @@ www-web-4 Bound pvc-e11bb5f8-b508-11e6-932f-42010a800002 1Gi RWO
541562
```
542563

543564
There are still five PersistentVolumeClaims and five PersistentVolumes.
544-
When exploring a Pod's [stable storage](#writing-to-stable-storage), we saw that the PersistentVolumes mounted to the Pods of a StatefulSet are not deleted when the StatefulSet's Pods are deleted. This is still true when Pod deletion is caused by scaling the StatefulSet down.
565+
When exploring a Pod's [stable storage](#writing-to-stable-storage), you saw that
566+
the PersistentVolumes mounted to the Pods of a StatefulSet are not deleted when the
567+
StatefulSet's Pods are deleted. This is still true when Pod deletion is caused by
568+
scaling the StatefulSet down.
545569

546570
## Updating StatefulSets
547571

@@ -1145,16 +1169,35 @@ For some distributed systems, the StatefulSet ordering guarantees are
11451169
unnecessary and/or undesirable. These systems require only uniqueness and
11461170
identity.
11471171

1148-
You can specify a Pod management policy to avoid this strict ordering;
1149-
either [`OrderedReady`](/docs/concepts/workloads/controllers/statefulset/#orderedready-pod-management) (the default)
1150-
or [`Parallel`](/docs/concepts/workloads/controllers/statefulset/#parallel-pod-management).
1172+
You can specify a [Pod management policy](/docs/concepts/workloads/controllers/statefulset/#pod-management-policies)
1173+
to avoid this strict ordering; either `OrderedReady` (the default), or `Parallel`.
1174+
1175+
### OrderedReady Pod management
1176+
1177+
`OrderedReady` pod management is the default for StatefulSets. It tells the
1178+
StatefulSet controller to respect the ordering guarantees demonstrated
1179+
above.
1180+
1181+
Use this when your application requires or expects that changes, such as rolling out a new
1182+
version of your application, happen in the strict order of the ordinal (pod number) that the StatefulSet provides.
1183+
In other words, if you have Pods `app-0`, `app-1` and `app-2`, Kubernetes will update `app-0` first and check it.
1184+
Once the checks are good, Kubernetes updates `app-1` and finally `app-2`.
1185+
1186+
If you added two more Pods, Kubernetes would set up `app-3` and wait for that to become healthy before deploying
1187+
`app-4`.
1188+
1189+
Because this is the default setting, you've already practised using it.
11511190

11521191
### Parallel Pod management
11531192

1154-
`Parallel` pod management tells the StatefulSet controller to launch or
1155-
terminate all Pods in parallel, and not to wait for Pods to become Running
1156-
and Ready or completely terminated prior to launching or terminating another
1157-
Pod. This option only affects the behavior for scaling operations. Updates are not affected.
1193+
The alternative, `Parallel` pod management, tells the StatefulSet controller to launch or
1194+
terminate all Pods in parallel, and not to wait for Pods to become `Running`
1195+
and `Ready` or completely terminated prior to launching or terminating another
1196+
Pod.
1197+
1198+
The `Parallel` pod management option only affects the behavior for scaling operations. Updates are not affected;
1199+
Kubernetes still rolls out changes in order. For this tutorial, the application is very simple: a webserver that
1200+
tells you its hostname (because this is a StatefulSet, the hostname for each Pod is different and predictable).
11581201

11591202
{{% code_sample file="application/web/web-parallel.yaml" %}}
11601203

@@ -1168,61 +1211,50 @@ In one terminal, watch the Pods in the StatefulSet.
11681211
kubectl get pod -l app=nginx --watch
11691212
```
11701213

1171-
In another terminal, create the StatefulSet and Service in the manifest:
1214+
In another terminal, reconfigure the StatefulSet for `Parallel` Pod management:
11721215

11731216
```shell
11741217
kubectl apply -f https://k8s.io/examples/application/web/web-parallel.yaml
11751218
```
11761219
```
1177-
service/nginx created
1178-
statefulset.apps/web created
1220+
service/nginx updated
1221+
statefulset.apps/web updated
11791222
```
11801223

1181-
Examine the output of the `kubectl get` command that you executed in the first terminal.
1182-
1183-
```shell
1184-
# This should already be running
1185-
kubectl get pod -l app=nginx --watch
1186-
```
1187-
```
1188-
NAME READY STATUS RESTARTS AGE
1189-
web-0 0/1 Pending 0 0s
1190-
web-0 0/1 Pending 0 0s
1191-
web-1 0/1 Pending 0 0s
1192-
web-1 0/1 Pending 0 0s
1193-
web-0 0/1 ContainerCreating 0 0s
1194-
web-1 0/1 ContainerCreating 0 0s
1195-
web-0 1/1 Running 0 10s
1196-
web-1 1/1 Running 0 10s
1197-
```
1198-
1199-
The StatefulSet controller launched both `web-0` and `web-1` at almost the
1200-
same time.
1201-
1202-
Keep the second terminal open, and, in another terminal window scale the
1224+
Keep the terminal open where you're running the watch. In another terminal window, scale the
12031225
StatefulSet:
12041226

12051227
```shell
1206-
kubectl scale statefulset/web --replicas=4
1228+
kubectl scale statefulset/web --replicas=5
12071229
```
12081230
```
12091231
statefulset.apps/web scaled
12101232
```
12111233

1212-
Examine the output of the terminal where the `kubectl get` command is running.
1234+
Examine the output of the terminal where the `kubectl get` command is running. It may look something like
12131235

12141236
```
12151237
web-3 0/1 Pending 0 0s
12161238
web-3 0/1 Pending 0 0s
12171239
web-3 0/1 Pending 0 7s
12181240
web-3 0/1 ContainerCreating 0 7s
1219-
web-2 1/1 Running 0 10s
1241+
web-2 0/1 Pending 0 0s
1242+
web-4 0/1 Pending 0 0s
1243+
web-2 1/1 Running 0 8s
1244+
web-4 0/1 ContainerCreating 0 4s
12201245
web-3 1/1 Running 0 26s
1246+
web-4 1/1 Running 0 2s
12211247
```
12221248

12231249

1224-
The StatefulSet launched two new Pods, and it did not wait for
1225-
the first to become Running and Ready prior to launching the second.
1250+
The StatefulSet launched three new Pods, and it did not wait for
1251+
the first to become Running and Ready prior to launching the second and third Pods.
1252+
1253+
This approach is useful if your workload has a stateful element, or needs Pods to be able to identify each other
1254+
with predictable naming, and especially if you sometimes need to provide a lot more capacity quickly. If this
1255+
simple web service for the tutorial suddenly got an extra 1,000,000 requests per minute then you would want to run
1256+
some more Pods - but you also would not want to wait for each new Pod to launch. Starting the extra Pods in parallel
1257+
cuts the time between requesting the extra capacity and having it available for use.
12261258

12271259
## {{% heading "cleanup" %}}
12281260

0 commit comments

Comments
 (0)