Skip to content

feat: support Azure DataLake account for blobfuse #488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/driver-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ storageAccount | specify Azure storage account name| STORAGE_ACCOUNT_NAME | - No
storeAccountKey | whether store account key to k8s secret | `true`,`false` | No | `true`
protocol | specify blobfuse mount or NFSv3 mount | `fuse`, `nfs` | No | `fuse`
containerName | specify the existing container name | existing container name | No | if empty, driver will create a new container name, starting with `pvc-fuse` for blobfuse or `pvc-nfs` for NFSv3
isHnsEnabled | enable `Hierarchical namespace` for Azure DataLake storage account(only for blobfuse) | `true`,`false` | No | `false`
server | specify Azure storage account server address | existing server address, e.g. `accountname.privatelink.blob.core.windows.net` | No | if empty, driver will use default `accountname.blob.core.windows.net` or other sovereign cloud account address
storageEndpointSuffix | specify Azure storage endpoint suffix | `core.windows.net` | No | if empty, driver will use default storage endpoint suffix according to cloud environment, e.g. `core.windows.net`
tags | [tags](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources) would be created in newly created storage account | tag format: 'foo=aaa,bar=bbb' | No | ""
Expand All @@ -23,6 +24,10 @@ tags | [tags](https://docs.microsoft.com/en-us/azure/azure-resource-manager/mana

Blobfuse driver does not honor `fsGroup` securityContext setting, instead user could use `-o gid=1000` in `mountoptions` to set ownership, check [here](https://github.com/Azure/Azure-storage-fuse#mount-options) for more mountoptions.

- Azure DataLake storage account support
- set `isHnsEnabled: "true"` in storage class parameter to create ADLS account by driver.
- mount option `--use-adls=true` must be specified to enable blobfuse access ADLS account.

- account tags format created by dynamic provisioning
```
created-by: azure
Expand Down
1 change: 1 addition & 0 deletions pkg/blob/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const (
secretNamespaceField = "secretnamespace"
containerNameField = "containername"
storeAccountKeyField = "storeaccountkey"
isHnsEnabledField = "ishnsenabled"
getAccountKeyFromSecretField = "getaccountkeyfromsecret"
keyVaultURLField = "keyvaulturl"
keyVaultSecretNameField = "keyvaultsecretname"
Expand Down
11 changes: 9 additions & 2 deletions pkg/blob/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
parameters = make(map[string]string)
}
var storageAccountType, resourceGroup, location, account, containerName, protocol, customTags, secretNamespace string
var isHnsEnabled *bool

// store account key to k8s secret by default
storeAccountKey := true
Expand All @@ -92,6 +93,10 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
customTags = v
case secretNamespaceField:
secretNamespace = v
case isHnsEnabledField:
if strings.EqualFold(v, trueValue) {
isHnsEnabled = to.BoolPtr(true)
}
case storeAccountKeyField:
if strings.EqualFold(v, falseValue) {
storeAccountKey = false
Expand Down Expand Up @@ -127,8 +132,10 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)

enableHTTPSTrafficOnly := true
accountKind := string(storage.KindStorageV2)
var vnetResourceIDs []string
var isHnsEnabled, enableNfsV3 *bool
var (
vnetResourceIDs []string
enableNfsV3 *bool
)
if protocol == nfs {
enableHTTPSTrafficOnly = false
isHnsEnabled = to.BoolPtr(true)
Expand Down
7 changes: 6 additions & 1 deletion pkg/blob/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe
secrets := req.GetSecrets()

var serverAddress, storageEndpointSuffix, protocol, ephemeralVolMountOptions string
var ephemeralVol bool
var ephemeralVol, isHnsEnabled bool
for k, v := range attrib {
switch strings.ToLower(k) {
case serverNameField:
Expand All @@ -224,6 +224,8 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe
ephemeralVol = strings.EqualFold(v, trueValue)
case mountOptionsField:
ephemeralVolMountOptions = v
case isHnsEnabledField:
isHnsEnabled = strings.EqualFold(v, trueValue)
}
}

Expand Down Expand Up @@ -271,6 +273,9 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe
if ephemeralVol {
mountOptions = util.JoinMountOptions(mountOptions, strings.Split(ephemeralVolMountOptions, ","))
}
if isHnsEnabled {
mountOptions = util.JoinMountOptions(mountOptions, []string{"--use-adls=true"})
}
// set different tmp-path with time info
tmpPath := fmt.Sprintf("%s/%s#%d", "/mnt", volumeID, time.Now().Unix())
mountOptions = appendDefaultMountOptions(mountOptions, tmpPath, containerName)
Expand Down
5 changes: 4 additions & 1 deletion test/e2e/dynamic_provisioning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ var _ = ginkgo.Describe("[blob-csi-e2e] Dynamic Provisioning", func() {
Cmd: []string{"cat", "/mnt/test-1/data"},
ExpectedString: "hello world\nhello world\n", // pod will be restarted so expect to see 2 instances of string
},
StorageClassParameters: map[string]string{"skuName": "Premium_LRS"},
StorageClassParameters: map[string]string{
"skuName": "Premium_LRS",
"isHnsEnabled": "true",
},
}
test.Run(cs, ns)
})
Expand Down