Skip to content

Commit

Permalink
Merge pull request #1599 from jeffmendoza/stateful-app
Browse files Browse the repository at this point in the history
Add stateful application tutorial.
  • Loading branch information
steveperry-53 authored Nov 17, 2016
2 parents 7b2589f + 053cdb3 commit 748bd4d
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 0 deletions.
4 changes: 4 additions & 0 deletions _data/tutorials.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ toc:
path: /docs/tutorials/stateless-application/expose-external-ip-address-service/
- title: Exposing an External IP Address to Access an Application in a Cluster
path: /docs/tutorials/stateless-application/expose-external-ip-address/
- title: Stateful Applications
section:
- title: Running a Single-Instance Stateful Application
path: /docs/tutorials/stateful-application/run-stateful-application/
4 changes: 4 additions & 0 deletions docs/tutorials/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ The Tutorials section of the Kubernetes documentation is a work in progress.

* [Exposing an External IP Address to Access an Application in a Cluster](/docs/tutorials/stateless-application/expose-external-ip-address/)

#### Stateful Applications

* [Running a Single-Instance Stateful Application](/docs/tutorials/stateful-application/run-stateful-application/)

### What's next

If you would like to write a tutorial, see
Expand Down
12 changes: 12 additions & 0 deletions docs/tutorials/stateful-application/gce-volume.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: mysql-disk
fsType: ext4
51 changes: 51 additions & 0 deletions docs/tutorials/stateful-application/mysql-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
220 changes: 220 additions & 0 deletions docs/tutorials/stateful-application/run-stateful-application.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
---
---

{% capture overview %}

This page shows you how to run a single-instance stateful application
in Kubernetes using a PersistentVolume and a Deployment. The
application is MySQL.

{% endcapture %}


{% capture objectives %}

* Create a PersistentVolume referencing a disk in your environment.
* Create a MySQL Deployment.
* Expose MySQL to other pods in the cluster at a known DNS name.

{% endcapture %}


{% capture prerequisites %}

* {% include task-tutorial-prereqs.md %}

* For data persistence we will create a Persistent Volume that
references a disk in your
environment. See
[here](/docs/user-guide/persistent-volumes/#types-of-persistent-volumes) for
the types of environments supported. This Tutorial will demonstrate
`GCEPersistentDisk` but any type will work. `GCEPersistentDisk`
volumes only work on Google Compute Engine.

{% endcapture %}


{% capture lessoncontent %}

### 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)
for a list of supported environment disks. For Google Compute Engine, run:

```
gcloud compute disks create --size=20GB mysql-disk
```

Next create a PersistentVolume that points to the `mysql-disk`
disk just created. Here is a configuration file for a PersistentVolume
that points to the Compute Engine disk above:

{% include code.html language="yaml" file="gce-volume.yaml" ghlink="/docs/tutorials/stateful-application/gce-volume.yaml" %}

Notice that the `pdName: mysql-disk` line matches the name of the disk
in the Compute Engine environment. See the
[Persistent Volumes](/docs/user-guide/persistent-volumes/)
for details on writing a PersistentVolume configuration file for other
environments.

Create the persistent volume:

```
kubectl create -f http://k8s.io/docs/tutorials/stateful-application/gce-volume.yaml
```


### Deploy MySQL

You can run a stateful application by creating a Kubernetes Deployment
and connecting it to an existing PersistentVolume using a
PersistentVolumeClaim. For example, this YAML file describes a
Deployment that runs MySQL and references the PersistentVolumeClaim. The file
defines a volume mount for /var/lib/mysql, and then creates a
PersistentVolumeClaim that looks for a 20G volume. This claim is
satisfied by any volume that meets the requirements, in this case, the
volume created above.

Note: The password is defined in the config yaml, and this is insecure. See
[Kubernetes Secrets](/docs/user-guide/secrets/)
for a secure solution.

{% include code.html language="yaml" file="mysql-deployment.yaml" ghlink="/docs/tutorials/stateful-application/mysql-deployment.yaml" %}

1. Deploy the contents of the YAML file:

kubectl create -f http://k8s.io/docs/tutorials/stateful-application/mysql-deployment.yaml

1. Display information about the Deployment:

kubectl describe deployment mysql

Name: mysql
Namespace: default
CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700
Labels: app=mysql
Selector: app=mysql
Replicas: 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: Recreate
MinReadySeconds: 0
OldReplicaSets: <none>
NewReplicaSet: mysql-63082529 (1/1 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1

1. List the pods created by the Deployment:

kubectl get pods -l app=mysql

NAME READY STATUS RESTARTS AGE
mysql-63082529-2z3ki 1/1 Running 0 3m
1. Inspect the Persistent Volume:

kubectl describe pv mysql-pv

Name: mysql-pv
Labels: <none>
Status: Bound
Claim: default/mysql-pv-claim
Reclaim Policy: Retain
Access Modes: RWO
Capacity: 20Gi
Message:
Source:
Type: GCEPersistentDisk (a Persistent Disk resource in Google Compute Engine)
PDName: mysql-disk
FSType: ext4
Partition: 0
ReadOnly: false
No events.

1. Inspect the PersistentVolumeClaim:

kubectl describe pvc mysql-pv-claim

Name: mysql-pv-claim
Namespace: default
Status: Bound
Volume: mysql-pv
Labels: <none>
Capacity: 20Gi
Access Modes: RWO
No events.

### 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
`clusterIP: None` lets the Service DNS name resolve directly to the
Pod's IP address. This is optimal when you have only one Pod
behind a Service and you don't intend to increase the number of Pods.

Run a MySQL client to connect to the server:

```
kubectl run -it --rm --image=mysql:5.6 mysql-client -- mysql -h mysql -ppassword
```

This command creates a new Pod in the cluster running a mysql client
and connects it to the server through the Service. If it connects, you
know your stateful MySQL database is up and running.

```
Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
mysql>
```

### 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
specific to stateful apps:

* Don't scale the app. This setup is for single-instance apps
only. The underlying PersistentVolume can only be mounted to one
Pod. For clustered stateful apps, see the
[StatefulSet documentation](/docs/user-guide/petset/).
* Use `strategy:` `type: Recreate` in the Deployment configuration
YAML file. This instructs Kubernetes to _not_ use rolling
updates. Rolling updates will not work, as you cannot have more than
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

Delete the deployed objects by name:

```
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv
```

Also, if you are using Compute Engine disks:

```
gcloud compute disks delete mysql-disk
```

{% endcapture %}


{% capture whatsnext %}

* Learn more about [Deployment objects](/docs/user-guide/deployments/).

* Learn more about [Deploying applications](/docs/user-guide/deploying-applications/)

* [kubectl run documentation](/docs/user-guide/kubectl/kubectl_run/)

* [Volumes](/docs/user-guide/volumes/) and [Persistent Volumes](/docs/user-guide/persistent-volumes/)

{% endcapture %}

{% include templates/tutorial.md %}

0 comments on commit 748bd4d

Please sign in to comment.