Skip to content

Commit

Permalink
feat(CSI-213): support NFS transport (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeyberezansky authored Sep 12, 2024
2 parents 1e59384 + 3c57498 commit d581918
Show file tree
Hide file tree
Showing 30 changed files with 2,046 additions and 121 deletions.
14 changes: 7 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
FROM golang:1.22-alpine as go-builder

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / push-dev

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
# https://stackoverflow.com/questions/36279253/go-compiled-binary-wont-run-in-an-alpine-docker-container-on-ubuntu-host
RUN apk add --no-cache libc6-compat gcc
RUN apk add musl-dev
RUN apk add --no-cache libc6-compat gcc musl-dev
COPY go.mod /src/go.mod
COPY go.sum /src/go.sum
WORKDIR /src
Expand All @@ -26,13 +25,14 @@ RUN CGO_ENABLED=0 GOOS="linux" GOARCH="amd64" go build -a -ldflags '-X main.vers
FROM alpine:3.18
LABEL maintainers="WekaIO, LTD"
LABEL description="Weka CSI Driver"
# Add util-linux to get a new version of losetup.
RUN apk add util-linux libselinux libselinux-utils util-linux pciutils usbutils coreutils binutils findutils grep bash
# Update CA certificates
RUN apk add ca-certificates
RUN update-ca-certificates
ADD https://github.com/tigrawap/locar/releases/download/0.4.0/locar_linux_amd64 /locar
RUN chmod +x /locar
RUN apk add --no-cache util-linux libselinux libselinux-utils util-linux \
pciutils usbutils coreutils binutils findutils \
grep bash nfs-utils rpcbind ca-certificates
# Update CA certificates
RUN update-ca-certificates
COPY --from=go-builder /bin/wekafsplugin /wekafsplugin
ARG binary=/bin/wekafsplugin
EXPOSE 2049 111/tcp 111/udp
ENTRYPOINT ["/wekafsplugin"]
18 changes: 18 additions & 0 deletions charts/csi-wekafsplugin/templates/NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,21 @@ https://github.com/weka/csi-wekafs/tree/master/examples
| NEW FEATURES RELY ON API CONNECTIVITY TO WEKA CLUSTER AND WILL NOT BE SUPPORTED ON API-UNBOUND VOLUMES. |
| PLEASE MAKE SURE TO MIGRATE ALL EXISTING VOLUMES TO API-BASED SCHEME PRIOR TO NEXT VERSION UPGRADE. |
------------------------------------------------------------------------------------------------------------

{{- if or .Values.pluginConfig.mountProtocol.useNfs .Values.pluginConfig.mountProtocol.allowNfsFailback }}
-------------------------------------------------- WARNING -------------------------------------------------
{{- if .Values.pluginConfig.mountProtocol.useNfs }}
| WARNING: NFS PROTOCOL IS ENFORCED AND WILL ALWAYS BE USED FOR MOUNTING WEKA FILESYSTEMS! |
| NFS TRANSPORT DOES NOT PROVIDE MAXIMUM PERFORMANCE AND IS NOT RECOMMENDED FOR PRODUCTION USE. |
{{- else }}
| WARNING: NFS MOUNT PROTOCOL FAILBACK IS ENABLED, AND NFS MOUNTS WILL BE USED IF WEKA IS NOT INSTALLED. |
| NFS TRANSPORT DOES NOT PROVIDE MAXIMUM PERFORMANCE AND IS NOT RECOMMENDED FOR PRODUCTION USE. |
| HOWEVER, IN CERTAIN CASES WHEN WEKA CLIENT INSTALLATION IS NOT POSSIBLE, NFS MOUNTS WILL BE USED. |
| IF WEKA CLIENT IS INSTALLED ON NODES AFTER CSI PLUGIN INSTALLATION, RESTART IS REQUIRED FOR THE |
| CORRESPONDENT CSI PLUGIN COMPONENTS RUNNING ON THE NODE TO SWITCH BACK TO WEKAFS PROTOCOL MOUNTING. |
{{- end }}
| MAKE SURE THAT AT LEAST ONE INTERFACE GROUP IS CONFIGURED ON WEKA CLUSTER, OTHERWISE PROVISION WILL FAIL |
| REFER TO THE DOCUMENTATION ABOVE FOR MORE INFORMATION ON NFS INTERFACE GROUP CONFIGURATION. |
| REFER TO WEKA CUSTOMER SUCCESS TEAM FOR RECOMMENDED CONFIGURATION AND BEST PRACTICES |
------------------------------------------------------------------------------------------------------------
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ metadata:

allowPrivilegedContainer: true
allowHostDirVolumePlugin: true
{{- if .Values.hostNetwork }}
{{- if or .Values.hostNetwork .Values.pluginConfig.mountProtocol.allowNfsFailback .Values.pluginConfig.mountProtocol.useNfs }}
allowHostNetwork: true
{{- end }}
allowedVolumeTypes:
- hostPath
- secret
readOnlyRootFilesystem: false

allowHostPorts: true
runAsUser:
type: RunAsAny
seLinuxContext:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ spec:
nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8}}
{{- end }}
serviceAccountName: {{ .Release.Name }}-controller
{{- if .Values.hostNetwork }}
hostNetwork: {{ .Values.hostNetwork }}
{{- if or .Values.hostNetwork .Values.pluginConfig.mountProtocol.useNfs .Values.pluginConfig.mountProtocol.allowNfsFailback}}
hostNetwork: true
{{- end }}
containers:
- name: csi-attacher
Expand Down Expand Up @@ -215,6 +215,15 @@ spec:
- "--concurrency.createSnapshot={{ .Values.controller.concurrency.createSnapshot | default "1" }}"
- "--concurrency.deleteSnapshot={{ .Values.controller.concurrency.deleteSnapshot | default "1" }}"
{{- end }}
{{- if .Values.pluginConfig.mountProtocol.useNfs | default false }}
- "--usenfs"
{{- end }}
{{- if .Values.pluginConfig.mountProtocol.allowNfsFailback | default false }}
- "--allownfsfailback"
{{- end }}
{{- if .Values.pluginConfig.mountProtocol.interfaceGroupName }}
- "--interfacegroupname={{ .Values.pluginConfig.mountProtocol.interfaceGroupName }}"
{{- end }}
ports:
- containerPort: 9898
name: healthz
Expand Down Expand Up @@ -249,6 +258,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: KUBE_NODE_IP_ADDRESS
valueFrom:
fieldRef:
fieldPath: status.hostIP
volumeMounts:
- mountPath: /csi
name: socket-dir
Expand Down
17 changes: 15 additions & 2 deletions charts/csi-wekafsplugin/templates/nodeserver-daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ spec:
{{- if .Values.priorityClassName }}
priorityClassName: {{ .Values.priorityClassName }}
{{- end }}
{{- if .Values.hostNetwork }}
hostNetwork: {{ .Values.hostNetwork }}
{{- if or .Values.hostNetwork .Values.pluginConfig.mountProtocol.useNfs .Values.pluginConfig.mountProtocol.allowNfsFailback}}
hostNetwork: true
{{- end }}
initContainers:
- name: init
Expand Down Expand Up @@ -106,6 +106,15 @@ spec:
- "--concurrency.nodePublishVolume={{ .Values.node.concurrency.nodePublishVolume | default "1" }}"
- "--concurrency.nodeUnpublishVolume={{ .Values.node.concurrency.nodeUnpublishVolume | default "1" }}"
{{- end }}
{{- if .Values.pluginConfig.mountProtocol.useNfs | default false }}
- "--usenfs"
{{- end }}
{{- if .Values.pluginConfig.mountProtocol.allowNfsFailback | default false }}
- "--allownfsfailback"
{{- end }}
{{- if .Values.pluginConfig.mountProtocol.interfaceGroupName }}
- "--interfacegroupname={{ .Values.pluginConfig.mountProtocol.interfaceGroupName }}"
{{- end }}
ports:
- containerPort: 9899
name: healthz
Expand Down Expand Up @@ -136,6 +145,10 @@ spec:
value: {{ required "Provide CSI Driver Dynamic Volume Creation Path" .Values.dynamicProvisionPath }}
- name: X_CSI_MODE
value: node
- name: KUBE_NODE_IP_ADDRESS
valueFrom:
fieldRef:
fieldPath: status.hostIP
volumeMounts:
- mountPath: /csi
name: socket-dir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:

