Regional PD documentation; edited validation for Volumes page (#8714)

This commit is contained in:
Cheng Xing
2018-06-01 07:52:56 -07:00
committed by k8s-ci-robot
parent e49f288730
commit 3e1465461f
3 changed files with 76 additions and 23 deletions
@@ -167,6 +167,7 @@ provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
zones: us-central1-a, us-central1-b
replication-type: none
```
* `type`: `pd-standard` or `pd-ssd`. Default: `pd-standard`
@@ -177,6 +178,18 @@ parameters:
is specified, volumes are generally round-robin-ed across all active zones
where Kubernetes cluster has a node. `zone` and `zones` parameters must not
be used at the same time.
* `replication-type`: `none` or `regional-pd`. Default: `none`.
If `replication-type` is set to `none`, a regular (zonal) PD will be provisioned.
If `replication-type` is set to `regional-pd`, a
[Regional Persistent Disk](https://cloud.google.com/compute/docs/disks/#repds)
will be provisioned. In this case, users must use `zones` instead of `zone` to
specify the desired replication zones. If exactly two zones are specified, the
Regional PD will be provisioned in those zones. If more than two zones are
specified, Kubernetes will arbitrarily choose among the specified zones. If the
`zones` parameter is omitted, Kubernetes will arbitrarily choose among zones
managed by the cluster.
### Glusterfs
+33 -1
View File
@@ -368,6 +368,38 @@ spec:
fsType: ext4
```
#### Regional Persistent Disks
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
The [Regional Persistent Disks](https://cloud.google.com/compute/docs/disks/#repds) feature allows the creation of Persistent Disks that are available in two zones within the same region. In order to use this feature, the volume must be provisioned as a PersistentVolume; referencing the volume directly from a pod is not supported.
#### Manually provisioning a Regional PD PersistentVolume
Dynamic provisioning is possible using a [StorageClass for GCE PD](/docs/concepts/storage/storage-classes/#gce).
Before creating a PersistentVolume, you must create the PD:
```shell
gcloud beta compute disks create --size=500GB my-data-disk
--region us-central1
--replica-zones us-central1-a,us-central1-b
```
Example PersistentVolume spec:
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-volume
labels:
failure-domain.beta.kubernetes.io/zone: us-central1-a__us-central1-b
spec:
capacity:
storage: 400Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
```
### gitRepo
A `gitRepo` volume is an example of what can be done as a volume plugin. It
@@ -527,7 +559,7 @@ durability characteristics of the underlying disk.
The following is an example PersistentVolume spec using a `local` volume and
`nodeAffinity`:
``` yaml
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
+30 -22
View File
@@ -421,15 +421,15 @@ func TestExampleObjectSchemas(t *testing.T) {
"tcp-liveness-readiness": {&api.Pod{}},
},
"docs/tasks/debug-application-cluster": {
"counter-pod": {&api.Pod{}},
"event-exporter-deploy": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}},
"fluentd-gcp-configmap": {&api.ConfigMap{}},
"fluentd-gcp-ds": {&extensions.DaemonSet{}},
"nginx-dep": {&extensions.Deployment{}},
"node-problem-detector": {&extensions.DaemonSet{}},
"node-problem-detector-configmap": {&extensions.DaemonSet{}},
"shell-demo": {&api.Pod{}},
"termination": {&api.Pod{}},
"counter-pod": {&api.Pod{}},
"event-exporter-deploy": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}},
"fluentd-gcp-configmap": {&api.ConfigMap{}},
"fluentd-gcp-ds": {&extensions.DaemonSet{}},
"nginx-dep": {&extensions.Deployment{}},
"node-problem-detector": {&extensions.DaemonSet{}},
"node-problem-detector-configmap": {&extensions.DaemonSet{}},
"shell-demo": {&api.Pod{}},
"termination": {&api.Pod{}},
},
// TODO: decide whether federation examples should be added
"docs/tasks/inject-data-application": {
@@ -456,8 +456,8 @@ func TestExampleObjectSchemas(t *testing.T) {
"secret-pod": {&api.Pod{}},
},
"docs/tasks/job": {
"cronjob": {&batch.CronJob{}},
"job": {&batch.Job{}},
"cronjob": {&batch.CronJob{}},
"job": {&batch.Job{}},
},
"docs/tasks/job/coarse-parallel-processing-work-queue": {
"job": {&batch.Job{}},
@@ -620,12 +620,19 @@ func TestExampleObjectSchemas(t *testing.T) {
var sampleRegexp = regexp.MustCompile("(?ms)^```(?:(?P<type>yaml)\\w*\\n(?P<content>.+?)|\\w*\\n(?P<content>\\{.+?\\}))\\n^```")
var subsetRegexp = regexp.MustCompile("(?ms)\\.{3}")
// Validates examples embedded in Markdown files.
func TestReadme(t *testing.T) {
// BlockVolume required for local volume example
utilfeature.DefaultFeatureGate.Set("BlockVolume=true")
paths := []struct {
file string
expectedType []runtime.Object
expectedType []runtime.Object // List of all valid types for the whole doc
}{
{"../content/en/docs/concepts/storage/volumes.md", []runtime.Object{&api.Pod{}}},
{"../content/en/docs/concepts/storage/volumes.md", []runtime.Object{
&api.Pod{},
&api.PersistentVolume{},
}},
}
for _, path := range paths {
@@ -639,7 +646,6 @@ func TestReadme(t *testing.T) {
if matches == nil {
continue
}
ix := 0
for _, match := range matches {
var content, subtype string
for i, name := range sampleRegexp.SubexpNames() {
@@ -655,21 +661,23 @@ func TestReadme(t *testing.T) {
continue
}
var expectedType runtime.Object
if len(path.expectedType) == 1 {
expectedType = path.expectedType[0]
} else {
expectedType = path.expectedType[ix]
ix++
}
json, err := yaml.ToJSON([]byte(content))
if err != nil {
t.Errorf("%s could not be converted to JSON: %v\n%s", path, err, string(content))
}
if err := runtime.DecodeInto(testapi.Default.Codec(), json, expectedType); err != nil {
var expectedType runtime.Object
for _, expectedType = range path.expectedType {
err = runtime.DecodeInto(testapi.Default.Codec(), json, expectedType)
if err == nil {
break
}
}
if err != nil {
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(content))
continue
}
if errors := validateObject(expectedType); len(errors) > 0 {
t.Errorf("%s did not validate correctly: %v", path, errors)
}