Skip to content

Commit 10ba719

Browse files
authored
Merge pull request #33791 from sftim/20200109_reword_replicated_stateful_app_task
Reword replicated stateful app task
2 parents 92d4bbf + eca7f75 commit 10ba719

File tree

4 files changed

+47
-32
lines changed

4 files changed

+47
-32
lines changed

content/en/docs/tasks/run-application/run-replicated-stateful-application.md

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ weight: 30
1414
<!-- overview -->
1515

1616
This page shows how to run a replicated stateful application using a
17-
[StatefulSet](/docs/concepts/workloads/controllers/statefulset/) controller.
17+
{{< glossary_tooltip term_id="statefulset" >}}.
1818
This application is a replicated MySQL database. The example topology has a
1919
single primary server and multiple replicas, using asynchronous row-based
2020
replication.
@@ -24,12 +24,10 @@ replication.
2424
on general patterns for running stateful applications in Kubernetes.
2525
{{< /note >}}
2626

27-
28-
2927
## {{% heading "prerequisites" %}}
3028

3129

32-
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
30+
* {{< include "task-tutorial-prereqs.md" >}}
3331
* {{< include "default-storage-class-prereqs.md" >}}
3432
* This tutorial assumes you are familiar with
3533
[PersistentVolumes](/docs/concepts/storage/persistent-volumes/)
@@ -46,7 +44,7 @@ on general patterns for running stateful applications in Kubernetes.
4644
## {{% heading "objectives" %}}
4745

4846

49-
* Deploy a replicated MySQL topology with a StatefulSet controller.
47+
* Deploy a replicated MySQL topology with a StatefulSet.
5048
* Send MySQL client traffic.
5149
* Observe resistance to downtime.
5250
* Scale the StatefulSet up and down.
@@ -60,7 +58,7 @@ on general patterns for running stateful applications in Kubernetes.
6058
The example MySQL deployment consists of a ConfigMap, two Services,
6159
and a StatefulSet.
6260

63-
### ConfigMap
61+
### Create a ConfigMap {#configmap}
6462

6563
Create the ConfigMap from the following YAML configuration file:
6664

@@ -71,7 +69,7 @@ kubectl apply -f https://k8s.io/examples/application/mysql/mysql-configmap.yaml
7169
```
7270

7371
This ConfigMap provides `my.cnf` overrides that let you independently control
74-
configuration on the primary MySQL server and replicas.
72+
configuration on the primary MySQL server and its replicas.
7573
In this case, you want the primary server to be able to serve replication logs to replicas
7674
and you want replicas to reject any writes that don't come via replication.
7775

@@ -80,7 +78,7 @@ portions to apply to different Pods.
8078
Each Pod decides which portion to look at as it's initializing,
8179
based on information provided by the StatefulSet controller.
8280

83-
### Services
81+
### Create Services {#services}
8482

8583
Create the Services from the following YAML configuration file:
8684

@@ -90,23 +88,24 @@ Create the Services from the following YAML configuration file:
9088
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-services.yaml
9189
```
9290

93-
The Headless Service provides a home for the DNS entries that the StatefulSet
94-
controller creates for each Pod that's part of the set.
95-
Because the Headless Service is named `mysql`, the Pods are accessible by
91+
The headless Service provides a home for the DNS entries that the StatefulSet
92+
{{< glossary_tooltip text="controllers" term_id="controller" >}} creates for each
93+
Pod that's part of the set.
94+
Because the headless Service is named `mysql`, the Pods are accessible by
9695
resolving `<pod-name>.mysql` from within any other Pod in the same Kubernetes
9796
cluster and namespace.
9897

99-
The Client Service, called `mysql-read`, is a normal Service with its own
98+
The client Service, called `mysql-read`, is a normal Service with its own
10099
cluster IP that distributes connections across all MySQL Pods that report
101100
being Ready. The set of potential endpoints includes the primary MySQL server and all
102101
replicas.
103102

