Reduce heading levels by 1.

This commit is contained in:
steveperry-53
2017-01-18 10:18:37 -08:00
parent 0f6b992771
commit 02d17ade5f
40 changed files with 178 additions and 187 deletions
+5 -5
View File
@@ -15,7 +15,7 @@ of Services, and how you can toggle this behavior according to your needs.
{% include task-tutorial-prereqs.md %}
### Terminology
## Terminology
This document makes use of the following terms:
@@ -26,7 +26,7 @@ This document makes use of the following terms:
* [Kube-proxy](/docs/user-guide/services/#virtual-ips-and-service-proxies): a network daemon that orchestrates Service VIP management on every node
### Prerequisites
## Prerequisites
You must have a working Kubernetes 1.5 cluster to run the examples in this
document. The examples use a small nginx webserver that echoes back the source
@@ -50,7 +50,7 @@ deployment "source-ip-app" created
{% capture lessoncontent %}
### Source IP for Services with Type=ClusterIP
## Source IP for Services with Type=ClusterIP
Packets sent to ClusterIP from within the cluster are never source NAT'd if
you're running kube-proxy in [iptables mode](/docs/user-guide/services/#proxy-mode-iptables),
@@ -107,7 +107,7 @@ command=GET
...
```
### Source IP for Services with Type=NodePort
## Source IP for Services with Type=NodePort
As of Kubernetes 1.5, packets sent to Services with [Type=NodePort](/docs/user-guide/services/#type-nodeport)
are source NAT'd by default. You can test this by creating a `NodePort` Service:
@@ -204,7 +204,7 @@ Visually:
### Source IP for Services with Type=LoadBalancer
## Source IP for Services with Type=LoadBalancer
As of Kubernetes 1.5, packets sent to Services with [Type=LoadBalancer](/docs/user-guide/services/#type-loadbalancer) are
source NAT'd by default, because all schedulable Kubernetes nodes in the
@@ -51,7 +51,7 @@ After this tutorial, you will be familiar with the following.
{% endcapture %}
{% capture lessoncontent %}
### Creating a StatefulSet
## Creating a StatefulSet
Begin by creating a StatefulSet using the example below. It is similar to the
example presented in the
@@ -95,7 +95,7 @@ NAME DESIRED CURRENT AGE
web 2 1 20s
```
#### Ordered Pod Creation
### Ordered Pod Creation
For a StatefulSet with N replicas, when Pods are being deployed, they are
created sequentially, in order from {0..N-1}. Examine the output of the
@@ -120,11 +120,11 @@ Notice that the `web-0` Pod is launched and set to Pending prior to
launching `web-1`. In fact, `web-1` is not launched until `web-0` is
[Running and Ready](/docs/user-guide/pod-states).
### Pods in a StatefulSet
## Pods in a StatefulSet
Unlike Pods in other controllers, the Pods in a StatefulSet have a unique
ordinal index and a stable network identity.
#### Examining the Pod's Ordinal Index
### Examining the Pod's Ordinal Index
Get the StatefulSet's Pods.
@@ -143,7 +143,7 @@ Set controller. The Pods' names take the form
`<statefulset name>-<ordinal index>`. Since the `web` StatefulSet has two
replicas, it creates two Pods, `web-0` and `web-1`.
#### Using Stable Network Identities
### Using Stable Network Identities
Each Pod has a stable hostname based on its ordinal index. Use
[`kubectl exec`](/docs/user-guide/kubectl/kubectl_exec/) to execute the
`hostname` command in each Pod.
@@ -253,7 +253,7 @@ liveness and readiness, you can use the SRV records of the Pods (
application will be able to discover the Pods' addresses when they transition
to Running and Ready.
#### Writing to Stable Storage
### Writing to Stable Storage
Get the PersistentVolumeClaims for `web-0` and `web-1`.
@@ -326,14 +326,14 @@ Volume Claims are remounted to their `volumeMount`s. No matter what node `web-0`
and `web-1` are scheduled on, their PersistentVolumes will be mounted to the
appropriate mount points.
### Scaling a StatefulSet
## Scaling a StatefulSet
Scaling a StatefulSet refers to increasing or decreasing the number of replicas.
This is accomplished by updating the `replicas` field. You can use either
[`kubectl scale`](/docs/user-guide/kubectl/kubectl_scale/) or
[`kubectl patch`](/docs/user-guide/kubectl/kubectl_patch/) to scale a Stateful
Set.
#### Scaling Up
### Scaling Up
In one terminal window, watch the Pods in the StatefulSet.
@@ -378,7 +378,7 @@ created each Pod sequentially with respect to its ordinal index, and it
waited for each Pod's predecessor to be Running and Ready before launching the
subsequent Pod.
#### Scaling Down
### Scaling Down
In one terminal, watch the StatefulSet's Pods.
@@ -412,7 +412,7 @@ web-3 1/1 Terminating 0 42s
web-3 1/1 Terminating 0 42s
```
#### Ordered Pod Termination
### Ordered Pod Termination
The controller deleted one Pod at a time, with respect to its ordinal index,
in reverse order, and it waited for each to be completely shutdown before
@@ -438,7 +438,7 @@ the StatefulSet's Pods are deleted. This is still true when Pod deletion is
caused by scaling the StatefulSet down. This feature can be used to facilitate
upgrading the container images of Pods in a StatefulSet.
### Updating Containers
## Updating Containers
As demonstrated in the [Scaling a StatefulSet](#scaling-a-statefulset) section,
the `replicas` field of a StatefulSet is mutable. The only other field of a
StatefulSet that can be updated is the `spec.template.containers` field.
@@ -530,14 +530,14 @@ gcr.io/google_containers/nginx-slim:0.7
All the Pods in the StatefulSet are now running a new container image.
### Deleting StatefulSets
## Deleting StatefulSets
StatefulSet supports both Non-Cascading and Cascading deletion. In a
Non-Cascading Delete, the StatefulSet's Pods are not deleted when the Stateful
Set is deleted. In a Cascading Delete, both the StatefulSet and its Pods are
deleted.
#### Non-Cascading Delete
### Non-Cascading Delete
In one terminal window, watch the Pods in the StatefulSet.
@@ -643,7 +643,7 @@ because the StatefulSet never deletes the PersistentVolumes associated with a
Pod. When you recreated the StatefulSet and it relaunched `web-0`, its original
PersistentVolume was remounted.
#### Cascading Delete
### Cascading Delete
In one terminal window, watch the Pods in the StatefulSet.
@@ -49,12 +49,12 @@ on general patterns for running stateful applications in Kubernetes.
{% capture lessoncontent %}
### Deploying MySQL
## Deploying MySQL
The example MySQL deployment consists of a ConfigMap, two Services,
and a StatefulSet.
#### ConfigMap
### ConfigMap
Create the ConfigMap from the following YAML configuration file:
@@ -74,7 +74,7 @@ portions to apply to different Pods.
Each Pod decides which portion to look at as it's initializing,
based on information provided by the StatefulSet controller.
#### Services
### Services
Create the Services from the following YAML configuration file:
@@ -100,7 +100,7 @@ Because there is only one MySQL master, clients should connect directly to the
MySQL master Pod (through its DNS entry within the Headless Service) to execute
writes.
#### StatefulSet
### StatefulSet
Finally, create the StatefulSet from the following YAML configuration file:
@@ -133,7 +133,7 @@ This manifest uses a variety of techniques for managing stateful Pods as part of
a StatefulSet. The next section highlights some of these techniques to explain
what happens as the StatefulSet creates Pods.
### Understanding stateful Pod initialization
## Understanding stateful Pod initialization
The StatefulSet controller starts Pods one at a time, in order by their
ordinal index.
@@ -146,7 +146,7 @@ In this case, that results in Pods named `mysql-0`, `mysql-1`, and `mysql-2`.
The Pod template in the above StatefulSet manifest takes advantage of these
properties to perform orderly startup of MySQL replication.
#### Generating configuration
### Generating configuration
Before starting any of the containers in the Pod spec, the Pod first runs any
[Init Containers](/docs/user-guide/production-pods/#handling-initialization)
@@ -175,7 +175,7 @@ Combined with the StatefulSet controller's
this ensures the MySQL master is Ready before creating slaves, so they can begin
replicating.
#### Cloning existing data
### Cloning existing data
In general, when a new Pod joins the set as a slave, it must assume the MySQL
master might already have data on it. It also must assume that the replication
@@ -196,7 +196,7 @@ from the Pod whose ordinal index is one lower.
This works because the StatefulSet controller always ensures Pod `N` is
Ready before starting Pod `N+1`.
#### Starting replication
### Starting replication
After the Init Containers complete successfully, the regular containers run.
The MySQL Pods consist of a `mysql` container that runs the actual `mysqld`
@@ -220,7 +220,7 @@ connections from other Pods requesting a data clone.
This server remains up indefinitely in case the StatefulSet scales up, or in
case the next Pod loses its PersistentVolumeClaim and needs to redo the clone.
### Sending client traffic
## Sending client traffic
You can send test queries to the MySQL master (hostname `mysql-0.mysql`)
by running a temporary container with the `mysql:5.7` image and running the
@@ -287,13 +287,13 @@ endpoint might be selected upon each connection attempt:
You can press **Ctrl+C** when you want to stop the loop, but it's useful to keep
it running in another window so you can see the effects of the following steps.
### Simulating Pod and Node downtime
## Simulating Pod and Node downtime
To demonstrate the increased availability of reading from the pool of slaves
instead of a single server, keep the `SELECT @@server_id` loop from above
running while you force a Pod out of the Ready state.
#### Break the Readiness Probe
### Break the Readiness Probe
The [readiness probe](/docs/user-guide/production-pods/#liveness-and-readiness-probes-aka-health-checks)
for the `mysql` container runs the command `mysql -h 127.0.0.1 -e 'SELECT 1'`
@@ -333,7 +333,7 @@ after a few seconds:
kubectl exec mysql-2 -c mysql -- mv /usr/bin/mysql.off /usr/bin/mysql
```
#### Delete Pods
### Delete Pods
The StatefulSet also recreates Pods if they're deleted, similar to what a
ReplicaSet does for stateless Pods.
@@ -348,7 +348,7 @@ PersistentVolumeClaim.
You should see server ID `102` disappear from the loop output for a while
and then return on its own.
#### Drain a Node
### Drain a Node
If your Kubernetes cluster has multiple Nodes, you can simulate Node downtime
(such as when Nodes are upgraded) by issuing a
@@ -407,7 +407,7 @@ Now uncordon the Node to return it to a normal state:
kubectl uncordon <node-name>
```
### Scaling the number of slaves
## Scaling the number of slaves
With MySQL replication, you can scale your read query capacity by adding slaves.
With StatefulSet, you can do this with a single command:
@@ -37,7 +37,7 @@ application is MySQL.
{% capture lessoncontent %}
### Set up a disk in your environment
## Set up a disk in your environment
You can use any type of persistent volume for your stateful app. See
[Types of Persistent Volumes](/docs/user-guide/persistent-volumes/#types-of-persistent-volumes)
@@ -66,7 +66,7 @@ kubectl create -f http://k8s.io/docs/tutorials/stateful-application/gce-volume.y
```
### Deploy MySQL
## Deploy MySQL
You can run a stateful application by creating a Kubernetes Deployment
and connecting it to an existing PersistentVolume using a
@@ -146,7 +146,7 @@ for a secure solution.
Access Modes: RWO
No events.
### Accessing the MySQL instance
## Accessing the MySQL instance
The preceding YAML file creates a service that
allows other Pods in the cluster to access the database. The Service option
@@ -171,7 +171,7 @@ If you don't see a command prompt, try pressing enter.
mysql>
```
### Updating
## Updating
The image or any other part of the Deployment can be updated as usual
with the `kubectl apply` command. Here are some precautions that are
@@ -187,7 +187,7 @@ specific to stateful apps:
one Pod running at a time. The `Recreate` strategy will stop the
first pod before creating a new one with the updated configuration.
### Deleting a deployment
## Deleting a deployment
Delete the deployed objects by name:
@@ -58,7 +58,7 @@ After this tutorial, you will know the following.
{% capture lessoncontent %}
#### ZooKeeper Basics
### ZooKeeper Basics
[Apache ZooKeeper](https://zookeeper.apache.org/doc/current/) is a
distributed, open-source coordination service for distributed applications.
@@ -86,7 +86,7 @@ snapshot their in memory state to storage media. These snapshots can be loaded
directly into memory, and all WAL entries that preceded the snapshot may be
safely discarded.
### Creating a ZooKeeper Ensemble
## Creating a ZooKeeper Ensemble
The manifest below contains a
[Headless Service](/docs/user-guide/services/#headless-services),
@@ -145,7 +145,7 @@ zk-2 1/1 Running 0 40s
The StatefulSet controller creates three Pods, and each Pod has a container with
a [ZooKeeper 3.4.9](http://www-us.apache.org/dist/zookeeper/zookeeper-3.4.9/) server.
#### Facilitating Leader Election
### Facilitating Leader Election
As there is no terminating algorithm for electing a leader in an anonymous
network, Zab requires explicit membership configuration in order to perform
@@ -242,7 +242,7 @@ server.2=zk-1.zk-headless.default.svc.cluster.local:2888:3888
server.3=zk-2.zk-headless.default.svc.cluster.local:2888:3888
```
#### Achieving Consensus
### Achieving Consensus
Consensus protocols require that the identifiers of each participant be
unique. No two participants in the Zab protocol should claim the same unique
@@ -301,7 +301,7 @@ and at least two of the Pods are Running and Ready), or they will fail to do so
(if either of the aforementioned conditions are not met). No state will arise
where one server acknowledges a write on behalf of another.
#### Sanity Testing the Ensemble
### Sanity Testing the Ensemble
The most basic sanity test is to write some data to one ZooKeeper server and
to read the data from another.
@@ -348,7 +348,7 @@ dataLength = 5
numChildren = 0
```
#### Providing Durable Storage
### Providing Durable Storage
As mentioned in the [ZooKeeper Basics](#zookeeper-basics) section,
ZooKeeper commits all entries to a durable WAL, and periodically writes snapshots
@@ -507,7 +507,7 @@ same PersistentVolume mounted to the ZooKeeper server's data directory.
Even when the Pods are rescheduled, all of the writes made to the ZooKeeper
servers' WALs, and all of their snapshots, remain durable.
### Ensuring Consistent Configuration
## Ensuring Consistent Configuration
As noted in the [Facilitating Leader Election](#facilitating-leader-election) and
[Achieving Consensus](#achieving-consensus) sections, the servers in a
@@ -651,7 +651,7 @@ ZK_DATA_LOG_DIR=/var/lib/zookeeper/log
ZK_LOG_DIR=/var/log/zookeeper
```
#### Configuring Logging
### Configuring Logging
One of the files generated by the `zkConfigGen.sh` script controls ZooKeeper's logging.
ZooKeeper uses [Log4j](http://logging.apache.org/log4j/2.x/), and, by default,
@@ -721,7 +721,7 @@ For cluster level log shipping and aggregation, you should consider deploying a
[sidecar](http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html)
container to rotate and ship your logs.
#### Configuring a Non-Privileged User
### Configuring a Non-Privileged User
The best practices with respect to allowing an application to run as a privileged
user inside of a container are a matter of debate. If your organization requires
@@ -773,7 +773,7 @@ and the ZooKeeper process is able to successfully read and write its data.
drwxr-sr-x 3 zookeeper zookeeper 4096 Dec 5 20:45 /var/lib/zookeeper/data
```
### Managing the ZooKeeper Process
## Managing the ZooKeeper Process
The [ZooKeeper documentation](https://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_supervision)
documentation indicates that "You will want to have a supervisory process that
@@ -783,7 +783,7 @@ common pattern. When deploying an application in Kubernetes, rather than using
an external utility as a supervisory process, you should use Kubernetes as the
watchdog for your application.
#### Handling Process Failure
### Handling Process Failure
[Restart Policies](/docs/user-guide/pod-states/#restartpolicy) control how
@@ -846,7 +846,7 @@ child process. This ensures that Kubernetes will restart the application's
container when the process implementing the application's business logic fails.
#### Testing for Liveness
### Testing for Liveness
Configuring your application to restart failed processes is not sufficient to
@@ -918,7 +918,7 @@ zk-0 1/1 Running 1 1h
```
#### Testing for Readiness
### Testing for Readiness
Readiness is not the same as liveness. If a process is alive, it is scheduled
@@ -951,7 +951,7 @@ to specify both. This ensures that only healthy servers in the ZooKeeper
ensemble receive network traffic.
### Tolerating Node Failure
## Tolerating Node Failure
ZooKeeper needs a quorum of servers in order to successfully commit mutations
to data. For a three server ensemble, two servers must be healthy in order for
@@ -1013,7 +1013,7 @@ Service in the domain defined by the `topologyKey`. The `topologyKey`
different rules, labels, and selectors, you can extend this technique to spread
your ensemble across physical, network, and power failure domains.
### Surviving Maintenance
## Surviving Maintenance
**In this section you will cordon and drain nodes. If you are using this tutorial
on a shared cluster, be sure that this will not adversely affect other tenants.**
@@ -29,7 +29,7 @@ provides load balancing for an application that has two running instances.
{% capture lessoncontent %}
### Creating a service for an application running in two pods
## Creating a service for an application running in two pods
1. Run a Hello World application in your cluster:
@@ -111,7 +111,7 @@ provides load balancing for an application that has two running instances.
Hello Kubernetes!
### Using a service configuration file
## Using a service configuration file
As an alternative to using `kubectl expose`, you can use a
[service configuration file](/docs/user-guide/services/operations)
@@ -36,7 +36,7 @@ external IP address.
{% capture lessoncontent %}
### Creating a service for an application running in five pods
## Creating a service for an application running in five pods
1. Run a Hello World application in your cluster:
@@ -38,7 +38,7 @@ driver.
{% capture lessoncontent %}
### Create a Minikube cluster
## Create a Minikube cluster
This tutorial uses [Minikube](https://github.com/kubernetes/minikube) to
create a local cluster. This tutorial also assumes you are using
@@ -94,7 +94,7 @@ Verify that `kubectl` is configured to communicate with your cluster:
kubectl cluster-info
```
### Create your Node.js application
## Create your Node.js application
The next step is to write the application. Save this code in a folder named `hellonode`
with the filename `server.js`:
@@ -113,7 +113,7 @@ Stop the running Node.js server by pressing **Ctrl-C**.
The next step is to package your application in a Docker container.
### Create a Docker container image
## Create a Docker container image
Create a file, also in the `hellonode` folder, named `Dockerfile`. A Dockerfile describes
the image that you want to build. You can build a Docker container image by extending an
@@ -145,7 +145,7 @@ docker build -t hello-node:v1 .
Now the Minikube VM can run the image you built.
### Create a Deployment
## Create a Deployment
A Kubernetes [*Pod*](/docs/user-guide/pods/) is a group of one or more Containers,
tied together for the purposes of administration and networking. The Pod in this
@@ -206,7 +206,7 @@ kubectl config view
For more information about `kubectl`commands, see the
[kubectl overview](/docs/user-guide/kubectl-overview/).
### Create a Service
## Create a Service
By default, the Pod is only accessible by its internal IP address within the
Kubernetes cluster. To make the `hello-node` Container accessible from outside the
@@ -254,7 +254,7 @@ you should now be able to see some logs:
kubectl logs <POD-NAME>
```
### Update your app
## Update your app
Edit your `server.js` file to return a new message:
@@ -281,7 +281,7 @@ Run your app again to view the new message:
minikube service hello-node
```
### Clean up
## Clean up
Now you can clean up the resources you created in your cluster:
@@ -27,7 +27,7 @@ This page shows how to run an application using a Kubernetes Deployment object.
{% capture lessoncontent %}
### Creating and exploring an nginx deployment
## Creating and exploring an nginx deployment
You can run an application by creating a Kubernetes Deployment object, and you
can describe a Deployment in a YAML file. For example, this YAML file describes
@@ -72,7 +72,7 @@ a Deployment that runs the nginx:1.7.9 Docker image:
where `<pod-name>` is the name of one of your pods.
### Updating the deployment
## Updating the deployment
You can update the deployment by applying a new YAML file. This YAML file
specifies that the deployment should be updated to use nginx 1.8.
@@ -87,7 +87,7 @@ specifies that the deployment should be updated to use nginx 1.8.
kubectl get pods -l app=nginx
### Scaling the application by increasing the replica count
## Scaling the application by increasing the replica count
You can increase the number of pods in your Deployment by applying a new YAML
file. This YAML file sets `replicas` to 4, which specifies that the Deployment
@@ -111,7 +111,7 @@ should have four pods:
nginx-deployment-148880595-fxcez 1/1 Running 0 2m
nginx-deployment-148880595-rwovn 1/1 Running 0 2m
### Deleting a deployment
## Deleting a deployment
Delete the deployment by name: