<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>AWS S3 on Digi Hunch</title><link>https://static.digihunch.com/tag/aws-s3/</link><description>Recent content in AWS S3 on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Thu, 17 Apr 2025 14:04:59 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/aws-s3/index.xml" rel="self" type="application/rss+xml"/><item><title>MinIO for S3-compatible Object Storage</title><link>https://static.digihunch.com/2022/09/minio-object-storage/</link><pubDate>Fri, 09 Sep 2022 09:00:00 -0400</pubDate><guid>https://static.digihunch.com/2022/09/minio-object-storage/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-minio.webp" alt="Featured image of post MinIO for S3-compatible Object Storage" /&gt;&lt;p class="wp-block-paragraph"&gt;I reviewed some storage technologies on Kubernetes but they are all for block and file storage. In this post, I will discuss the current available options for container workload to use object storage. I will also touch on MinIO as an object storage solution.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-object-storage"&gt;Object storage&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Block and file system are more native to operating system because they present themselves to the OS as a block device or file system attached to the OS. In other words, application processes running on the OS will be able to access the storage by address expressed as a POSIX-compatible path. On the contrary, object storage is a REST API service, operating at the application layer in the TCP/IP stack. Therefore, we can think of object storage as &amp;#8220;storage as a web service&amp;#8221;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Object storage can be made very cheap. However, the application protocol may vary depending on the object storage provider. Amazon S3 is a forerunner in object storage market and its protocol has emerged as the de-facto standard for object storage. When building an application and if there is one object storage protocol to support, it should be S3. For non-S3 object storage services, we can front them with an S3 interface, if the provider itself does not have one. For example Ceph storage has its &lt;a href="https://docs.ceph.com/en/latest/radosgw/s3/"&gt;Gateway S3 API&lt;/a&gt;. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Container Object Storage Interface&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;If we use S3 as the universal object storage protocol, does that also address object storage access with container workload on Kubernetes? Absolutely. Nonetheless, for a number of reasons using REST API from containers are not the best option. From platform&amp;#8217;s perspective, it is the platform that should define how to access object storage, instead of leaving it with an application-layer protocol. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When a pattern (for storage, or networking, etc) turns out very common, the platform layer should incorporate it as an infrastructure service, manage it with its own standard, and provide it to application so that developer can focus on business features. With that vision, the community brought up the &lt;a href="https://github.com/kubernetes-sigs/container-object-storage-interface"&gt;Container Object Storage Interface&lt;/a&gt; (COSI) initiative. It is currently in very early stage, but the idea is to commoditize object storage in Kubernetes platform with a unified interface. For more background about this initiative, refer to the post &amp;#8220;&lt;a href="https://thenewstack.io/beyond-block-and-file-cosi-enables-object-storage-in-kubernetes/"&gt;Beyond block and file &amp;#8211; COSI enables object storage in Kubernetes&lt;/a&gt;&amp;#8220;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;COSI is the ultimate cloud native solution but it is still in pre-alpha phase as of mid 2022. Unfortunately, it is not a recommended solution to any real-life project in 2022, and we are stuck with the unified API approach until COSI matures.. The unified API approach is by no means cloud native, but has come to maturity for adoption. S3 Rest API is our friend, regardless of whether the client process is in a container or not.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Update: on Sept 2, 2022, Kubernetes &lt;a href="https://kubernetes.io/blog/2022/09/02/cosi-kubernetes-object-storage-management/"&gt;introduced COSI&lt;/a&gt; as alpha feature.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;MinIO Introduction&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In order to use S3 protocol without using Amazon S3 storage, we can use MinIO to build our own object storage service serve client via a S3-compatible REST API interface. The main developer of the &lt;a href="https://min.io/"&gt;MinIO&lt;/a&gt; project is MinIO Inc, a startup from 2014. Having learned the lessons from GlusterFS, the founders and developers make MinIO very simple. MinIO operates in two modes: gateway mode (soon to be legacy) and server mode.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the Gateway mode, MinIO as a gateway between client and destination storage, and does not persist data to itself. In the past, the destination storage can be Azure Blob and Google Cloud Storage (GCS) and HDFS as backend. However, these supports are &lt;a href="https://github.com/minio/minio/pull/14418"&gt;deprecated&lt;/a&gt; now. The current release (July 2022) only supports S3 and NAS backend. According to MinIO&amp;#8217;s blog &lt;a href="https://blog.min.io/deprecation-of-the-minio-gateway/"&gt;post&lt;/a&gt; from February 2022, the entire MinIO Gateway feature will be removed in August, leaving server mode the only option for MinIO.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the Server mode, the MinIO service will persist data to itself in a file system (or volume). You can specify that file system (or volume) as you launch the server. As one of the &lt;a href="https://docs.min.io/docs/minio-quickstart-guide.html"&gt;quick-start guides&lt;/a&gt; shows, we can host MinIO server using a single executable. For administrative tasks, MinIO has a web console and a client utility called mc.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;MinIO Deployment Options&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For storage service, there are a number of &lt;a href="https://docs.min.io/minio/baremetal/installation/deployment-and-management.html"&gt;deployment options&lt;/a&gt;: &lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;SNSD (single-node, single-drive): single MinIO server with a single storage volume or folder. &lt;/li&gt;&#10;&lt;li&gt;SNMD (signle-node, multi-drive): single MinIO server with four or more storage volumes.&lt;/li&gt;&#10;&lt;li&gt;MNMD (multi-node, multi-drive, aka distributed): multiple MinIO servers with at least four drives across all servers. This should be considered for production grade configuration.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The deployment options above describes the node and volume topology. No matter which topology option, there are also a number of ways to host the MinIO service process: on &lt;a href="https://min.io/docs/minio/linux/index.html"&gt;Linux OS&lt;/a&gt;, &lt;a href="https://min.io/docs/minio/windows/index.html"&gt;Windows OS&lt;/a&gt;, &lt;a href="https://min.io/docs/minio/macos/index.html"&gt;MacOS&lt;/a&gt;, &lt;a href="https://min.io/docs/minio/container/index.html"&gt;Docker Container&lt;/a&gt;, and on &lt;a href="https://min.io/docs/minio/kubernetes/upstream/index.html"&gt;Kubernetes&lt;/a&gt; platform. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In addition, MinIO Inc ships the software under different business models. For example, there are fully managed applications in &lt;a href="https://web.archive.org/web/20220927211802/https://azuremarketplace.microsoft.com/en-us/marketplace/apps/minio.minio-object-storage_v1dot1"&gt;Azure Marketplace&lt;/a&gt;, &lt;a href="https://aws.amazon.com/marketplace/pp/prodview-smchi7bcs4nn4"&gt;AWS Marketplace&lt;/a&gt;, and &lt;a href="https://console.cloud.google.com/marketplace/product/minio-inc-public/minio-enterprise"&gt;GCP Marketplace&lt;/a&gt; all hosted on virtual machines with extra charges. Clients not willing to pay can host MinIO storage all on their own, either on virtual machines, or on managed Kubernetes environment provided by each cloud provider. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;MinIO Hosting solutions&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;MinIO lists these hosting solutions under multi-cloud products. These hosting solutions (or &amp;#8220;products&amp;#8221; in MinIO&amp;#8217;s term) vary in terms of where peripheral services and data tiers are hosted. Here is the list of the supported platforms:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;a href="https://min.io/product/kubernetes"&gt;(generic) Kubernetes&lt;/a&gt;;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://min.io/product/private-cloud-vmware-tanzu"&gt;VMWare Tanzu&lt;/a&gt;;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://min.io/product/private-cloud-red-hat-openshift"&gt;OpenShift&lt;/a&gt;;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://min.io/product/multicloud-suse-rancher"&gt;SUSE Rancher&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://min.io/product/multicloud-elastic-kubernetes-service"&gt;EKS&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://min.io/product/multicloud-azure-kubernetes-service"&gt;AKS&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://min.io/product/multicloud-google-kubernetes-service"&gt;GKE&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To illustrate how these solutions are different, I put some details on a few options together for an incomplete comparison below:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-regular"&gt;&lt;table class="has-very-light-gray-to-cyan-bluish-gray-gradient-background has-background"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;EKS&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;AKS&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;GKE&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Hot Storage&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Direct PV (NVMe)&lt;/td&gt;&lt;td&gt;EKS EBS CSI&lt;/td&gt;&lt;td&gt;Azure CSI &lt;/td&gt;&lt;td&gt;GKE Standard SSD&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Warm Storage&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Direct PV (HDD)&lt;/td&gt;&lt;td&gt;S3 IA&lt;/td&gt;&lt;td&gt;Azure BlobStore&lt;/td&gt;&lt;td&gt;GCS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Cold Storage&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Public Cloud storage&lt;/td&gt;&lt;td&gt;Glacier&lt;/td&gt;&lt;td&gt;Azure Cool Blob&lt;/td&gt;&lt;td&gt;GCS for Data Archiving&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Encryption&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;HashiCorp Vault&lt;/td&gt;&lt;td&gt;KMS&lt;/td&gt;&lt;td&gt;Azure Key Vault&lt;/td&gt;&lt;td&gt;Cloud Key Management&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Observability&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Elastic Stack and Grafana&lt;/td&gt;&lt;td&gt;Managed ElasticSearch Prometheus&lt;/td&gt;&lt;td&gt;Azure Monitor&lt;/td&gt;&lt;td&gt;Stack Driver&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Identity Provider&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;KeyCloak&lt;/td&gt;&lt;td&gt;LDAP, SSO&lt;/td&gt;&lt;td&gt;Azure Active Directory&lt;/td&gt;&lt;td&gt;GCP Cloud Identity&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;LB and Cert Mgmt&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Nginx, Let&amp;#8217;s Entrypt&lt;/td&gt;&lt;td&gt;AWS Cert Mgr, ELB&lt;/td&gt;&lt;td&gt;Azure Load Balancer, JetStack, Let&amp;#8217;s Encrypt&lt;/td&gt;&lt;td&gt;GCP Cloud LB and Managed Cert&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Note that all of these hosting solutions are based on some flavour of Kubernetes. The hot tier is usually based on storage options available to the platform. MinIO service access this hot tier via Kubernetes persistent volume. The warm and cold tiers are backed by different object storage service. Between MinIO and storage client, it always use the same S3 compatible Rest API.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;MinIO also has tiering capability. While the hot storage destination has to be either a file system or Kubernetes persistent volume, remote tiers can be S3 , Azure Blob, or GCS. MinIO supports encryption at rest (SSE-KMS, SSE-S3, SSE-C) and in transit (TLS) for security, as well as many other useful features such as object &lt;a href="https://docs.min.io/minio/baremetal/replication/replication-overview.html"&gt;replication&lt;/a&gt;, &lt;a href="https://docs.min.io/minio/baremetal/object-retention/bucket-versioning.html"&gt;versioning&lt;/a&gt;, &lt;a href="https://docs.min.io/minio/baremetal/object-retention/minio-object-locking.html"&gt;locking&lt;/a&gt;, &lt;a href="https://docs.min.io/minio/baremetal/monitoring/bucket-notifications/bucket-notifications.html"&gt;events&lt;/a&gt;, Prometheus &lt;a href="https://docs.min.io/minio/baremetal/monitoring/metrics-alerts/minio-metrics-and-alerts.html"&gt;metrics&lt;/a&gt;, &lt;a href="https://docs.min.io/minio/baremetal/lifecycle-management/lifecycle-management-overview.html"&gt;lifecycle management&lt;/a&gt; etc. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Connect to MinIO server with S3 client&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To validate that the client is compatible, we use MinIO&amp;#8217;s client utility (mc) to connect to an AWS S3 bucket. Then we use AWS CLI to connect to a MinIO server, similar to this &lt;a href="https://docs.min.io/docs/aws-cli-with-minio"&gt;instruction&lt;/a&gt;. To do so, we first install client and server utilities:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install minio/stable/minio&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install minio/stable/mc&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;minio --version&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mc --version&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Then, we start MinIO server and store an object using AWS CLI&amp;#8217;s S3 tool. In our working directory, we create a new directory called minio_data and launch MinIO server with it:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir minio_data&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;minio server minio_data --console-address :9090&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Once the server is up, the screen should display the details, including the portal URL and the default username and password will be used as Access Key ID and Secret Key:&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img loading="lazy" decoding="async" width="1307" height="649" src="https://static.digihunch.com/wp-content/uploads/2022/07/image-2.png" alt="" class="wp-image-6276"/&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Note that the MinIO service does NOT have &lt;a href="https://docs.min.io/docs/how-to-secure-access-to-minio-server-with-tls.html"&gt;TLS enabled&lt;/a&gt; by default, on the console or API service. At this point, we can browse to the console web page using the given credential. Then, we can configure AWS CLI with a new profile just to act as a client to communicate with the MinIO server:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws configure --profile minio-cli&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AWS Access Key ID &lt;span style="color:#f92672"&gt;[&lt;/span&gt;None&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: minioadmin&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AWS Secret Access Key &lt;span style="color:#f92672"&gt;[&lt;/span&gt;None&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: minioadmin&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Default region name &lt;span style="color:#f92672"&gt;[&lt;/span&gt;None&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: us-east-1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Default output format &lt;span style="color:#f92672"&gt;[&lt;/span&gt;None&lt;span style="color:#f92672"&gt;]&lt;/span&gt;: json&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws configure set default.s3.signature_version s3v4 --profile minio-cli&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;At this point, the AWS CLI is configured to communicate with MinIO server. Then, we can create bucket, list object in the bucket, copy an object to the bucket, etc&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws --endpoint-url http://127.0.0.1:9000 s3 ls --profile minio-cli &lt;span style="color:#75715e"&gt;# list all bucket, should return empty&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws --endpoint-url http://127.0.0.1:9000 s3 mb s3://hehebucket --profile minio-cli &lt;span style="color:#75715e"&gt;# create new bucket&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make_bucket: hehebucket&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws --endpoint-url http://127.0.0.1:9000 s3 cp README.md s3://hehebucket --profile minio-cli &lt;span style="color:#75715e"&gt;# copy a file to bucket as a new object&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;upload: ./README.md to s3://hehebucket/README.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws --endpoint-url http://127.0.0.1:9000 s3 ls s3://hehebucket --profile minio-cli &lt;span style="color:#75715e"&gt;# list objects in the bucket&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-07-09 00:30:23 &lt;span style="color:#ae81ff"&gt;631&lt;/span&gt; README.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The created bucket and object are also visible in MinIO web console, under &amp;#8220;Bucket&amp;#8221;:&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="947" height="235" src="https://static.digihunch.com/wp-content/uploads/2022/07/image-3.png" alt="" class="wp-image-6287"/&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The steps above validate that AWS CLI can talk to MinIO server. Because of that, MinIO server can emulate an S3 service in any development environment so users do not always have to use S3 from AWS. This makes sense for both cost and security reasons for the organization. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Connect to S3 with MinIO client&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In this lab, we create an S3 bucket and use mc utility to store an object to it. In order to consistently create S3 bucket and associated permissions, I use the CloudFormation template in &lt;a href="https://github.com/digihunch/cloudformation/blob/master/obj-store-helper/aws-s3-stack.yaml"&gt;this&lt;/a&gt; repo. The output of the CloudFormation stack returns the Access Key ID and Secret Key required for the client to access the bucket. Once we cloned the repo, let&amp;#8217;s enter the &lt;a href="https://github.com/digihunch/cloudformation/tree/master/obj-store-helper"&gt;obj-store-helper&lt;/a&gt; directory, and run aws cli command to launch the CloudFormation template, assuming it has been configured:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BUCKET_NAME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;c0sas2dsadigihunch&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;S3_STACK_NAME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$BUCKET_NAME-stack&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aws cloudformation create-stack --template-body file://aws-s3-stack.yaml --stack-name $S3_STACK_NAME --parameters ParameterKey&lt;span style="color:#f92672"&gt;=&lt;/span&gt;S3BucketName,ParameterValue&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$BUCKET_NAME --capabilities CAPABILITY_IAM&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# to delete stack after test, run: aws cloudformation delete-stack --stack-name $S3_STACK_NAME&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;In the AWS console, we should see the configuration information as below:&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="925" height="708" src="https://static.digihunch.com/wp-content/uploads/2022/07/image-1.png" alt="" class="wp-image-6266"/&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Supposed the bucket name is vna-tst-c0sas2dsadigihunch as shown above, this allows us to configure the client utility MC as below:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mc alias set awss3 https://s3.amazonaws.com &lt;span style="color:#75715e"&gt;# Fill in access key ID and Secret key at the prompt&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mc ls awss3/vna-tst-c0sas2dsadigihunch &lt;span style="color:#75715e"&gt;# list objects in the bucket, should return empty&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mc cp README.md awss3/vna-tst-c0sas2dsadigihunch/README.md &lt;span style="color:#75715e"&gt;# upload and object to bucket&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mc ls awss3/vna-tst-c0sas2dsadigihunch &lt;span style="color:#75715e"&gt;# list objects in the bucket, the uploaded object should be there&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mc rm awss3/vna-tst-c0sas2dsadigihunch/README.md &lt;span style="color:#75715e"&gt;# delete the object&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mc alias remove awss3 &lt;span style="color:#75715e"&gt;# remove awss3 alias&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Once we emptied the bucket, we can delete the CloudFormation stack. This test only needs client utility mc to verify that MinIO client is able to talk to AWS S3 server.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Erasure Coding&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For scalable production use, we should deploy MinIO in distributed mode. When MinIO is configured in &lt;a href="https://docs.min.io/minio/baremetal/installation/deploy-minio-distributed.html"&gt;distributed deployment&lt;/a&gt; (MNMD, or multi-node, multi-drive), it implicitly enables an important feature called &lt;a href="https://docs.min.io/minio/baremetal/concepts/erasure-coding.html#minio-erasure-coding"&gt;erasure coding&lt;/a&gt;. This erasure coding feature further unlocks a number of other MinIO features:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;a href="https://docs.min.io/minio/baremetal/object-retention/bucket-versioning.html#minio-bucket-versioning"&gt;Object Versioning&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://docs.min.io/minio/baremetal/replication/bucket-replication-overview.html#minio-bucket-replication-serverside"&gt;Server-Side Replication&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://docs.min.io/minio/baremetal/reference/minio-mc/mc-retention-set.html#minio-bucket-locking"&gt;Write-Once Read-Many (WORM) Locking&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Erasure coding is MinIO&amp;#8217;s data redundancy and availability feature that allows MinIO deployments to automatically reconstruct objects on-the-fly despite the loss of multiple drives or nodes in the cluster. Erasure coding provides object-level handling with less overhead than adjacent technologies such as RAID. The key concept is &lt;a href="https://docs.min.io/minio/baremetal/concepts/erasure-coding.html#erasure-sets"&gt;Erasure Set&lt;/a&gt;, a set of drives in a MinIO deployment that supports Erasure Coding. MinIO evenly distributes object data and parity blocks among the drives in the Erasure Set. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Two important variables are M and N: for a given erasure set of size M, MinIO splits objects into N parity blocks, and M-N data blocks. MinIO uses the &lt;a href="https://docs.min.io/minio/baremetal/concepts/erasure-coding.html#erasure-code-parity-ec-n"&gt;EC:N&lt;/a&gt; notation to refer to the number of parity blocks (N) in the deployment. To determine optimal erasure set size for the cluster, use MinIO&amp;#8217;s &lt;a href="https://min.io/product/erasure-code-calculator"&gt;Erasure Coding Calculator&lt;/a&gt; tool.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To help client to specify per-object parity with Erasure Coding, MinIO uses storage classes. Note that the storage class concept in MinIO is distinct from AWS &lt;a href="https://aws.amazon.com/s3/storage-classes/"&gt;S3 storage class&lt;/a&gt; or Kubernetes &lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/"&gt;storage class&lt;/a&gt;. In MinIO, a &lt;a href="https://github.com/minio/minio/tree/master/docs/erasure/storage-class"&gt;storage class&lt;/a&gt; defines parity settings per object. The STANDARD &lt;a href="https://docs.min.io/minio/baremetal/concepts/erasure-coding.html#storage-classes"&gt;storage class&lt;/a&gt; (default) defines EC:N based on M, which can be overridden. In addition, there is REDUCED_REDUNDANCY storage class, whose parity must be less than or equal to that of STANDARD storage class. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The &lt;a href="https://docs.min.io/minio/baremetal/concepts/erasure-coding.html#bitrot-protection"&gt;erasure coded backend&lt;/a&gt; also protects the storage against &lt;a href="https://github.com/minio/minio/blob/master/docs/erasure/README.md#what-is-bit-rot-protection"&gt;Bit Rot&lt;/a&gt; with HighwayHash algorithm. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;More Features&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Authentication and authorization between MinIO client and MinIO server have a number of options. MinIO client may use the built-in standalone identity management in MinIO server. This is the default mode. In addition, one may delegate IAM to external service. To Active Directory via LDAP, or any Identity provider that supports OIDC (JWT with Authorization Code Flow). &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;As to &lt;a href="https://docs.min.io/minio/baremetal/lifecycle-management/lifecycle-management-overview.html"&gt;Object Lifecycle Management&lt;/a&gt; (OLM), MinIO allows you to define a remote tier storage for each local target (bucket). The remote tier can be Amazon S3, Google Cloud Storage or Azure Blob storage. We can use mc utility to administer the remote tier and OLM. Configuration steps (e.g. &lt;a href="https://docs.min.io/minio/baremetal/lifecycle-management/transition-objects-to-azure.html"&gt;Azure&lt;/a&gt; Blob, &lt;a href="https://docs.min.io/minio/baremetal/lifecycle-management/transition-objects-to-s3.html"&gt;AWS S3&lt;/a&gt;) usually include:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;Configure required permissions on the MinIO bucket, create user account for OLM activities. &lt;/li&gt;&#10;&lt;li&gt;Configure the Remote Storage Tier&lt;/li&gt;&#10;&lt;li&gt;Create and Apply an ILM Transition Rule. The rule can be expressed in a json document.&lt;/li&gt;&#10;&lt;li&gt;Validate the creation of ILM transition rule&lt;/li&gt;&#10;&lt;li&gt;Validate the effect of transition rule. &lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;As for encryption, MinIO can support encryption at rest. It can also work with &lt;a href="https://static.digihunch.com/2022/06/etcd-the-key-value-store-for-kubernetes/"&gt;etcd&lt;/a&gt; store to store encrypted IAM assets if KMS is configured. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Conclusion&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Even though we watch for the progress of COSI initiative, we still use Rest API to access object storage from container, which is no different than from a virtual machine. If we develop an application, then we should make it support S3 protocol, a de-facto standard protocol for object storage. As for the storage backend, if we want to be vendor neutral, the feature-rich MinIO is the best bet. We can use MinIO to build our own Object storage as a service compatible with S3. We can also lifecycle our object to remote object storage tier backed by Azure, GCP or S3. In this post we validated the S3 compatibility, and discussed some advanced MinIO features.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2022/08/storage-solution-on-aks-2-of-3-ceph-by-rook/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Kubernetes Storage on Azure 3 of 3 – Ceph by Rook&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2022/09/build-a-kubernetes-cluster/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Build and Manage Kubernetes Clusters&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>File storage vs object storage in the cloud</title><link>https://static.digihunch.com/2021/09/file-storage-vs-object-storage/</link><pubDate>Thu, 23 Sep 2021 22:54:00 -0400</pubDate><guid>https://static.digihunch.com/2021/09/file-storage-vs-object-storage/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-file-obj-storage.webp" alt="Featured image of post File storage vs object storage in the cloud" /&gt;&lt;p class="wp-block-paragraph"&gt;File storage (e.g. NFS) used to be prevalent until object storage comes in for competition.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-the-competition"&gt;The competition&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Traditionally, enterprise storage product lines are built around three capabilities, as listed in this table below:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-stripes"&gt;&lt;table class="has-black-color has-white-background-color has-text-color has-background"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Capability&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Typical Implementation&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Data served&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;T1 &amp;#8211; &lt;br&gt;Block stroage&lt;/td&gt;&lt;td&gt;DAS (e.g. SAS cable) or SAN (Fibre Cable for FCP protocol, or Ethernet for iSCSI protocol)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Mission critical data that are extremely sensitive to latency (e.g. database). Client has block-level access.&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;T2 &amp;#8211; &lt;br&gt;File storage&lt;/td&gt;&lt;td&gt;NAS (connect via CIFS or NFS protocols). Storage arrays are typically a mix of HDD and SSD. Storage servers are usually deployed in the same location over low latency network. DR location is usually in the same region.&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Hot data. Multiple client access at file level. The size of each data request varies from small to medium (e.g. text document)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;T3 &amp;#8211; &lt;br&gt;Object storage&lt;/td&gt;&lt;td&gt;Hardware agnostic, connect via layer-7 protocol (e.g. S3). Storage backend can be either on premise, or in the cloud, over WAN connection.&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Warm and code data. Multiple client access at object level. Traditionally for backup but use cases are expanding. The size of each data request varies significantly, from small to very large (e.g. media content).&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the last couple decades, leading players for T2 have been enterprise storage vendors. They each have developed their secret sauces to tackle the challenges. For example, EMC has OneFS, a parallel distributed file system as the foundation of &lt;a href="https://static.digihunch.com/2020/07/emc-productlines/"&gt;PowerScale&lt;/a&gt; (formerly Isilon) product line. NetApp develops ONTAP, featuring proprietary techniques for storage efficiency (deduplication, compaction and compression).&amp;nbsp;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The leading players in T3 are mostly &lt;a href="https://static.digihunch.com/2020/08/cloud-storage-overview/"&gt;public cloud&lt;/a&gt; provider, such as Amazon&amp;#8217;s S3. They might work with enterprise storage vendor behind the scene. But the T3 services appear to the end users as provided by the public cloud. Originally, the use case for T3 was archive only for its virtually unlimited capacity. This is not entirely true today. With the drastic improvement in modern network infrastructure, T3 can also brings satisfactory performance to serve hot data. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A competition between T2 and T3 arises. After all, both offer storage service over Ethernet, and both support multiple clients. Today when developers architect the storage layer of their applications, they need to weigh between supporting T2 and T3. Since &lt;a href="https://static.digihunch.com/2020/07/nfs-network-file-system-and-rpc-remote-procedure-call/"&gt;NFS&lt;/a&gt; is the typical protocol for T2 storage (sorry Windows guys) and S3 is typical T3 storage. This competition essentially boils down to NFS versus S3.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For many, the fancy S3 is a no-brainer. While I have suffered from many NFS drawbacks, and there&amp;#8217;s even a whole &lt;a href="https://www.kernel.org/doc/ols/2006/ols2006v2-pages-59-72.pdf"&gt;article&lt;/a&gt; by Linux folks about why NFS sucks, is it sentenced to death today? Does it beat S3 in some cases? Do so many organizations still stick to NFS just out of inertia?&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To answer these questions, I examine four aspects to explore the differences between file storage via NFS protocol, and object storage in S3. &lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-data-request-size"&gt;Data request size&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Storage client can make request by byte range of a file. Therefore, data request size, instead of file size, is what ultimately matters. I pick a few data request sizes (1K, 4K, 16K, 64K, 246K, 1024K and 4096K) in my experiment, and want to see how much network traffic a write operation produces using NFS and using S3.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To emulate request size, I created files at each size (using dd command), and copy the entire file to each backend. In the mean time, I use tcpdump to write out traffic across the wire into capture files. The size of capture file gives me an idea of how much network traffic went through the network interface, which is closely related to latency. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For NFS, I mounted the target with sync option. This requires NFS client to write out to server synchronously on file copy. I&amp;#8217;ve also set the wsize to be 1M. For S3, I simply use the following CLI command to copy file:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aws s3 cp 1kb.img s3://digihunch5ffafe32ab0fd40f&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;On the network interface, I use tcpdump to filter traffic through specific TCP port (443 for S3, or 2049 for NFS) and record the size of the capture file:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo tcpdump -s0 -pi eth0 dst port &lt;span style="color:#ae81ff"&gt;443&lt;/span&gt; or src port &lt;span style="color:#ae81ff"&gt;443&lt;/span&gt; -w /tmp/4096kb.cap&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The key indicator is the payload size (file size) as a percentage of the capture size. I call it payload ratio. The closer it is to 1, the better. I have the following result from my experiment:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-stripes"&gt;&lt;table class="has-black-color has-white-background-color has-text-color has-background"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Request&lt;/td&gt;&lt;td&gt;Payload&lt;/td&gt;&lt;td&gt;S3 capture size (byte)&lt;/td&gt;&lt;td&gt;NFS capture size (byte)&lt;/td&gt;&lt;td&gt;S3 payload ratio&lt;/td&gt;&lt;td&gt;NFS payload ratio&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1K&lt;/td&gt;&lt;td&gt;1024&lt;/td&gt;&lt;td&gt;9352&lt;/td&gt;&lt;td&gt;4332&lt;/td&gt;&lt;td&gt;0.11&lt;/td&gt;&lt;td&gt;0.24&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4K&lt;/td&gt;&lt;td&gt;4096&lt;/td&gt;&lt;td&gt;12640&lt;/td&gt;&lt;td&gt;7404&lt;/td&gt;&lt;td&gt;0.32&lt;/td&gt;&lt;td&gt;0.55&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16K&lt;/td&gt;&lt;td&gt;16384&lt;/td&gt;&lt;td&gt;25969&lt;/td&gt;&lt;td&gt;20472&lt;/td&gt;&lt;td&gt;0.63&lt;/td&gt;&lt;td&gt;0.80&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;64K&lt;/td&gt;&lt;td&gt;65536&lt;/td&gt;&lt;td&gt;79183&lt;/td&gt;&lt;td&gt;69746&lt;/td&gt;&lt;td&gt;0.83&lt;/td&gt;&lt;td&gt;0.94&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;256K&lt;/td&gt;&lt;td&gt;262144&lt;/td&gt;&lt;td&gt;290035&lt;/td&gt;&lt;td&gt;271408&lt;/td&gt;&lt;td&gt;0.90&lt;/td&gt;&lt;td&gt;0.97&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1024K&lt;/td&gt;&lt;td&gt;1048576&lt;/td&gt;&lt;td&gt;1085366&lt;/td&gt;&lt;td&gt;1074076&lt;/td&gt;&lt;td&gt;0.97&lt;/td&gt;&lt;td&gt;0.98&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4096K&lt;/td&gt;&lt;td&gt;4194304&lt;/td&gt;&lt;td&gt;4381547&lt;/td&gt;&lt;td&gt;4286910&lt;/td&gt;&lt;td&gt;0.96&lt;/td&gt;&lt;td&gt;0.98&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This result indicates that NFS has a higher ratio in all groups. However, its advantage diminishes as the data request size grows. What it tells us is that if your applications workload issues most request in small chunks of data, such as 1K, 4K, then NFS will require much less traffic over the network, and thus less latency. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This essentially explains the use case of NFS against S3: workload with small data requests.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-client-support"&gt;Client Support&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;NFS is natively supported by Linux operating system kernel. NFS client sits below the virtual file system (VFS) layer, which sits below the system call layer. The NFS client translate system calls into RPC (remote procedure calls). Communication between client and server is completed with RPC, on top of TCP. &lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full"&gt;&lt;img loading="lazy" decoding="async" width="554" height="314" src="https://static.digihunch.com/wp-content/uploads/2021/10/image.png" alt="" class="wp-image-2732"/&gt;&lt;figcaption class="wp-element-caption"&gt;NFS architecture&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Because of the native support, in most cases, developer can treat NFS mounts as if they were local. For performance to be sustainable as file system grows, the directory structure on NFS should follow a certain naming conventions so that files are evenly distributed across directories. The client should also use list operation as sparse as it can because that operation is expensive across the network.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;From developer&amp;#8217;s perspective, NFS support is brought in by operating system and does not require much effort. On the other hand, S3 client support is not included by default in the operating system. S3 support requires special library, code changes, and integration effort to manage dependency and library version. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;NFS has an advantage on client supportability. However, as we move applications to containers, and as container storage options mature, we will need an intermediary layer (storage class, storage provisioner, CSI driver, etc), NFS, or in general file storage, does not have this advantage any more.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-client-side-cache"&gt;Client-side Cache&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The NFS support behind VFS layer also means it can leverage the I/O caching mechanism on the client side, that comes with operating system. Client operating system with sufficient memory can take advantage of this mechanism to give it a performance boost. Check out &lt;a href="https://www.ibm.com/docs/en/aix/7.2?topic=performance-nfs-tuning-client"&gt;this&lt;/a&gt; guide for NFS cache tuning.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In comparison, S3 does not have a cache mechanism by itself. Either the application needs to implement its own cache mechanism, or a cache architecture needs to be introduced, such as CloudFront. &lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-consistency-and-concurrency"&gt;Consistency and concurrency&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A common consistency problem is whether client can read the changes immediately after it writes the file. S3 and NFS make a tie in this round.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;S3 &lt;a href="https://aws.amazon.com/blogs/aws/amazon-s3-update-strong-read-after-write-consistency/"&gt;originally&lt;/a&gt; came with eventual consistency model for read after write since 2006. As of &lt;a href="https://aws.amazon.com/about-aws/whats-new/2020/12/amazon-s3-now-delivers-strong-read-after-write-consistency-automatically-for-all-applications/"&gt;Dec 2020&lt;/a&gt; it introduced strong read-after-write consistency. For more information, refer to the guide &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html#ConsistencyModel"&gt;here&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;NFS has a similar consistency guarantee called close-to-open cache coherency. Any changes made by client are flushed to the server on closing the file, and a cache revalidation occurs when you re-open it. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are more to consider in terms of consistency. For example, multiple clients tries to write the same file/object at the same time. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;On the S3 side, there is a locking mechanism called &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html"&gt;S3 object lock&lt;/a&gt; at object level (no byte-range lock). Without an object lock, when two PUT requests are simultaneously made to an object, the request with the latest timestamp wins. Refer to the section &lt;em&gt;Concurrent application&lt;/em&gt; on &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html#ConsistencyModel"&gt;this&lt;/a&gt; page.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;As far as NFS goes, managing this kind of consistency problem is not in the scope of the standard. Although there are some tinkers. For example, NFS v4 includes a file locking mechanism. Client can choose to lock the entire file, or a byte range within the file. Locking can be mandatory or advisory.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-the-convergence"&gt;The convergence&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;NFS and S3 each has their respective advantage. Enterprise NAS customers have been looking for ways to expand into the cloud for lower storage cost. To combine the advantages of the two, solution providers started to converge file storage and object storage. There are two types of solutions that reflects this trend of convergence. In the first trend, enterprise NAS deployed on premise now have the ability to scale out into the cloud. In the second trend, public cloud just brought enterprise NAS into their product offerings.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-scale-out-nas"&gt;Scale-out NAS&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;NAS is traditionally expensive to scale because it requires physical storage media. The idea of scale-out NAS allows NAS to connect to object storage in the public cloud, making it a hybrid architecture. This essentially makes T3 storage as a backend of T2 and it can be implemented with a virtual storage appliance (VSA). The VSA translate file system activities into API calls for object storage operations. One example is AWS &lt;a href="https://aws.amazon.com/storagegateway/?whats-new-cards.sort-by=item.additionalFields.postDateTime&amp;amp;whats-new-cards.sort-order=desc"&gt;storage gateway&lt;/a&gt;. EMC has a similar appliance called ECS and this white paper explains how it proxies file system calls and interact with object backends. NetApp, a vested enterprise NAS provider, also has a counterpart called Cloud Volumes ONTAP (CVO). It works well with NetApp on-premise deployment, but the architecture is similar. &lt;a href="https://cloud.netapp.com/blog/aws-cvo-blg-aws-storage-gateway-vs.-cloud-volumes-ontap"&gt;Here&lt;/a&gt;&amp;#8216;s NetApp&amp;#8217;s take on how CVO is different than AWS Storage Gateway.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the scale-out NAS architecture, the public cloud acts merely as extension to on-premise storage solution, to provide capacity. The NAS on premise serves the storage workload primarily.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-cloud-hosted-nas"&gt;Cloud hosted NAS&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For applications hosted in public cloud, it makes sense for public cloud provider to operate enterprise NAS storage as a service. The underlying storage technology is provided by storage vendor. It is just installed in the data centre managed by the public cloud vendor, instead of customer&amp;#8217;s own data centre. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;One example is &lt;a href="https://azure.microsoft.com/en-us/services/netapp/"&gt;Azure NetApp Files&lt;/a&gt; (ANF). ANF is fully managed services, presented to users as storage volumes. The underlying storage technology is NetApp ONTAP. Because it is offered as a fully managed service, the customers are not able to manage the fine details of the storage, as they could with an ONTAP cluster on premise. This takes a lot of flexibility away from the user.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;a href="https://aws.amazon.com/fsx/netapp-ontap/"&gt;FSx ONTAP&lt;/a&gt; is a managed NetApp storage service by AWS, launched in September 2021. The NetApp arrays are installed in AWS data centre, ready for users to provision from AWS console, or using CLI. The Terraform provider support is not available as of yet. Unlike ANF, FSx ONTAP exposes the ONTAP CLI to users, allowing for advanced storage managed by storage gurus. They can use ONTAP CLI commands to configure custom policy for Snapshot, setup SnapMirror replication, and so forth.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Likewise, PowerScale landed on GCP as public cloud partner to launch &lt;a href="https://cloud.google.com/vmware-engine/docs/vmware-ecosystem/howto-cloud-dell-powerscale#:~:text=Dell%20PowerScale%20on%20Google%20Cloud,workload%20virtual%20machines%20(VMs)."&gt;Dell Cloud PowerScale for Google Cloud&lt;/a&gt; in 2020. However, it seems to require a purchase agreement before APIs are enabled.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-conclusion"&gt;Conclusion&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Object storage has a great momentum and some sees that as a replacement of file storage in the long run. However file storage has its advantages for small data requests, OS-level cache support, and built-in POSIX compatibility. It will continue to be an option for customers with specific workload. Customer stickiness to file storage is so firm, that public cloud providers now install them in their data centres. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;From competition to collaboration, it will be interesting to watch what happens next for enterprise storage.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Follow-up Reading&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Tom Lyon&amp;#8217;s presentation on &lt;a href="https://blocksandfiles.com/2024/06/17/eminent-sun-alumnus-says-nfs-must-die/"&gt;why NFS must die&lt;/a&gt;.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2021/09/single-node-kubernetes-cluster-minikube/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Local multi-node cluster – Minikube, MicroK8s and KinD&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2021/10/intro-to-plg-stack-prometheus-loki-and-grafana/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Intro to PLG stack -Prometheus, Loki and Grafana&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>