104-
Note that only read queries can use the load-balanced Client Service.
103+
Note that only read queries can use the load-balanced client Service.
105104
Because there is only one primary MySQL server, clients should connect directly to the
106-
primary MySQL Pod (through its DNS entry within the Headless Service) to execute
105+
primary MySQL Pod (through its DNS entry within the headless Service) to execute
107106
writes.
108107

109-
### StatefulSet
108+
### Create the StatefulSet {#statefulset}
110109

111110
Finally, create the StatefulSet from the following YAML configuration file:
112111

@@ -122,7 +121,7 @@ You can watch the startup progress by running:
122121
kubectl get pods -l app=mysql --watch
123122
```
124123

125-
After a while, you should see all 3 Pods become Running:
124+
After a while, you should see all 3 Pods become `Running`:
126125

127126
```
128127
NAME READY STATUS RESTARTS AGE
@@ -132,8 +131,11 @@ mysql-2 2/2 Running 0 1m
132131
```
133132

134133
Press **Ctrl+C** to cancel the watch.
134+
135+
{{< note >}}
135136
If you don't see any progress, make sure you have a dynamic PersistentVolume
136-
provisioner enabled as mentioned in the [prerequisites](#before-you-begin).
137+
provisioner enabled, as mentioned in the [prerequisites](#before-you-begin).
138+
{{< /note >}}
137139

138140
This manifest uses a variety of techniques for managing stateful Pods as part of
139141
a StatefulSet. The next section highlights some of these techniques to explain
@@ -155,19 +157,18 @@ properties to perform orderly startup of MySQL replication.
155157
### Generating configuration
156158

157159
Before starting any of the containers in the Pod spec, the Pod first runs any
158-
[Init Containers](/docs/concepts/workloads/pods/init-containers/)
160+
[init containers](/docs/concepts/workloads/pods/init-containers/)
159161
in the order defined.
160162

161-
The first Init Container, named `init-mysql`, generates special MySQL config
163+
The first init container, named `init-mysql`, generates special MySQL config
162164
files based on the ordinal index.
163165

164166
The script determines its own ordinal index by extracting it from the end of
165167
the Pod name, which is returned by the `hostname` command.
166168
Then it saves the ordinal (with a numeric offset to avoid reserved values)
167169
into a file called `server-id.cnf` in the MySQL `conf.d` directory.
168170
This translates the unique, stable identity provided by the StatefulSet
169-
controller into the domain of MySQL server IDs, which require the same
170-
properties.
171+
into the domain of MySQL server IDs, which require the same properties.
171172

172173
The script in the `init-mysql` container also applies either `primary.cnf` or
173174
`replica.cnf` from the ConfigMap by copying the contents into `conf.d`.
@@ -187,7 +188,7 @@ logs might not go all the way back to the beginning of time.
187188
These conservative assumptions are the key to allow a running StatefulSet
188189
to scale up and down over time, rather than being fixed at its initial size.
189190

190-
The second Init Container, named `clone-mysql`, performs a clone operation on
191+
The second init container, named `clone-mysql`, performs a clone operation on
191192
a replica Pod the first time it starts up on an empty PersistentVolume.
192193
That means it copies all existing data from another running Pod,
193194
so its local state is consistent enough to begin replicating from the primary server.
@@ -202,7 +203,7 @@ Ready before starting Pod `N+1`.
202203

203204
### Starting replication
204205

205-
After the Init Containers complete successfully, the regular containers run.
206+
After the init containers complete successfully, the regular containers run.
206207
The MySQL Pods consist of a `mysql` container that runs the actual `mysqld`
207208
server, and an `xtrabackup` container that acts as a
208209
[sidecar](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns).
@@ -291,13 +292,13 @@ endpoint might be selected upon each connection attempt:
291292
You can press **Ctrl+C** when you want to stop the loop, but it's useful to keep
292293
it running in another window so you can see the effects of the following steps.
293294

294-
## Simulating Pod and Node downtime
295+
## Simulate Pod and Node failure {#simulate-pod-and-node-downtime}
295296

296297
To demonstrate the increased availability of reading from the pool of replicas
297298
instead of a single server, keep the `SELECT @@server_id` loop from above
298299
running while you force a Pod out of the Ready state.
299300

300-
### Break the Readiness Probe
301+
### Break the Readiness probe
301302

302303
The [readiness probe](/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)
303304
for the `mysql` container runs the command `mysql -h 127.0.0.1 -e 'SELECT 1'`
@@ -371,14 +372,18 @@ NAME READY STATUS RESTARTS AGE IP NODE
371372
mysql-2 2/2 Running 0 15m 10.244.5.27 kubernetes-node-9l2t
372373
```
373374

