feat: support dynamic provisioning
update doc add test test
This commit is contained in:
parent
ada407fd45
commit
a84d12ab46
|
|
@ -1,14 +1,57 @@
|
||||||
## CSI driver E2E usage example
|
## CSI driver E2E usage example
|
||||||
### Prerequisite
|
### Prerequisite
|
||||||
- [Set up a Samba Server on a Kubernetes cluster](./smb-provisioner/)
|
- [Set up a Samba Server on a Kubernetes cluster](./smb-provisioner/)
|
||||||
|
> this example will create a new Samba Server(`//smb-server.default.svc.cluster.local/share`) with credential stored in secret `smbcreds`
|
||||||
#### 1. Create PV/PVC bound with SMB share
|
- Use `kubectl create secret` to create `smbcreds` with Samba Server username, password
|
||||||
- Use `kubectl create secret` to create `smbcreds` with SMB username, password
|
> skip this if already done
|
||||||
```console
|
```console
|
||||||
kubectl create secret generic smbcreds --from-literal username=USERNAME --from-literal password="PASSWORD"
|
kubectl create secret generic smbcreds --from-literal username=USERNAME --from-literal password="PASSWORD"
|
||||||
```
|
```
|
||||||
> add `--from-literal domain=DOMAIN-NAME` for domain support
|
> add `--from-literal domain=DOMAIN-NAME` for domain support
|
||||||
|
|
||||||
|
### Option#1: Storage Class Usage
|
||||||
|
#### 1. Create a storage class
|
||||||
|
```yaml
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: smb
|
||||||
|
provisioner: smb.csi.k8s.io
|
||||||
|
parameters:
|
||||||
|
source: "//smb-server.default.svc.cluster.local/share"
|
||||||
|
csi.storage.k8s.io/node-stage-secret-name: "smbcreds"
|
||||||
|
csi.storage.k8s.io/node-stage-secret-namespace: "default"
|
||||||
|
createSubDir: "true" # optional: create a sub dir for new volume
|
||||||
|
reclaimPolicy: Retain # only retain is supported
|
||||||
|
volumeBindingMode: Immediate
|
||||||
|
mountOptions:
|
||||||
|
- dir_mode=0777
|
||||||
|
- file_mode=0777
|
||||||
|
- uid=1001
|
||||||
|
- gid=1001
|
||||||
|
```
|
||||||
|
- Run below command to create a storage class
|
||||||
|
```console
|
||||||
|
kubectl create -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/deploy/example/storageclass-smb.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Create a statefulset pod
|
||||||
|
```console
|
||||||
|
kubectl create -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/deploy/example/statefulset.yaml
|
||||||
|
```
|
||||||
|
- enter the pod container to verify
|
||||||
|
```console
|
||||||
|
# k exec -it statefulset-smb2-0 bash
|
||||||
|
root@statefulset-smb2-0:/# df -h
|
||||||
|
Filesystem Size Used Avail Use% Mounted on
|
||||||
|
...
|
||||||
|
//smb-server.default.svc.cluster.local/share 124G 15G 110G 12% /mnt/smb
|
||||||
|
/dev/sda1 124G 15G 110G 12% /etc/hosts
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option#2: PV/PVC Usage
|
||||||
|
#### 1. Create PV/PVC bound with SMB share
|
||||||
- Create a smb CSI PV, download [`pv-smb.yaml`](https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/deploy/example/pv-smb.yaml) file and edit `source` in `volumeAttributes`
|
- Create a smb CSI PV, download [`pv-smb.yaml`](https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/deploy/example/pv-smb.yaml) file and edit `source` in `volumeAttributes`
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
|
@ -68,6 +111,6 @@ Filesystem Size Used Avail Use% Mounted on
|
||||||
In the above example, there is a `/mnt/smb` directory mounted as cifs filesystem.
|
In the above example, there is a `/mnt/smb` directory mounted as cifs filesystem.
|
||||||
|
|
||||||
### 2.2 Create a deployment on Windows
|
### 2.2 Create a deployment on Windows
|
||||||
```
|
```console
|
||||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/deploy/example/windows/deployment.yaml
|
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/deploy/example/windows/deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ parameters:
|
||||||
source: "//smb-server.default.svc.cluster.local/share"
|
source: "//smb-server.default.svc.cluster.local/share"
|
||||||
csi.storage.k8s.io/node-stage-secret-name: "smbcreds"
|
csi.storage.k8s.io/node-stage-secret-name: "smbcreds"
|
||||||
csi.storage.k8s.io/node-stage-secret-namespace: "default"
|
csi.storage.k8s.io/node-stage-secret-namespace: "default"
|
||||||
|
createSubDir: "true" # optional: create a sub dir for new volume
|
||||||
reclaimPolicy: Retain # only retain is supported
|
reclaimPolicy: Retain # only retain is supported
|
||||||
volumeBindingMode: Immediate
|
volumeBindingMode: Immediate
|
||||||
mountOptions:
|
mountOptions:
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -82,6 +83,23 @@ func (d *Driver) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolu
|
||||||
return nil, fmt.Errorf("prepare publish failed for %s with error: %v", target, err)
|
return nil, fmt.Errorf("prepare publish failed for %s with error: %v", target, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context := req.GetVolumeContext()
|
||||||
|
var createSubDir string
|
||||||
|
for k, v := range context {
|
||||||
|
switch strings.ToLower(k) {
|
||||||
|
case createSubDirField:
|
||||||
|
createSubDir = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.EqualFold(createSubDir, "true") {
|
||||||
|
source = filepath.Join(source, req.GetVolumeId())
|
||||||
|
klog.V(2).Infof("NodePublishVolume: createSubDir(%s) MkdirAll(%s)", createSubDir, source)
|
||||||
|
if err := os.MkdirAll(source, 0750); err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, fmt.Sprintf("MkdirAll %s failed with error: %v", source, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
klog.V(2).Infof("NodePublishVolume: mounting %s at %s with mountOptions: %v", source, target, mountOptions)
|
klog.V(2).Infof("NodePublishVolume: mounting %s at %s with mountOptions: %v", source, target, mountOptions)
|
||||||
if err := d.mounter.Mount(source, target, "", mountOptions); err != nil {
|
if err := d.mounter.Mount(source, target, "", mountOptions); err != nil {
|
||||||
if removeErr := os.Remove(target); removeErr != nil {
|
if removeErr := os.Remove(target); removeErr != nil {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DriverName = "smb.csi.k8s.io"
|
DriverName = "smb.csi.k8s.io"
|
||||||
|
createSubDirField = "createsubdir"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Driver implements all interfaces of CSI drivers
|
// Driver implements all interfaces of CSI drivers
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ function cleanup {
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly CSC_BIN="$GOBIN/csc"
|
readonly CSC_BIN="$GOBIN/csc"
|
||||||
volumeid="volumetest"
|
readonly volname="citest-$(date +%s)"
|
||||||
endpoint='tcp://127.0.0.1:10000'
|
endpoint='tcp://127.0.0.1:10000'
|
||||||
staging_target_path='/tmp/stagingtargetpath'
|
staging_target_path='/tmp/stagingtargetpath'
|
||||||
target_path='/tmp/targetpath'
|
target_path='/tmp/targetpath'
|
||||||
|
|
@ -50,10 +50,17 @@ trap cleanup EXIT
|
||||||
sleep 5
|
sleep 5
|
||||||
# set secret for csc node stage
|
# set secret for csc node stage
|
||||||
export X_CSI_SECRETS=username=username,"password=test"
|
export X_CSI_SECRETS=username=username,"password=test"
|
||||||
|
params='source="//0.0.0.0/share",createSubDir="true"'
|
||||||
# Begin to run CSI functions one by one
|
# Begin to run CSI functions one by one
|
||||||
|
echo 'Create volume test:'
|
||||||
|
readonly value=$("$CSC_BIN" controller new --endpoint "$endpoint" --cap 1,block "$volname" --req-bytes 2147483648 --params "$params")
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
readonly volumeid=$(echo "$value" | awk '{print $1}' | sed 's/"//g')
|
||||||
|
echo "Got volume id: $volumeid"
|
||||||
|
|
||||||
echo "stage volume test:"
|
echo "stage volume test:"
|
||||||
"$CSC_BIN" node stage --endpoint "$endpoint" --cap 1,block --staging-target-path "$staging_target_path" --vol-context=source="//0.0.0.0/share" "$volumeid"
|
"$CSC_BIN" node stage --endpoint "$endpoint" --cap 1,block --vol-context=source="//0.0.0.0/share" --staging-target-path "$staging_target_path" "$volumeid"
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
# check cifs mount
|
# check cifs mount
|
||||||
|
|
@ -71,6 +78,10 @@ echo "unstage volume test:"
|
||||||
"$CSC_BIN" node unstage --endpoint "$endpoint" --staging-target-path "$staging_target_path" "$volumeid"
|
"$CSC_BIN" node unstage --endpoint "$endpoint" --staging-target-path "$staging_target_path" "$volumeid"
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
|
echo 'Delete volume test:'
|
||||||
|
"$CSC_BIN" controller del --endpoint "$endpoint" "$volumeid"
|
||||||
|
sleep 2
|
||||||
|
|
||||||
"$CSC_BIN" identity plugin-info --endpoint "$endpoint"
|
"$CSC_BIN" identity plugin-info --endpoint "$endpoint"
|
||||||
"$CSC_BIN" node get-info --endpoint "$endpoint"
|
"$CSC_BIN" node get-info --endpoint "$endpoint"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue