Add local-path-provisioner

This commit is contained in:
dvirlabs 2025-06-03 02:44:25 +03:00
parent f1a2b4eb79
commit 92b012b3dd
15 changed files with 573 additions and 0 deletions

View File

@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: local-path-provisioner
namespace: argocd
spec:
project: infra
destination:
server: https://kubernetes.default.svc
namespace: infra
source:
repoURL: https://git.example.com/devops/infra.git
targetRevision: HEAD
path: charts/local-path-provisioner
helm:
valueFiles:
- ../../manifests/local-path-provisioner/values.yaml
syncPolicy:
automated:
selfHeal: true
prune: true
syncOptions:
- CreateNamespace=true

View File

@ -0,0 +1,22 @@
# 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
.vscode/

View File

@ -0,0 +1,12 @@
apiVersion: v1
appVersion: v0.0.22
description: Use HostPath for persistent local storage with Kubernetes
home: https://github.com/rancher/local-path-provisioner
keywords:
- storage
- hostpath
kubeVersion: '>=1.12.0-r0'
name: local-path-provisioner
sources:
- https://github.com/rancher/local-path-provisioner.git
version: 0.0.22

View File

@ -0,0 +1,116 @@
# Local Path Provisioner
[Local Path Provisioner](https://github.com/rancher/local-path-provisioner) provides a way for the Kubernetes users to
utilize the local storage in each node. Based on the user configuration, the Local Path Provisioner will create
`hostPath` based persistent volume on the node automatically. It utilizes the features introduced by Kubernetes [Local
Persistent Volume feature](https://kubernetes.io/blog/2018/04/13/local-persistent-volumes-beta/), but make it a simpler
solution than the built-in `local` volume feature in Kubernetes.
## TL;DR;
```console
$ git clone https://github.com/rancher/local-path-provisioner.git
$ cd local-path-provisioner
$ helm install --name local-path-storage --namespace local-path-storage ./deploy/chart/
```
## Introduction
This chart bootstraps a [Local Path Provisioner](https://github.com/rancher/local-path-provisioner) deployment on a
[Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
## Prerequisites
- Kubernetes 1.12+ with Beta APIs enabled
## Installing the Chart
To install the chart with the release name `local-path-storage`:
```console
$ git clone https://github.com/rancher/local-path-provisioner.git
$ cd local-path-provisioner
$ helm install ./deploy/chart/ --name local-path-storage --namespace local-path-storage
```
The command deploys Local Path Provisioner on the Kubernetes cluster in the default configuration. The
[configuration](#configuration) section lists the parameters that can be configured during installation.
> **Tip**: List all releases using `helm list`
## Uninstalling the Chart
To uninstall/delete the `local-path-storage` deployment:
```console
$ helm delete --purge local-path-storage
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Configuration
The following table lists the configurable parameters of the Local Path Provisioner for Kubernetes chart and their
default values.
| Parameter | Description | Default |
| ----------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `image.repository` | Local Path Provisioner image name | `rancher/local-path-provisioner` |
| `image.tag` | Local Path Provisioner image tag | `v0.0.22` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `storageClass.create` | If true, create a `StorageClass` | `true` |
| `storageClass.provisionerName` | The provisioner name for the storage class | `nil` |
| `storageClass.defaultClass` | If true, set the created `StorageClass` as the cluster's default `StorageClass` | `false` |
| `storageClass.name` | The name to assign the created StorageClass | local-path |
| `storageClass.reclaimPolicy` | ReclaimPolicy field of the class | Delete |
| `nodePathMap` | Configuration of where to store the data on each node | `[{node: DEFAULT_PATH_FOR_NON_LISTED_NODES, paths: [/opt/local-path-provisioner]}]` |
| `resources` | Local Path Provisioner resource requests & limits | `{}` |
| `rbac.create` | If true, create & use RBAC resources | `true` |
| `serviceAccount.create` | If true, create the Local Path Provisioner service account | `true` |
| `serviceAccount.name` | Name of the Local Path Provisioner service account to use or create | `nil` |
| `nodeSelector` | Node labels for Local Path Provisioner pod assignment | `{}` |
| `tolerations` | Node taints to tolerate | `[]` |
| `affinity` | Pod affinity | `{}` |
| `configmap.setup` | Configuration of script to execute setup operations on each node | #!/bin/sh<br>while getopts "m:s:p:" opt<br>do<br>&emsp;case $opt in <br>&emsp;&emsp;p)<br>&emsp;&emsp;absolutePath=$OPTARG<br>&emsp;&emsp;;;<br>&emsp;&emsp;s)<br>&emsp;&emsp;sizeInBytes=$OPTARG<br>&emsp;&emsp;;;<br>&emsp;&emsp;m)<br>&emsp;&emsp;volMode=$OPTARG<br>&emsp;&emsp;;;<br>&emsp;esac<br>done<br>mkdir -m 0777 -p ${absolutePath} |
| `configmap.teardown` | Configuration of script to execute teardown operations on each node | #!/bin/sh<br>while getopts "m:s:p:" opt<br>do<br>&emsp;case $opt in <br>&emsp;&emsp;p)<br>&emsp;&emsp;absolutePath=$OPTARG<br>&emsp;&emsp;;;<br>&emsp;&emsp;s)<br>&emsp;&emsp;sizeInBytes=$OPTARG<br>&emsp;&emsp;;;<br>&emsp;&emsp;m)<br>&emsp;&emsp;volMode=$OPTARG<br>&emsp;&emsp;;;<br>&emsp;esac<br>done<br>rm -rf ${absolutePath} |
| `configmap.name` | configmap name | `local-path-config` |
| `configmap.helperPod` | helper pod yaml file | apiVersion: v1<br>kind: Pod<br>metadata:<br>&emsp;name: helper-pod<br>spec:<br>&emsp;containers:<br>&emsp;- name: helper-pod<br>&emsp;&emsp;image: busybox |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```console
$ helm install ./deploy/chart/ --name local-path-storage --namespace local-path-storage --set storageClass.provisionerName=rancher.io/local-path
```
Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the
chart. For example,
```console
$ helm install --name local-path-storage --namespace local-path-storage ./deploy/chart/ -f values.yaml
```
> **Tip**: You can use the default [values.yaml](values.yaml)
## RBAC
By default the chart will install the recommended RBAC roles and rolebindings.
You need to have the flag `--authorization-mode=RBAC` on the api server. See the following document for how to enable
[RBAC](https://kubernetes.io/docs/admin/authorization/rbac/).
To determine if your cluster supports RBAC, run the following command:
```console
$ kubectl api-versions | grep rbac
```
If the output contains "beta", you may install the chart with RBAC enabled (see below).
### Enable RBAC role/rolebinding creation
To enable the creation of RBAC resources (On clusters with RBAC). Do the following:
```console
$ helm install ./deploy/chart/ --name local-path-storage --namespace local-path-storage --set rbac.create=true
```

View File

@ -0,0 +1,13 @@
You can create a hostpath-backed persistent volume with a persistent volume claim like this:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-path-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: {{ .Values.storageClass.name }}
resources:
requests:
storage: 2Gi

View File

@ -0,0 +1,71 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "local-path-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 "local-path-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 "local-path-provisioner.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "local-path-provisioner.labels" -}}
app.kubernetes.io/name: {{ include "local-path-provisioner.name" . }}
helm.sh/chart: {{ include "local-path-provisioner.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Create the name of the service account to use.
*/}}
{{- define "local-path-provisioner.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "local-path-provisioner.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{/*
Create the name of the provisioner to use.
*/}}
{{- define "local-path-provisioner.provisionerName" -}}
{{- if .Values.storageClass.provisionerName -}}
{{- printf .Values.storageClass.provisionerName -}}
{{- else -}}
cluster.local/{{ template "local-path-provisioner.fullname" . -}}
{{- end -}}
{{- end -}}
{{- define "local-path-provisioner.secret" }}
{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.privateRegistry.registryUrl (printf "%s:%s" .Values.privateRegistry.registryUser .Values.privateRegistry.registryPasswd | b64enc) | b64enc }}
{{- end }}

View File

@ -0,0 +1,21 @@
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "local-path-provisioner.fullname" . }}
labels:
{{ include "local-path-provisioner.labels" . | indent 4 }}
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumeclaims", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["endpoints", "persistentvolumes", "pods"]
verbs: ["*"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
{{- end -}}

View File

@ -0,0 +1,16 @@
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "local-path-provisioner.fullname" . }}
labels:
{{ include "local-path-provisioner.labels" . | indent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "local-path-provisioner.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ template "local-path-provisioner.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end -}}

View File

@ -0,0 +1,18 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.configmap.name }}
labels:
{{ include "local-path-provisioner.labels" . | indent 4 }}
data:
config.json: |-
{
"nodePathMap": {{ .Values.nodePathMap | toPrettyJson | nindent 8 }}
}
setup: |-
{{ .Values.configmap.setup | nindent 4 }}
teardown: |-
{{ .Values.configmap.teardown | nindent 4 }}
helperPod.yaml: |-
{{ .Values.configmap.helperPod | nindent 4 }}

View File

@ -0,0 +1,85 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "local-path-provisioner.fullname" . }}
labels:
{{ include "local-path-provisioner.labels" . | indent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "local-path-provisioner.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "local-path-provisioner.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "local-path-provisioner.serviceAccountName" . }}
containers:
- name: {{ .Chart.Name }}
{{- if .Values.privateRegistry.registryUrl }}
image: "{{ .Values.privateRegistry.registryUrl }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}"
{{- else }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- local-path-provisioner
- --debug
- start
- --config
- /etc/config/config.json
- --service-account-name
- {{ template "local-path-provisioner.serviceAccountName" . }}
- --provisioner-name
- {{ template "local-path-provisioner.provisionerName" . }}
- --helper-image
{{- if .Values.privateRegistry.registryUrl }}
- "{{ .Values.privateRegistry.registryUrl }}/{{ .Values.helperImage.repository }}:{{ .Values.helperImage.tag }}"
{{- else }}
- "{{ .Values.helperImage.repository }}:{{ .Values.helperImage.tag }}"
{{- end }}
- --configmap-name
- {{ .Values.configmap.name }}
{{- if .Values.workerThreads }}
- --worker-threads
- {{ .Values.workerThreads }}
{{- end }}
{{- if .Values.provisioningRetryCount }}
- --provisioning-retry-count
- {{ .Values.provisioningRetryCount }}
{{- end }}
{{- if .Values.deletionRetryCount }}
- --deletion-retry-count
- {{ .Values.deletionRetryCount }}
{{- end }}
volumeMounts:
- name: config-volume
mountPath: /etc/config/
env:
- name: POD_NAMESPACE
value: {{ .Release.Namespace }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: config-volume
configMap:
name: {{ .Values.configmap.name }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,9 @@
{{- if .Values.defaultSettings.registrySecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.defaultSettings.registrySecret }}
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: {{ template "local-path-provisioner.secret" . }}
{{- end }}

View File

@ -0,0 +1,15 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "local-path-provisioner.serviceAccountName" . }}
labels:
{{ include "local-path-provisioner.labels" . | indent 4 }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- if .Values.defaultSettings.registrySecret }}
- name: {{ .Values.defaultSettings.registrySecret }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,16 @@
{{ if .Values.storageClass.create -}}
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: {{ .Values.storageClass.name }}
labels:
{{ include "local-path-provisioner.labels" . | indent 4 }}
{{- if .Values.storageClass.defaultClass }}
annotations:
storageclass.kubernetes.io/is-default-class: "true"
{{- end }}
provisioner: {{ template "local-path-provisioner.provisionerName" . }}
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: {{ .Values.storageClass.reclaimPolicy }}
allowVolumeExpansion: true
{{- end }}

View File

@ -0,0 +1,121 @@
# Default values for local-path-provisioner.
replicaCount: 1
image:
repository: rancher/local-path-provisioner
tag: v0.0.22
pullPolicy: IfNotPresent
helperImage:
repository: busybox
tag: latest
defaultSettings:
registrySecret: ~
privateRegistry:
registryUrl: ~
registryUser: ~
registryPasswd: ~
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
## For creating the StorageClass automatically:
storageClass:
create: true
## Set a provisioner name. If unset, a name will be generated.
# provisionerName: rancher.io/local-path
## 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: local-path
## ReclaimPolicy field of the class, which can be either Delete or Retain
reclaimPolicy: Delete
# nodePathMap is the place user can customize where to store the data on each node.
# 1. If one node is not listed on the nodePathMap, and Kubernetes wants to create volume on it, the paths specified in
# DEFAULT_PATH_FOR_NON_LISTED_NODES will be used for provisioning.
# 2. If one node is listed on the nodePathMap, the specified paths will be used for provisioning.
# 1. If one node is listed but with paths set to [], the provisioner will refuse to provision on this node.
# 2. If more than one path was specified, the path would be chosen randomly when provisioning.
#
# The configuration must obey following rules:
# 1. A path must start with /, a.k.a an absolute path.
# 2. Root directory (/) is prohibited.
# 3. No duplicate paths allowed for one node.
# 4. No duplicate node allowed.
nodePathMap:
- node: DEFAULT_PATH_FOR_NON_LISTED_NODES
paths:
- /opt/local-path-provisioner
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
rbac:
# Specifies whether RBAC resources should be created
create: true
serviceAccount:
# Specifies whether a ServiceAccount should be created
create: true
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
nodeSelector: {}
tolerations: []
affinity: {}
configmap:
# specify the config map name
name: local-path-config
# specify the custom script for setup and teardown
setup: |-
#!/bin/sh
set -eu
mkdir -m 0777 -p "$VOL_DIR"
teardown: |-
#!/bin/sh
set -eu
rm -rf "$VOL_DIR"
# specify the custom helper pod yaml
helperPod: |-
apiVersion: v1
kind: Pod
metadata:
name: helper-pod
spec:
containers:
- name: helper-pod
image: busybox
imagePullPolicy: IfNotPresent
# Number of provisioner worker threads to call provision/delete simultaneously.
# workerThreads: 4
# Number of retries of failed volume provisioning. 0 means retry indefinitely.
# provisioningRetryCount: 15
# Number of retries of failed volume deletion. 0 means retry indefinitely.
# deletionRetryCount: 15

View File

@ -0,0 +1,15 @@
storageClass:
defaultClass: true
name: local-path
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
config:
nodePathMap:
- node: DEFAULT_PATH_FOR_NON_LISTED_NODES
paths:
- /opt/local-path-provisioner
image:
repository: rancher/local-path-provisioner
tag: v0.0.24