mirror of https://github.com/k3s-io/k3s
Merge pull request #52469 from andyzhangx/azurefile-mount-windows
Automatic merge from submit-queue (batch tested with PRs 52469, 52574, 52330, 52689, 52829). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.. add feature: azurefile mount on windows node **What this PR does / why we need it**: feature: azurefile mount on windows node. I created this new PR, close the original one(https://github.com/kubernetes/kubernetes/pull/50233) as there is a big rebase change. Currently only SMB(a nfs protocol) is supported for windows container in the new Windows 2016 RS3 image, and windows container in RS3 could only use New-SmbGlobalMapping cmdlet for volume mapping, "net use" command does not work for windows container. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # **Special notes for your reviewer**: As there is a known blocking issue in Windows 2016 server when mounting a SMB(a NFS protocol in Windows) share on a container host and then bind that share to a container ( Azure file on Windows is using SMB protocol), this PR still could not mount an azure file on current windows 2016 server node, it depends on 2016 RS3 release, and it will still succeed (as a workaround) if customer want to mount an azure file on current windows node. Main code logic is similar to what it does in Linux node: 1. create target directory in Windows host 2. Use New-SmbGlobalMapping powershell cmdlet to mount SMB azure file to a drive in Windows host 3. Use mklink command to link target directory to the mounted drive K8s would bind target directory to the container directory source in mount function would be like: `\\[accountname].file.core.windows.net\test` target in mount function would be like: `c:\var\lib\kubelet\pods\5f679f75-7ce3-11e7-b718-000d3a31dac4\volumes\kubernetes.io~azure-file` sample azure file config file: ``` apiVersion: v1 kind: Pod metadata: name: iis spec: containers: - image: microsoft/iis name: iis volumeMounts: - name: azure mountPath: "d:" nodeSelector: beta.kubernetes.io/os: windows volumes: - name: azure azureFile: secretName: azure-secret shareName: k8stest readOnly: false ``` **Release note**: ```release-note ```pull/6/head
commit
17ba22aa85
|
@ -74,9 +74,29 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
|
|||
return nil
|
||||
}
|
||||
|
||||
// empty implementation for mounting azure file
|
||||
// currently only cifs mount is supported
|
||||
if strings.ToLower(fstype) != "cifs" {
|
||||
return fmt.Errorf("azureMount: only cifs mount is supported now, fstype: %q, mounting source (%q), target (%q), with options (%q)", fstype, source, target, options)
|
||||
}
|
||||
|
||||
cmdLine := fmt.Sprintf(`$User = "%s";$PWord = ConvertTo-SecureString -String "%s" -AsPlainText -Force;`+
|
||||
`$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord`,
|
||||
options[0], options[1])
|
||||
|
||||
driverLetter, err := getAvailableDriveLetter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bindSource = driverLetter + ":"
|
||||
cmdLine += fmt.Sprintf(";New-SmbGlobalMapping -LocalPath %s -RemotePath %s -Credential $Credential", bindSource, source)
|
||||
|
||||
if output, err := exec.Command("powershell", "/c", cmdLine).CombinedOutput(); err != nil {
|
||||
// we don't return error here, even though New-SmbGlobalMapping failed, we still make it successful,
|
||||
// will return error when Windows 2016 RS3 is ready on azure
|
||||
glog.Errorf("azureMount: SmbGlobalMapping failed: %v, only SMB mount is supported now, output: %q", err, string(output))
|
||||
return os.MkdirAll(target, 0755)
|
||||
}
|
||||
}
|
||||
|
||||
if output, err := exec.Command("cmd", "/c", "mklink", "/D", target, bindSource).CombinedOutput(); err != nil {
|
||||
glog.Errorf("mklink failed: %v, source(%q) target(%q) output: %q", err, bindSource, target, string(output))
|
||||
|
@ -178,6 +198,20 @@ func normalizeWindowsPath(path string) string {
|
|||
return normalizedPath
|
||||
}
|
||||
|
||||
func getAvailableDriveLetter() (string, error) {
|
||||
cmd := "$used = Get-PSDrive | Select-Object -Expand Name | Where-Object { $_.Length -eq 1 }"
|
||||
cmd += ";$drive = 67..90 | ForEach-Object { [string][char]$_ } | Where-Object { $used -notcontains $_ } | Select-Object -First 1;$drive"
|
||||
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getAvailableDriveLetter failed: %v, output: %q", err, string(output))
|
||||
}
|
||||
|
||||
if len(output) == 0 {
|
||||
return "", fmt.Errorf("azureMount: there is no available drive letter now")
|
||||
}
|
||||
return string(output)[:1], nil
|
||||
}
|
||||
|
||||
// ValidateDiskNumber : disk number should be a number in [0, 99]
|
||||
func ValidateDiskNumber(disk string) error {
|
||||
diskNum, err := strconv.Atoi(disk)
|
||||
|
|
|
@ -218,7 +218,7 @@ func (b *azureFileMounter) SetUpAt(dir string, fsGroup *int64) error {
|
|||
source = fmt.Sprintf("%s%s%s.file.%s%s%s", osSeparator, osSeparator, accountName, getStorageEndpointSuffix(b.plugin.host.GetCloudProvider()), osSeparator, b.shareName)
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
mountOptions = []string{accountName, accountKey}
|
||||
mountOptions = []string{fmt.Sprintf("AZURE\\%s", accountName), accountKey}
|
||||
} else {
|
||||
os.MkdirAll(dir, 0700)
|
||||
// parameters suggested by https://azure.microsoft.com/en-us/documentation/articles/storage-how-to-use-files-linux/
|
||||
|
|
Loading…
Reference in New Issue