[stable/nfs-server-provisioner]: Add nfs-server-provisioner chart (#3870)

* [stable/nfs-provisioner]: Add nfs-provisioner chart

Adds a new chart to deploy the kubernetes-incubator nfs-provisioner
using a StatefulSet. Additionally, it requested, will define the
necessary StorageClass resource needed to make use of the provisioner.

* [stable/nfs-provisioner]: Update image tag to v1.0.9

* [stable/nfs-server-provisioner]: Move stable/nfs-provisioner to stable/nfs-server-provisioner

* [stable/nfs-server-provisioner]: Update Chart.yaml and README.md for name change
This commit is contained in:
Kiall Mac Innes
2018-04-25 03:10:02 -07:00
committed by k8s-ci-robot
parent d9f690a7e9
commit 294015f83d
13 changed files with 614 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
+13
View File
@@ -0,0 +1,13 @@
apiVersion: v1
appVersion: 1.0.8
description: nfs-server-provisioner is an out-of-tree dynamic provisioner for Kubernetes. You can use it to quickly & easily deploy shared storage that works almost anywhere.
name: nfs-server-provisioner
version: 0.1.0
maintainers:
- name: kiall
email: kiall@macinnes.ie
sources:
- https://github.com/kubernetes-incubator/external-storage/tree/master/nfs
keywords:
- nfs
- storage
+4
View File
@@ -0,0 +1,4 @@
approvers:
- kiall
reviewers:
- kiall
+200
View File
@@ -0,0 +1,200 @@
# NFS Server Provisioner
[NFS Server Provisioner](https://github.com/kubernetes-incubator/external-storage/tree/master/nfs)
is an out-of-tree dynamic provisioner for Kubernetes. You can use it to quickly
& easily deploy shared storage that works almost anywhere.
This chart will deploy the Kubernetes [external-storage projects](https://github.com/kubernetes-incubator/external-storage)
`nfs` provisioner. This provisioner includes a built in NFS server, and is not intended for connecting to a pre-existing
NFS server. If you have a pre-existing NFS Server, please consider using the [NFS Client Provisioner](https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client)
instead.
## TL;DR;
```console
$ helm install stable/nfs-server-provisioner
```
> **Warning**: While installing in the default configuration will work, any data stored on
the dynamic volumes provisioned by this chart will not be persistent!
## Introduction
This chart bootstraps a [nfs-server-provisioner](https://github.com/kubernetes-incubator/external-storage/tree/master/nfs)
deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh)
package manager.
## Installing the Chart
To install the chart with the release name `my-release`:
```console
$ helm install stable/nfs-server-provisioner --name my-release
```
The command deploys nfs-server-provisioner on the Kubernetes cluster in the default
configuration. The [configuration](#configuration) section lists the parameters
that can be configured during installation.
## Uninstalling the Chart
To uninstall/delete the `my-release` deployment:
```console
$ helm delete my-release
```
The command removes all the Kubernetes components associated with the chart and
deletes the release.
## Configuration
The following tables lists the configurable parameters of the kibana chart and
their default values.
| Parameter | Description | Default |
|:-------------------------------|:----------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------|
| `imagePullSecrets` | Specify image pull secrets | `nil` (does not add image pull secrets to deployed pods) |
| `image.repository` | The image repository to pull from | `quay.io/kubernetes_incubator/nfs-provisioner` |
| `image.tag` | The image tag to pull from | `v1.0.8` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `service.type` | service type | `ClusterIP` |
| `service.nfsPort` | TCP port on which the nfs-server-provisioner NFS service is exposed | `2049` |
| `service.mountdPort` | TCP port on which the nfs-server-provisioner mountd service is exposed | `20048` |
| `service.rpcbindPort` | TCP port on which the nfs-server-provisioner RPC service is exposed | `51413` |
| `service.nfsNodePort` | if `service.type` is `NodePort` and this is non-empty, sets the nfs-server-provisioner node port of the NFS service | `nil` |
| `service.mountdNodePort` | if `service.type` is `NodePort` and this is non-empty, sets the nfs-server-provisioner node port of the mountd service | `nil` |
| `service.rpcbindNodePort` | if `service.type` is `NodePort` and this is non-empty, sets the nfs-server-provisioner node port of the RPC service | `nil` |
| `persistence.enabled` | Enable config persistence using PVC | `false` |
| `persistence.storageClass` | PVC Storage Class for config volume | `nil` |
| `persistence.accessMode` | PVC Access Mode for config volume | `ReadWriteOnce` |
| `persistence.size` | PVC Storage Request for config volume | `1Gi` |
| `storageClass.create` | Enable creation of a StorageClass to consume this nfs-server-provisioner instance | `true` |
| `storageClass.provisionerName` | The provisioner name for the storageclass | `cluster.local/{release-name}-{chart-name}` |
| `storageClass.defaultClass` | Whether to set the created StorageClass as the clusters default StorageClass | `false` |
| `storageClass.name` | The name to assign the created StorageClass | `nfs` |
| `resources` | Resoure limits for nfs-server-provisioner pod | `{}` |
| `nodeSelector` | Map of node labels for pod assignment | `{}` |
| `tolerations` | List of node taints to tolerate | `[]` |
| `affinity` | Map of node/pod affinities | `{}` |
```console
$ helm install stable/nfs-server-provisioner --name my-release \
--set=image.tag=v1.0.8,resources.limits.cpu=200m
```
Alternatively, a YAML file that specifies the values for the above parameters
can be provided while installing the chart. For example,
```console
$ helm install stable/nfs-server-provisioner --name my-release -f values.yaml
```
> **Tip**: You can use the default [values.yaml](values.yaml) as an example
## Persistence
The nfs-server-provisioner image stores it's configuration data, and importantly, **the dynamic volumes it
manages** `/export` path of the container.
The chart mounts a [Persistent Volume](http://kubernetes.io/docs/user-guide/persistent-volumes/)
volume at this location. The volume can be created using dynamic volume
provisioning. However, **it is highly recommended** to explicitly specify
a storageclass to use rather than accept the clusters default, or pre-create
a volume for each replica.
If this chart is deployed with more than 1 replica, `storageClass.defaultClass=true`
and `persistence.storageClass`, then the 2nd+ replica will end up using the 1st
replica to provision storage - which is likely never a desired outcome.
## Recommended Persistence Configuration Examples
The following is a recommended configration example when another storage class
exists to provide persistence:
persistence:
enabled: true
storageClass: "standard"
size: 200Gi
storageClass:
defaultClass: true
On many clusters, the cloud provider integration will create a "standard" storage
class which will create a volume (e.g. a Google Compute Engine Persistent Disk or
Amazon EBS volume) to provide persistence.
---
The following is a recommended configration example when another storage class
does not exist to provide persistence:
persistence:
enabled: true
storageClass: "-"
size: 200Gi
storageClass:
defaultClass: true
In this configuration, a `PersistentVolume` must be created for each replica
to use. Installing the Helm chart, and then inspecting the `PersistentVolumeClaim`'s
created will provide the necessary names for your `PersistentVolume`'s to bind to.
An example of the necessary `PersistentVolume`:
apiVersion: v1
kind: PersistentVolume
metadata:
name: data-nfs-server-provisioner-0
spec:
capacity:
storage: 200Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
fsType: "ext4"
pdName: "data-nfs-server-provisioner-0"
claimRef:
namespace: kube-system
name: data-nfs-server-provisioner-0
---
The following is a recommended configration example for running on bare metal with a hostPath volume:
persistence:
enabled: true
storageClass: "-"
size: 200Gi
storageClass:
defaultClass: true
nodeSelector:
kubernetes.io/hostname: {node-name}
In this configuration, a `PersistentVolume` must be created for each replica
to use. Installing the Helm chart, and then inspecting the `PersistentVolumeClaim`'s
created will provide the necessary names for your `PersistentVolume`'s to bind to.
An example of the necessary `PersistentVolume`:
apiVersion: v1
kind: PersistentVolume
metadata:
name: data-nfs-server-provisioner-0
spec:
capacity:
storage: 200Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /srv/volumes/data-nfs-server-provisioner-0
claimRef:
namespace: kube-system
name: data-nfs-server-provisioner-0
> **Warning**: `hostPath` volumes cannot be migrated between machines by Kubernetes, as such,
in this example, we have restricted the `nfs-server-provisioner` pod to run on a single node. This
is unsuitable for production deployments.
@@ -0,0 +1,26 @@
The NFS Provisioner service has now been installed.
{{ if .Values.storageClass.create -}}
A storage class named '{{ .Values.storageClass.name }}' has now been created
and is available to provision dynamic volumes.
You can use this storageclass by creating a `PersistentVolumeClaim` with the
correct storageClassName attribute. For example:
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-dynamic-volume-claim
spec:
storageClassName: "{{ .Values.storageClass.name }}"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
{{ else -}}
A storage class has NOT been created. You may create a custom `StorageClass`
resource with a `provisioner` attribute of `{{ template "nfs-provisioner.provisionerName" . }}`.
{{ end -}}
@@ -0,0 +1,43 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "nfs-provisioner.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "nfs-provisioner.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "nfs-provisioner.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "nfs-provisioner.provisionerName" -}}
{{- if .Values.storageClass.provisionerName -}}
{{- printf.Values.storageClass.provisionerName -}}
{{- else -}}
cluster.local/{{ template "nfs-provisioner.fullname" . -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,31 @@
{{ if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "nfs-provisioner.fullname" . }}
labels:
app: {{ template "nfs-provisioner.name" . }}
chart: {{ template "nfs-provisioner.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
{{- end -}}
@@ -0,0 +1,19 @@
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app: {{ template "nfs-provisioner.name" . }}
chart: {{ template "nfs-provisioner.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "nfs-provisioner.fullname" . }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "nfs-provisioner.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ template "nfs-provisioner.fullname" . }}
namespace: {{ .Release.Namespace }}
{{- end -}}
@@ -0,0 +1,47 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "nfs-provisioner.fullname" . }}
labels:
app: {{ template "nfs-provisioner.name" . }}
chart: {{ template "nfs-provisioner.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.nfsPort }}
targetPort: nfs
protocol: TCP
name: nfs
{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nfsNodePort))) }}
nodePort: {{ .Values.service.nfsNodePort }}
{{- end }}
- port: {{ .Values.service.mountdPort }}
targetPort: mountd
protocol: TCP
name: mountd
{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.mountdNodePort))) }}
nodePort: {{ .Values.service.mountdNodePort }}
{{- end }}
- port: {{ .Values.service.rpcbindPort }}
targetPort: rpcbind-tcp
protocol: TCP
name: rpcbind-tcp
{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.rpcbindNodePort))) }}
nodePort: {{ .Values.service.rpcbindNodePort }}
{{- end }}
- port: {{ .Values.service.rpcbindPort }}
targetPort: rpcbind-udp
protocol: UDP
name: rpcbind-udp
{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.rpcbindNodePort))) }}
nodePort: {{ .Values.service.rpcbindNodePort }}
{{- end }}
{{- if .Values.service.externalIPs }}
externalIPs:
{{ toYaml .Values.service.externalIPs | indent 4 }}
{{- end }}
selector:
app: {{ template "nfs-provisioner.name" . }}
release: {{ .Release.Name }}
@@ -0,0 +1,11 @@
{{- if .Values.rbac.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: {{ template "nfs-provisioner.name" . }}
chart: {{ template "nfs-provisioner.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "nfs-provisioner.fullname" . }}
{{- end -}}
@@ -0,0 +1,107 @@
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: {{ template "nfs-provisioner.fullname" . }}
labels:
app: {{ template "nfs-provisioner.name" . }}
chart: {{ template "nfs-provisioner.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
# TODO: Investigate how/if nfs-provisioner can be scaled out beyond 1 replica
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ template "nfs-provisioner.name" . }}
release: {{ .Release.Name }}
serviceName: {{ template "nfs-provisioner.fullname" . }}
template:
metadata:
labels:
app: {{ template "nfs-provisioner.name" . }}
chart: {{ template "nfs-provisioner.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
# NOTE: This is 10 seconds longer than the default nfs-provisioner --grace-period value of 90sec
terminationGracePeriodSeconds: 100
serviceAccountName: {{ if .Values.rbac.create }}{{ template "nfs-provisioner.fullname" . }}{{ else }}{{ .Values.rbac.serviceAccountName | quote }}{{ end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: nfs
containerPort: 2049
protocol: TCP
- name: mountd
containerPort: 20048
protocol: TCP
- name: rpcbind-tcp
containerPort: 111
protocol: TCP
- name: rpcbind-udp
containerPort: 111
protocol: UDP
securityContext:
capabilities:
add:
- DAC_READ_SEARCH
- SYS_RESOURCE
args:
- "-provisioner={{ template "nfs-provisioner.provisionerName" . }}"
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_NAME
value: {{ .Chart.Name }}
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: data
mountPath: /export
resources:
{{- with .Values.resources }}
resources:
{{ toYaml . | indent 12 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if not .Values.persistence.enabled }}
volumes:
- name: data
emptyDir: {}
{{- end }}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ {{ .Values.persistence.accessMode | quote }} ]
{{- if .Values.persistence.storageClass }}
{{- if (eq "-" .Values.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: {{ .Values.persistence.storageClass | quote }}
{{- end }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- end }}
@@ -0,0 +1,16 @@
{{ if .Values.storageClass.create -}}
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: {{ .Values.storageClass.name }}
labels:
app: {{ template "nfs-provisioner.name" . }}
chart: {{ template "nfs-provisioner.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
{{- if .Values.storageClass.defaultClass }}
annotations:
storageclass.kubernetes.io/is-default-class: "true"
{{- end }}
provisioner: {{ template "nfs-provisioner.provisionerName" . }}
{{ end -}}
+76
View File
@@ -0,0 +1,76 @@
# Default values for nfs-provisioner.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
# imagePullSecrets:
image:
repository: quay.io/kubernetes_incubator/nfs-provisioner
tag: v1.0.9
pullPolicy: IfNotPresent
service:
type: ClusterIP
nfsPort: 2049
mountdPort: 20048
rpcbindPort: 51413
# nfsNodePort:
# mountdNodePort:
# rpcbindNodePort:
externalIPs: []
persistence:
enabled: false
## Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
# storageClass: "-"
accessMode: ReadWriteOnce
size: 1Gi
## For creating the StorageClass automatically:
storageClass:
create: true
## Set a provisioner name. If unset, a name will be generated.
# provisionerName:
## Set StorageClass as the default StorageClass
## Ignored if storageClass.create is false
defaultClass: false
## Set a StorageClass name
## Ignored if storageClass.create is false
name: nfs
## For RBAC support:
rbac:
create: true
## Ignored if rbac.create is true
##
serviceAccountName: default
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}