374-
Then drain the Node by running the following command, which cordons it so
375+
Then, drain the Node by running the following command, which cordons it so
375376
no new Pods may schedule there, and then evicts any existing Pods.
376377
Replace `<node-name>` with the name of the Node you found in the last step.
377378

378-
This might impact other applications on the Node, so it's best to
379-
**only do this in a test cluster**.
379+
{{< caution >}}
380+
Draining a Node can impact other workloads and applications
381+
running on the same node. Only perform the following step in a test
382+
cluster.
383+
{{< /caution >}}
380384

381385
```shell
386+
# See above advice about impact on other workloads
382387
kubectl drain <node-name> --force --delete-emptydir-data --ignore-daemonsets
383388
```
384389

@@ -413,8 +418,9 @@ kubectl uncordon <node-name>
413418

414419
## Scaling the number of replicas
415420

416-
With MySQL replication, you can scale your read query capacity by adding replicas.
417-
With StatefulSet, you can do this with a single command:
421+
When you use MySQL replication, you can scale your read query capacity by
422+
adding replicas.
423+
For a StatefulSet, you can achieve this with a single command:
418424

419425
```shell
420426
kubectl scale statefulset mysql --replicas=5
@@ -453,10 +459,13 @@ Scaling back down is also seamless:
453459
kubectl scale statefulset mysql --replicas=3
454460
```
455461

456-
Note, however, that while scaling up creates new PersistentVolumeClaims
462+
{{< note >}}
463+
Although scaling up creates new PersistentVolumeClaims
457464
automatically, scaling down does not automatically delete these PVCs.
465+
458466
This gives you the choice to keep those initialized PVCs around to make
459467
scaling back up quicker, or to extract data before deleting them.
468+
{{< /note >}}
460469

461470
You can see this by running:
462471

content/en/examples/application/mysql/mysql-configmap.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ metadata:
44
name: mysql
55
labels:
66
app: mysql
7+
app.kubernetes.io/name: mysql
78
data:
89
primary.cnf: |
910
# Apply this config only on the primary.

content/en/examples/application/mysql/mysql-services.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ metadata:
55
name: mysql
66
labels:
77
app: mysql
8+
app.kubernetes.io/name: mysql
89
spec:
910
ports:
1011
- name: mysql
@@ -21,6 +22,8 @@ metadata:
2122
name: mysql-read
2223
labels:
2324
app: mysql
25+
app.kubernetes.io/name: mysql
26+
readonly: "true"
2427
spec:
2528
ports:
2629
- name: mysql

content/en/examples/application/mysql/mysql-statefulset.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ metadata:
55
spec:
66
selector:
77
matchLabels:
8-
app: mysql
8+
app: mysql-server
9+
app.kubernetes.io/name: mysql
910
serviceName: mysql
1011
replicas: 3
1112
template:
1213
metadata:
1314
labels:
1415
app: mysql
16+
app.kubernetes.io/name: mysql
1517
spec:
1618
initContainers:
1719
- name: init-mysql

0 commit comments

Comments
 (0)