website/docs/tasks/run-application/run-single-instance-statefu...

248 lines
8.2 KiB
Markdown
Raw Normal View History

2016-11-01 20:29:42 +00:00
---
title: Run a Single-Instance Stateful Application
2016-11-01 20:29:42 +00:00
---
{% 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 %}
2017-01-18 18:18:37 +00:00
## Set up a disk in your environment
2016-11-01 20:29:42 +00:00
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/tasks/run-application/gce-volume.yaml" %}
2016-11-01 20:29:42 +00:00
Notice that the `pdName: mysql-disk` line matches the name of the disk
in the Compute Engine environment. See the
[Persistent Volumes](/docs/concepts/storage/persistent-volumes/)
2016-11-01 20:29:42 +00:00
for details on writing a PersistentVolume configuration file for other
environments.
Create the persistent volume:
```
kubectl create -f https://k8s.io/docs/tasks/run-application/gce-volume.yaml
2016-11-01 20:29:42 +00:00
```
2017-01-18 18:18:37 +00:00
## Deploy MySQL
2016-11-01 20:29:42 +00:00
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/concepts/configuration/secret/)
2016-11-01 20:29:42 +00:00
for a secure solution.
2017-05-05 02:28:01 +00:00
{% include code.html language="yaml" file="mysql-deployment.yaml" ghlink="/docs/tasks/run-application/mysql-deployment.yaml" %}
2016-11-01 20:29:42 +00:00
1. Deploy the contents of the YAML file:
kubectl create -f https://k8s.io/docs/tasks/run-application/mysql-deployment.yaml
2016-11-01 20:29:42 +00:00
1. Display information about the Deployment:
kubectl describe deployment mysql
2016-11-01 20:29:42 +00:00
Name: mysql
Namespace: default
CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700
Labels: app=mysql
Annotations: deployment.kubernetes.io/revision=1
Selector: app=mysql
Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app=mysql
Containers:
mysql:
Image: mysql:5.6
Port: 3306/TCP
Environment:
MYSQL_ROOT_PASSWORD: password
Mounts:
/var/lib/mysql from mysql-persistent-storage (rw)
Volumes:
mysql-persistent-storage:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: mysql-pv-claim
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: mysql-63082529 (1/1 replicas created)
2016-11-01 20:29:42 +00:00
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
2016-11-01 20:29:42 +00:00
1. List the pods created by the Deployment:
kubectl get pods -l app=mysql
2016-11-01 20:29:42 +00:00
NAME READY STATUS RESTARTS AGE
mysql-63082529-2z3ki 1/1 Running 0 3m
2016-11-01 20:29:42 +00:00
1. Inspect the Persistent Volume:
kubectl describe pv mysql-pv
2016-11-01 20:29:42 +00:00
Name: mysql-pv
Labels: <none>
Annotations: pv.kubernetes.io/bound-by-controller=yes
StorageClass:
Status: Bound
Claim: default/mysql-pv-claim
Reclaim Policy: Retain
Access Modes: RWO
Capacity: 20Gi
Message:
2016-11-01 20:29:42 +00:00
Source:
Type: GCEPersistentDisk (a Persistent Disk resource in Google Compute Engine)
PDName: mysql-disk
FSType: ext4
Partition: 0
ReadOnly: false
Events: <none>
2016-11-01 20:29:42 +00:00
1. Inspect the PersistentVolumeClaim:
kubectl describe pvc mysql-pv-claim
2016-11-01 20:29:42 +00:00
Name: mysql-pv-claim
Namespace: default
StorageClass:
Status: Bound
Volume: mysql-pv
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
Capacity: 20Gi
Access Modes: RWO
Events: <none>
2016-11-01 20:29:42 +00:00
2017-01-18 18:18:37 +00:00
## Accessing the MySQL instance
2016-11-01 20:29:42 +00:00
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 <pod-ip> -p <password>
2016-11-01 20:29:42 +00:00
```
This command creates a new Pod in the cluster running a MySQL client
2016-11-01 20:29:42 +00:00
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>
2016-11-01 20:29:42 +00:00
```
2017-01-18 18:18:37 +00:00
## Updating
2016-11-01 20:29:42 +00:00
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/concepts/workloads/controllers/petset/).
2016-11-01 20:29:42 +00:00
* 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.
2017-01-18 18:18:37 +00:00
## Deleting a deployment
2016-11-01 20:29:42 +00:00
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/concepts/workloads/controllers/deployment/).
2016-11-01 20:29:42 +00:00
* Learn more about [Deploying applications](/docs/user-guide/deploying-applications/)
2017-04-13 06:03:33 +00:00
* [kubectl run documentation](/docs/user-guide/kubectl/v1.6/#run)
2016-11-01 20:29:42 +00:00
* [Volumes](/docs/concepts/storage/volumes/) and [Persistent Volumes](/docs/concepts/storage/persistent-volumes/)
2016-11-01 20:29:42 +00:00
{% endcapture %}
{% include templates/tutorial.md %}