allowPrivilegedContainer: true
allowHostDirVolumePlugin: true
{{- if .Values.hostNetwork }}
{{- if or .Values.hostNetwork .Values.pluginConfig.mountProtocol.allowNfsFailback .Values.pluginConfig.mountProtocol.useNfs }}
allowHostNetwork: true
{{- end }}
allowedVolumeTypes:
Expand Down
11 changes: 10 additions & 1 deletion charts/csi-wekafsplugin/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ metrics:
# -- Tracing URL (For Jaeger tracing engine / OpenTelemetry), optional
# @ignore
tracingUrl: ""
# -- Set to true to use host networking
# -- Set to true to use host networking. Will be always set to true when using NFS mount protocol
hostNetwork: false
pluginConfig:
# -- CSI Driver support for fsGroupPolicy, may be either "File" or "None". Default is "File"
Expand Down Expand Up @@ -140,3 +140,12 @@ pluginConfig:
snapshotVolumesWithoutQuotaEnforcement: false
mutuallyExclusiveMountOptions:
- "readcache,writecache,coherent,forcedirect"
mountProtocol:
# -- Use NFS transport for mounting Weka filesystems, off by default
useNfs: false
# -- Allow Failback to NFS transport if Weka client fails to mount filesystem using native protocol
allowNfsFailback: false
# -- Specify name of NFS interface group to use for mounting Weka filesystems. If not set, first NFS interface group will be used
interfaceGroupName: ""


