diff --git a/README.md b/README.md index a1a6c63..ae4ece8 100644 --- a/README.md +++ b/README.md @@ -110,31 +110,33 @@ As S3 is not a real file system there are some limitations to consider here. Dep The driver can be configured to use one of these mounters to mount buckets: -* [rclone](https://rclone.org/commands/rclone_mount) +* [geesefs](https://github.com/yandex-cloud/geesefs) (recommended and default) * [s3fs](https://github.com/s3fs-fuse/s3fs-fuse) -* [goofys](https://github.com/kahing/goofys) +* [rclone](https://rclone.org/commands/rclone_mount) * [s3backer](https://github.com/archiecobbs/s3backer) The mounter can be set as a parameter in the storage class. You can also create multiple storage classes for each mounter if you like. -All mounters have different strengths and weaknesses depending on your use case. Here are some characteristics which should help you choose a mounter: +Characteristics of different mounters (for more detailed information consult their own documentation): -#### rclone +#### GeeseFS -* Almost full POSIX compatibility (depends on caching mode) +* Almost full POSIX compatibility +* Good performance for both small and big files * Files can be viewed normally with any S3 client #### s3fs -* Large subset of POSIX +* Almost full POSIX compatibility +* Good performance for big files, poor performance for small files * Files can be viewed normally with any S3 client -#### goofys +#### rclone -* Weak POSIX compatibility -* Performance first +* Less POSIX compatible than s3fs +* Bad performance for big files, okayish performance for small files * Files can be viewed normally with any S3 client -* Does not support appends or random writes +* Doesn't create directory objects like s3fs or GeeseFS #### s3backer (experimental*) @@ -148,8 +150,6 @@ All mounters have different strengths and weaknesses depending on your use case. *s3backer is experimental at this point because volume corruption can occur pretty quickly in case of an unexpected shutdown of a Kubernetes node or CSI pod. The s3backer binary is not bundled with the normal docker image to keep that as small as possible. Use the `-full` image tag for testing s3backer. -Fore more detailed limitations consult the documentation of the different projects. - ## Troubleshooting ### Issues while creating PVC diff --git a/cmd/s3driver/Dockerfile b/cmd/s3driver/Dockerfile index 6d9e61e..00f91c1 100644 --- a/cmd/s3driver/Dockerfile +++ b/cmd/s3driver/Dockerfile @@ -10,8 +10,7 @@ FROM debian:buster-slim LABEL maintainers="Vitaliy Filippov " LABEL description="csi-s3 slim image" -# patched goofys -ADD goofys /usr/bin/ +ADD geesefs /usr/bin/ RUN apt-get update && \ apt-get install -y ca-certificates && \ diff --git a/deploy/kubernetes/examples/storageclass.yaml b/deploy/kubernetes/examples/storageclass.yaml index 60668af..067a00b 100644 --- a/deploy/kubernetes/examples/storageclass.yaml +++ b/deploy/kubernetes/examples/storageclass.yaml @@ -5,7 +5,7 @@ metadata: name: csi-s3 provisioner: ch.ctrox.csi.s3-driver parameters: - mounter: goofys + mounter: geesefs # to use an existing bucket, specify it here: # bucket: some-existing-bucket csi.storage.k8s.io/provisioner-secret-name: csi-s3-secret diff --git a/pkg/driver/driver_suite_test.go b/pkg/driver/driver_suite_test.go index ccd1ee2..2ef7a62 100644 --- a/pkg/driver/driver_suite_test.go +++ b/pkg/driver/driver_suite_test.go @@ -14,8 +14,8 @@ import ( var _ = Describe("S3Driver", func() { - Context("goofys", func() { - socket := "/tmp/csi-goofys.sock" + Context("geesefs", func() { + socket := "/tmp/csi-geesefs.sock" csiEndpoint := "unix://" + socket if err := os.Remove(socket); err != nil && !os.IsNotExist(err) { Expect(err).NotTo(HaveOccurred()) @@ -28,12 +28,12 @@ var _ = Describe("S3Driver", func() { Describe("CSI sanity", func() { sanityCfg := &sanity.Config{ - TargetPath: os.TempDir() + "/goofys-target", - StagingPath: os.TempDir() + "/goofys-staging", + TargetPath: os.TempDir() + "/geesefs-target", + StagingPath: os.TempDir() + "/geesefs-staging", Address: csiEndpoint, SecretsFile: "../../test/secret.yaml", TestVolumeParameters: map[string]string{ - "mounter": "goofys", + "mounter": "geesefs", "bucket": "testbucket0", }, } @@ -41,8 +41,8 @@ var _ = Describe("S3Driver", func() { }) }) - Context("goofys-no-bucket", func() { - socket := "/tmp/csi-goofys-no-bucket.sock" + Context("geesefs-no-bucket", func() { + socket := "/tmp/csi-geesefs-no-bucket.sock" csiEndpoint := "unix://" + socket if err := os.Remove(socket); err != nil && !os.IsNotExist(err) { Expect(err).NotTo(HaveOccurred()) @@ -55,12 +55,12 @@ var _ = Describe("S3Driver", func() { Describe("CSI sanity", func() { sanityCfg := &sanity.Config{ - TargetPath: os.TempDir() + "/goofys-no-bucket-target", - StagingPath: os.TempDir() + "/goofys-no-bucket-staging", + TargetPath: os.TempDir() + "/geesefs-no-bucket-target", + StagingPath: os.TempDir() + "/geesefs-no-bucket-staging", Address: csiEndpoint, SecretsFile: "../../test/secret.yaml", TestVolumeParameters: map[string]string{ - "mounter": "goofys", + "mounter": "geesefs", }, } sanity.GinkgoTest(sanityCfg) diff --git a/pkg/mounter/geesefs.go b/pkg/mounter/geesefs.go new file mode 100644 index 0000000..af6ff5f --- /dev/null +++ b/pkg/mounter/geesefs.go @@ -0,0 +1,60 @@ +package mounter + +import ( + "fmt" + "os" + + "github.com/ctrox/csi-s3/pkg/s3" +) + +const ( + geesefsCmd = "geesefs" + defaultRegion = "us-east-1" +) + +// Implements Mounter +type geesefsMounter struct { + meta *s3.FSMeta + endpoint string + region string + accessKeyID string + secretAccessKey string +} + +func newGeeseFSMounter(meta *s3.FSMeta, cfg *s3.Config) (Mounter, error) { + region := cfg.Region + // if endpoint is set we need a default region + if region == "" && cfg.Endpoint != "" { + region = defaultRegion + } + return &geesefsMounter{ + meta: meta, + endpoint: cfg.Endpoint, + region: region, + accessKeyID: cfg.AccessKeyID, + secretAccessKey: cfg.SecretAccessKey, + }, nil +} + +func (geesefs *geesefsMounter) Stage(stageTarget string) error { + return nil +} + +func (geesefs *geesefsMounter) Unstage(stageTarget string) error { + return nil +} + +func (geesefs *geesefsMounter) Mount(source string, target string) error { + fullPath := fmt.Sprintf("%s:%s", geesefs.meta.BucketName, geesefs.meta.Prefix) + // FIXME Add memory limits + args := []string{ + "--endpoint", geesefs.endpoint, + "--region", geesefs.region, + "-o", "allow_other", + fullPath, target, + } + args = append(args, geesefs.meta.MountOptions...) + os.Setenv("AWS_ACCESS_KEY_ID", geesefs.accessKeyID) + os.Setenv("AWS_SECRET_ACCESS_KEY", geesefs.secretAccessKey) + return fuseMount(target, geesefsCmd, args) +} diff --git a/pkg/mounter/goofys.go b/pkg/mounter/goofys.go deleted file mode 100644 index 1a75364..0000000 --- a/pkg/mounter/goofys.go +++ /dev/null @@ -1,60 +0,0 @@ -package mounter - -import ( - "fmt" - "os" - - "github.com/ctrox/csi-s3/pkg/s3" -) - -const ( - goofysCmd = "goofys" - defaultRegion = "us-east-1" -) - -// Implements Mounter -type goofysMounter struct { - meta *s3.FSMeta - endpoint string - region string - accessKeyID string - secretAccessKey string -} - -func newGoofysMounter(meta *s3.FSMeta, cfg *s3.Config) (Mounter, error) { - region := cfg.Region - // if endpoint is set we need a default region - if region == "" && cfg.Endpoint != "" { - region = defaultRegion - } - return &goofysMounter{ - meta: meta, - endpoint: cfg.Endpoint, - region: region, - accessKeyID: cfg.AccessKeyID, - secretAccessKey: cfg.SecretAccessKey, - }, nil -} - -func (goofys *goofysMounter) Stage(stageTarget string) error { - return nil -} - -func (goofys *goofysMounter) Unstage(stageTarget string) error { - return nil -} - -func (goofys *goofysMounter) Mount(source string, target string) error { - fullPath := fmt.Sprintf("%s:%s", goofys.meta.BucketName, goofys.meta.Prefix) - // FIXME Add memory limits - args := []string{ - "--endpoint", goofys.endpoint, - "--region", goofys.region, - "-o", "allow_other", - fullPath, target, - } - args = append(args, goofys.meta.MountOptions...) - os.Setenv("AWS_ACCESS_KEY_ID", goofys.accessKeyID) - os.Setenv("AWS_SECRET_ACCESS_KEY", goofys.secretAccessKey) - return fuseMount(target, goofysCmd, args) -} diff --git a/pkg/mounter/mounter.go b/pkg/mounter/mounter.go index 11a4f84..24bb942 100644 --- a/pkg/mounter/mounter.go +++ b/pkg/mounter/mounter.go @@ -27,7 +27,7 @@ type Mounter interface { const ( s3fsMounterType = "s3fs" - goofysMounterType = "goofys" + geesefsMounterType = "geesefs" s3backerMounterType = "s3backer" rcloneMounterType = "rclone" TypeKey = "mounter" @@ -43,12 +43,12 @@ func New(meta *s3.FSMeta, cfg *s3.Config) (Mounter, error) { mounter = cfg.Mounter } switch mounter { + case geesefsMounterType: + return newGeeseFSMounter(meta, cfg) + case s3fsMounterType: return newS3fsMounter(meta, cfg) - case goofysMounterType: - return newGoofysMounter(meta, cfg) - case s3backerMounterType: return newS3backerMounter(meta, cfg) @@ -56,8 +56,8 @@ func New(meta *s3.FSMeta, cfg *s3.Config) (Mounter, error) { return newRcloneMounter(meta, cfg) default: - // default to s3backer - return newS3backerMounter(meta, cfg) + // default to GeeseFS + return newGeeseFSMounter(meta, cfg) } }