Files
website/_site/v1.1/docs/design/persistent-storage/index.html
T

419 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!Doctype html>
<html id="docs">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="/css/styles.css"/>
<script src="/js/script.js"></script>
<script src="/js/jquery-2.2.0.min.js"></script>
<script src="/js/non-mini.js"></script>
<title>Kubernetes - Persistent Storage</title>
</head>
<body>
<div id="cellophane" onclick="kub.toggleMenu()"></div>
<header>
<a href="/" class="logo"></a>
<div class="nav-buttons" data-auto-burger="primary">
<a href="/docs" class="button" id="viewDocs">View Documentation</a>
<a href="/get-started" class="button" id="tryKubernetes">Try Kubernetes</a>
<button id="hamburger" onclick="kub.toggleMenu()" data-auto-burger-exclude><div></div></button>
</div>
<nav id="mainNav">
<main data-auto-burger="primary">
<div class="nav-box">
<h3><a href="">Get Started</a></h3>
<p>Built for a multi-cloud world, public, private or hybrid. Seamlessly roll out new features.</p>
</div>
<div class="nav-box">
<h3><a href="">Documentation</a></h3>
<p>Pellentesque in ipsum id orci porta dapibus. Nulla porttitor accumsan tincidunt. </p>
</div>
<div class="nav-box">
<h3><a href="">Community</a></h3>
<p>Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. </p>
</div>
<div class="nav-box">
<h3><a href="">Blog</a></h3>
<p>Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem. Quisque velit nisi, pretium ut lacinia in. </p>
</div>
</main>
<main data-auto-burger="primary">
<div class="left">
<h5 class="github-invite">Interested in hacking on the core Kubernetes code base?</h5>
<a href="" class="button">View On Github</a>
</div>
<div class="right">
<h5 class="github-invite">Explore the community</h5>
<div class="social">
<a href="https://twitter.com/kubernetesio" class="Twitter"><span>twitter</span></a>
<a href="https://github.com/kubernetes/kubernetes" class="github"><span>Github</span></a>
<a href="http://slack.k8s.io/" class="slack"><span>Slack</span></a>
<a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>stackoverflow</span></a>
<a href="https://groups.google.com/forum/#!forum/google-containers" class="mailing-list"><span>Mailing List</span></a>
</div>
</div>
<div class="clear" style="clear: both"></div>
</main>
</nav>
</header>
<!-- HERO -->
<section id="hero" class="light-text">
<h1></h1>
<h5></h5>
<div id="vendorStrip" class="light-text">
<ul>
<li><a href="/v1.1/guides">GUIDES</a></li>
<li><a href="/v1.1/reference">REFERENCE</a></li>
<li><a href="/v1.1/samples">SAMPLES</a></li>
<li><a href="/v1.1/support">SUPPORT</a></li>
</ul>
<div class="dropdown">
<div class="readout"></div>
<a href="/v1.1">Version 1.1</a>
<a href="/v1.0">Version 1.0</a>
</div>
<input type="text" id="search" placeholder="Search the docs">
</div>
</section>
<section id="encyclopedia">
<div id="docsToc">
<div class="pi-accordion">
</div> <!-- /pi-accordion -->
</div> <!-- /docsToc -->
<div id="docsContent">
<h1>Persistent Storage</h1>
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
<!-- END MUNGE: UNVERSIONED_WARNING -->
<h1 id="persistent-storage">Persistent Storage</h1>
<p>This document proposes a model for managing persistent, cluster-scoped storage for applications requiring long lived data.</p>
<h3 id="tldr">tl;dr</h3>
<p>Two new API kinds:</p>
<p>A <code>PersistentVolume</code> (PV) is a storage resource provisioned by an administrator. It is analogous to a node. See <a href="../user-guide/persistent-volumes/">Persistent Volume Guide</a> for how to use it.</p>
<p>A <code>PersistentVolumeClaim</code> (PVC) is a users request for a persistent volume to use in a pod. It is analogous to a pod.</p>
<p>One new system component:</p>
<p><code>PersistentVolumeClaimBinder</code> is a singleton running in master that watches all PersistentVolumeClaims in the system and binds them to the closest matching available PersistentVolume. The volume manager watches the API for newly created volumes to manage.</p>
<p>One new volume:</p>
<p><code>PersistentVolumeClaimVolumeSource</code> references the users PVC in the same namespace. This volume finds the bound PV and mounts that volume for the pod. A <code>PersistentVolumeClaimVolumeSource</code> is, essentially, a wrapper around another type of volume that is owned by someone else (the system).</p>
<p>Kubernetes makes no guarantees at runtime that the underlying storage exists or is available. High availability is left to the storage provider.</p>
<h3 id="goals">Goals</h3>
<ul>
<li>Allow administrators to describe available storage</li>
<li>Allow pod authors to discover and request persistent volumes to use with pods</li>
<li>Enforce security through access control lists and securing storage to the same namespace as the pod volume</li>
<li>Enforce quotas through admission control</li>
<li>Enforce scheduler rules by resource counting</li>
<li>Ensure developers can rely on storage being available without being closely bound to a particular disk, server, network, or storage device.</li>
</ul>
<h4 id="describe-available-storage">Describe available storage</h4>
<p>Cluster administrators use the API to manage <em>PersistentVolumes</em>. A custom store <code>NewPersistentVolumeOrderedIndex</code> will index volumes by access modes and sort by storage capacity. The <code>PersistentVolumeClaimBinder</code> watches for new claims for storage and binds them to an available volume by matching the volumes characteristics (AccessModes and storage size) to the users request.</p>
<p>PVs are system objects and, thus, have no namespace.</p>
<p>Many means of dynamic provisioning will be eventually be implemented for various storage types.</p>
<h5 id="persistentvolume-api">PersistentVolume API</h5>
<table>
<thead>
<tr>
<th>Action</th>
<th>HTTP Verb</th>
<th>Path</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>CREATE</td>
<td>POST</td>
<td>/api/{version}/persistentvolumes/</td>
<td>Create instance of PersistentVolume</td>
</tr>
<tr>
<td>GET</td>
<td>GET</td>
<td>/api/{version}persistentvolumes/{name}</td>
<td>Get instance of PersistentVolume with {name}</td>
</tr>
<tr>
<td>UPDATE</td>
<td>PUT</td>
<td>/api/{version}/persistentvolumes/{name}</td>
<td>Update instance of PersistentVolume with {name}</td>
</tr>
<tr>
<td>DELETE</td>
<td>DELETE</td>
<td>/api/{version}/persistentvolumes/{name}</td>
<td>Delete instance of PersistentVolume with {name}</td>
</tr>
<tr>
<td>LIST</td>
<td>GET</td>
<td>/api/{version}/persistentvolumes</td>
<td>List instances of PersistentVolume</td>
</tr>
<tr>
<td>WATCH</td>
<td>GET</td>
<td>/api/{version}/watch/persistentvolumes</td>
<td>Watch for changes to a PersistentVolume</td>
</tr>
</tbody>
</table>
<h4 id="request-storage">Request Storage</h4>
<p>Kubernetes users request persistent storage for their pod by creating a <code>PersistentVolumeClaim</code>. Their request for storage is described by their requirements for resources and mount capabilities.</p>
<p>Requests for volumes are bound to available volumes by the volume manager, if a suitable match is found. Requests for resources can go unfulfilled.</p>
<p>Users attach their claim to their pod using a new <code>PersistentVolumeClaimVolumeSource</code> volume source.</p>
<h5 id="persistentvolumeclaim-api">PersistentVolumeClaim API</h5>
<table>
<thead>
<tr>
<th>Action</th>
<th>HTTP Verb</th>
<th>Path</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>CREATE</td>
<td>POST</td>
<td>/api/{version}/namespaces/{ns}/persistentvolumeclaims/</td>
<td>Create instance of PersistentVolumeClaim in namespace {ns}</td>
</tr>
<tr>
<td>GET</td>
<td>GET</td>
<td>/api/{version}/namespaces/{ns}/persistentvolumeclaims/{name}</td>
<td>Get instance of PersistentVolumeClaim in namespace {ns} with {name}</td>
</tr>
<tr>
<td>UPDATE</td>
<td>PUT</td>
<td>/api/{version}/namespaces/{ns}/persistentvolumeclaims/{name}</td>
<td>Update instance of PersistentVolumeClaim in namespace {ns} with {name}</td>
</tr>
<tr>
<td>DELETE</td>
<td>DELETE</td>
<td>/api/{version}/namespaces/{ns}/persistentvolumeclaims/{name}</td>
<td>Delete instance of PersistentVolumeClaim in namespace {ns} with {name}</td>
</tr>
<tr>
<td>LIST</td>
<td>GET</td>
<td>/api/{version}/namespaces/{ns}/persistentvolumeclaims</td>
<td>List instances of PersistentVolumeClaim in namespace {ns}</td>
</tr>
<tr>
<td>WATCH</td>
<td>GET</td>
<td>/api/{version}/watch/namespaces/{ns}/persistentvolumeclaims</td>
<td>Watch for changes to PersistentVolumeClaim in namespace {ns}</td>
</tr>
</tbody>
</table>
<h4 id="scheduling-constraints">Scheduling constraints</h4>
<p>Scheduling constraints are to be handled similar to pod resource constraints. Pods will need to be annotated or decorated with the number of resources it requires on a node. Similarly, a node will need to list how many it has used or available.</p>
<p>TBD</p>
<h4 id="events">Events</h4>
<p>The implementation of persistent storage will not require events to communicate to the user the state of their claim. The CLI for bound claims contains a reference to the backing persistent volume. This is always present in the API and CLI, making an event to communicate the same unnecessary.</p>
<p>Events that communicate the state of a mounted volume are left to the volume plugins.</p>
<h3 id="example">Example</h3>
<h4 id="admin-provisions-storage">Admin provisions storage</h4>
<p>An administrator provisions storage by posting PVs to the API. Various way to automate this task can be scripted. Dynamic provisioning is a future feature that can maintain levels of PVs.</p>
<div class="highlight">
<pre><code class="language-yaml">POST:
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv0001
spec:
capacity:
storage: 10
persistentDisk:
pdName: "abc123"
fsType: "ext4"
</code></pre>
</div>
<div class="highlight">
<pre><code class="language-console">$ kubectl get pv
NAME LABELS CAPACITY ACCESSMODES STATUS CLAIM REASON
pv0001 map[] 10737418240 RWO Pending
</code></pre>
</div>
<h4 id="users-request-storage">Users request storage</h4>
<p>A user requests storage by posting a PVC to the API. Their request contains the AccessModes they wish their volume to have and the minimum size needed.</p>
<p>The user must be within a namespace to create PVCs.</p>
<div class="highlight">
<pre><code class="language-yaml">POST:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim-1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3
</code></pre>
</div>
<div class="highlight">
<pre><code class="language-console">$ kubectl get pvc
NAME LABELS STATUS VOLUME
myclaim-1 map[] pending
</code></pre>
</div>
<h4 id="matching-and-binding">Matching and binding</h4>
<p>The <code>PersistentVolumeClaimBinder</code> attempts to find an available volume that most closely matches the users request. If one exists, they are bound by putting a reference on the PV to the PVC. Requests can go unfulfilled if a suitable match is not found.</p>
<div class="highlight">
<pre><code class="language-console">$ kubectl get pv
NAME LABELS CAPACITY ACCESSMODES STATUS CLAIM REASON
pv0001 map[] 10737418240 RWO Bound myclaim-1 / f4b3d283-c0ef-11e4-8be4-80e6500a981e
kubectl get pvc
NAME LABELS STATUS VOLUME
myclaim-1 map[] Bound b16e91d6-c0ef-11e4-8be4-80e6500a981e
</code></pre>
</div>
<h4 id="claim-usage">Claim usage</h4>
<p>The claim holder can use their claim as a volume. The <code>PersistentVolumeClaimVolumeSource</code> knows to fetch the PV backing the claim and mount its volume for a pod.</p>
<p>The claim holder owns the claim and its data for as long as the claim exists. The pod using the claim can be deleted, but the claim remains in the users namespace. It can be used again and again by many pods.</p>
<div class="highlight">
<pre><code class="language-yaml">POST:
kind: Pod
apiVersion: v1
metadata:
name: mypod
spec:
containers:
- image: nginx
name: myfrontend
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
source:
persistentVolumeClaim:
accessMode: ReadWriteOnce
claimRef:
name: myclaim-1
</code></pre>
</div>
<h4 id="releasing-a-claim-and-recycling-a-volume">Releasing a claim and Recycling a volume</h4>
<p>When a claim holder is finished with their data, they can delete their claim.</p>
<div class="highlight">
<pre><code class="language-console">$ kubectl delete pvc myclaim-1
</code></pre>
</div>
<p>The <code>PersistentVolumeClaimBinder</code> will reconcile this by removing the claim reference from the PV and change the PVs status to Released.</p>
<p>Admins can script the recycling of released volumes. Future dynamic provisioners will understand how a volume should be recycled.</p>
<!-- BEGIN MUNGE: IS_VERSIONED -->
<!-- TAG IS_VERSIONED -->
<!-- END MUNGE: IS_VERSIONED -->
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
<p><a href=""><img src="https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/persistent-storage.md?pixel" alt="Analytics" /></a>
<!-- END MUNGE: GENERATED_ANALYTICS --></p>
</div>
</section>
<footer>
<main class="light-text">
<nav>
<a href="/getting-started.html">Getting Started</a>
<a href="/docs.html">Documentation</a>
<a href="http://blog.kubernetes.io/">Blog</a>
<a href="/foobang.html">Community</a>
</nav>
<div class="social">
<a href="https://twitter.com/kubernetesio" class="twitter"><span>twitter</span></a>
<a href="https://github.com/kubernetes/kubernetes" class="github"><span>Github</span></a>
<a href="http://slack.k8s.io/" class="slack"><span>Slack</span></a>
<a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>stackoverflow</span></a>
<a href="https://groups.google.com/forum/#!forum/google-containers" class="mailing-list"><span>Mailing List</span></a>
<label for="wishField">I wish this page <input type="text" id="wishField" name="wishField" placeholder="made better textfield suggestions"></label>
</div>
<div class="center">&copy; 2016 Kubernetes</div>
</main>
</footer>
</body>
</html>