6 changes: 6 additions & 0 deletions cmd/wekafsplugin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ var (
maxConcurrentNodeUnpublishVolumeReqs = flag.Int64("concurrency.nodeUnpublishVolume", 1, "Maximum concurrent NodeUnpublishVolume requests")
grpcRequestTimeoutSeconds = flag.Int("grpcrequesttimeoutseconds", 30, "Time out requests waiting in queue after X seconds")
allowProtocolContainers = flag.Bool("allowprotocolcontainers", false, "Allow protocol containers to be used for mounting filesystems")
allowNfsFailback = flag.Bool("allownfsfailback", false, "Allow NFS failback")
useNfs = flag.Bool("usenfs", false, "Use NFS for mounting volumes")
interfaceGroupName = flag.String("interfacegroupname", "", "Name of the NFS interface group to use for mounting volumes")
// Set by the build process
version = ""
)
Expand Down Expand Up @@ -217,6 +220,9 @@ func handle() {
*maxConcurrentNodeUnpublishVolumeReqs,
*grpcRequestTimeoutSeconds,
*allowProtocolContainers,
*allowNfsFailback,
*useNfs,
*interfaceGroupName,
)
driver, err := wekafs.NewWekaFsDriver(
*driverName, *nodeID, *endpoint, *maxVolumesPerNode, version, *debugPath, csiMode, *selinuxSupport, config)
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/prometheus/client_golang v1.19.1
github.com/rs/zerolog v1.33.0
github.com/showa-93/go-mask v0.6.2
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/otel v1.28.0
go.opentelemetry.io/otel/exporters/jaeger v1.17.0
go.opentelemetry.io/otel/sdk v1.28.0
Expand All @@ -30,13 +31,16 @@ require (
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
Expand All @@ -45,6 +49,7 @@ require (
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
)
14 changes: 12 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/container-storage-interface/spec v1.10.0 h1:YkzWPV39x+ZMTa6Ax2czJLLwpryrQ+dPesB34mrRMXA=
github.com/container-storage-interface/spec v1.10.0/go.mod h1:DtUvaQszPml1YJfIK7c00mlv6/g4wNMLanLgiUbKFRI=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
Expand All @@ -24,6 +25,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubernetes-csi/csi-lib-utils v0.18.1 h1:vpg1kbQ6lFVCz7mY71zcqVE7W0GAQXXBoFfHvbW3gdw=
github.com/kubernetes-csi/csi-lib-utils v0.18.1/go.mod h1:PIcn27zmbY0KBue4JDdZVfDF56tjcS3jKroZPi+pMoY=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
Expand All @@ -49,13 +54,15 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/showa-93/go-mask v0.6.2 h1:sJEUQRpbxUoMTfBKey5K9hCg+eSx5KIAZFT7pa1LXbM=
github.com/showa-93/go-mask v0.6.2/go.mod h1:aswIj007gm0EPAzOGES9ACy1jDm3QT08/LPSClMp410=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
Expand Down Expand Up @@ -89,6 +96,9 @@ google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc=
Expand Down
24 changes: 13 additions & 11 deletions pkg/wekafs/apiclient/apiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type ApiClient struct {
CompatibilityMap *WekaCompatibilityMap
clientHash uint32
hostname string
NfsInterfaceGroups map[string]*InterfaceGroup
}

type ApiEndPoint struct {
Expand Down Expand Up @@ -119,6 +120,7 @@ func NewApiClient(ctx context.Context, credentials Credentials, allowInsecureHtt
CompatibilityMap: &WekaCompatibilityMap{},
hostname: hostname,
actualApiEndpoints: make(map[string]*ApiEndPoint),
NfsInterfaceGroups: make(map[string]*InterfaceGroup),
}
a.resetDefaultEndpoints(ctx)

Expand Down Expand Up @@ -745,21 +747,21 @@ type ApiResponse struct {

// ApiObject generic interface of API object of any type (FileSystem, Quota, etc.)
type ApiObject interface {
GetType() string
GetBasePath(a *ApiClient) string
GetApiUrl(a *ApiClient) string
EQ(other ApiObject) bool
getImmutableFields() []string
String() string
GetType() string // returns the type of the object
GetBasePath(a *ApiClient) string // returns the base path of objects of this type (plural)
GetApiUrl(a *ApiClient) string // returns the full URL of the object consisting of base path and object UID
EQ(other ApiObject) bool // a way to compare objects and check if they are the same
getImmutableFields() []string // provides a list of fields that are used for comparison in EQ()
String() string // returns a string representation of the object
}

// ApiObjectRequest interface that describes a request for an ApiObject CRUD operation
type ApiObjectRequest interface {
getRequiredFields() []string
hasRequiredFields() bool
getRelatedObject() ApiObject
getApiUrl(a *ApiClient) string
String() string
getRequiredFields() []string // returns a list of fields that are mandatory for the object for creation
hasRequiredFields() bool // checks if all mandatory fields are filled in
getRelatedObject() ApiObject // returns the type of object that is being requested
getApiUrl(a *ApiClient) string // returns the full URL of the object consisting of base path and object UID
String() string // returns a string representation of the object request
}

type Credentials struct {
Expand Down
Loading

0 comments on commit d581918

Please sign in to comment.