Azure 파일 공유를 탑재할 때 오류 발생
이 문서에서는 Azure 파일 공유의 탑재가 실패하는 오류에 대한 가능한 원인과 솔루션을 제공합니다.
증상
AKS(Azure Kubernetes Service) 환경에서 배포 또는 StatefulSet과 같은 Kubernetes 리소스를 배포합니다. 배포는 Azure 파일 공유를 참조하는 PVC(PersistentVolumeClaim)를 탑재하는 Pod를 만듭니다.
그러나 Pod는 ContainerCreating 상태를 유지합니다. 명령을 실행할 kubectl describe pods
때 명령 출력에 다음 오류 중 하나가 표시되어 탑재 작업이 실패할 수 있습니다.
예제로 다음 출력을 참조하세요.
MountVolume.MountDevice failed for volume "\<pv-fileshare-name>"
rpc error: code = Internal desc =
volume(\<storage-account's-resource-group>#\<storage-account-name>#\<pv/fileshare-name>#) > mount "//\<storage-account-name>.file.core.windows.net/\<pv-fileshare-name>" on "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/\<pv-fileshare-name>/globalmount" failed with
mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t cifs -o dir_mode=0777,file_mode=0777,uid=0,gid=0,mfsymlinks,cache=strict,actimeo=30,\<masked> //\<storage-account-name>.file.core.windows.net/\<pv-name> /var/lib/kubelet/plugins/kubernetes.io/csi/pv/\<pv-name>/globalmount
Output: mount error(\<error-id>): \<error-description>
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)
참고 항목
- 스토리지 계정에 공개적으로 액세스할 수 있는 경우 출력에 표시되는 호스트 이름은 storage-account-name.file.core.windows.net>.<
- 스토리지 계정이 프라이빗 링크, 엔드포인트 또는 DNS 영역으로 비공개로 구성된 경우 호스트 이름은 storage-account-name.privatelink.file.core.windows.net>.<
문제 해결 전
다음 예제와 같이 출력의 메시지에 따라 스토리지 계정 및 파일 공유를 식별합니다. 이 값은 이후 문제 해결 단계에서 사용됩니다.
mount "//<storage-account-name.file.core.windows.net/>< pv-fileshare-name>"
가능한 원인 및 솔루션은 다음 섹션을 참조하세요.
탑재 오류(2): 해당하는 파일이나 디렉터리가 없습니다.
이 오류는 AKS 클러스터와 스토리지 계정 간에 연결이 없음을 나타냅니다.
초기 문제 해결
Azure 파일은 SMB 프로토콜(포트 445)을 사용합니다. 포트 445 및/또는 스토리지 계정의 IP 주소가 차단되지 않았는지 확인합니다.
스토리지 계정의 IP 주소를 확인하려면 nslookup
, dig
또는 host
와 같은 DNS(Domain Name System) 명령을 실행합니다. 예시:
nslookup <storage-account-name>.file.core.windows.net
AKS 클러스터와 스토리지 계정 간에 연결이 있는지 확인하려면 node 또는 pod 내부로 들어가 다음 nc
또는 telnet
명령을 실행합니다.
nc -v -w 2 <storage-account-name>.file.core.windows.net 445
telnet <storage-account-name>.file.core.windows.net 445
탑재 오류의 가능한 원인(2)
- 원인 1: 파일 공유가 존재하지 않음
- 원인 2: NSG는 AKS와 스토리지 계정 간의 트래픽을 차단합니다.
- 원인 3: 가상 어플라이언스가 AKS와 스토리지 계정 간의 트래픽 차단
- 원인 4: FIPS 지원 노드 풀이 사용됨
참고 항목
- 원인 1, 2 및 4는 공용 및 프라이빗 스토리지 계정 시나리오에 적용됩니다.
- 원인 3은 공용 시나리오에만 적용됩니다.
원인 1: 파일 공유가 존재하지 않음
파일 공유가 있는지 확인하려면 다음 단계를 따릅니다.
Azure Portal에서 Storage 계정을 검색하고 스토리지 계정에 액세스합니다.
스토리지 계정의 데이터 스토리지에서 파일 공유를 선택하고 Pod, 배포 또는 상태 저장 집합의 yaml 파일에 연결된 PersistentVolumeClaim이 파일 공유에 있는지 확인합니다.
솔루션: 파일 공유가 있는지 확인
이 문제를 해결하려면 PV/PVC와 연결된 파일 공유가 있는지 확인합니다.
원인 2: 네트워크 보안 그룹이 AKS와 스토리지 계정 간의 트래픽 차단
초기 문제 해결 섹션에 nc
언급된 명령의 telnet
출력을 확인합니다 . 시간 제한이 표시되면 NSG(네트워크 보안 그룹)를 확인하고 스토리지 계정의 IP 주소가 차단되지 않았는지 확인합니다.
NSG가 스토리지 계정의 IP 주소를 차단하는지 확인하려면 다음 단계를 따릅니다.
Azure Portal에서 Network Watcher로 이동하여 NSG 진단을 선택합니다.
다음 값을 사용하여 필드를 채웁니다.
- 프로토콜: 모두
- 방향: 아웃바운드
- 원본 유형: IPv4 주소/CIDR
- IPv4 주소/CIDR: AKS 노드와 연결된 인스턴스의 IP 주소
- 대상 IP 주소: 스토리지 계정의 IP 주소
- 대상 포트: 445
확인 단추를 선택하고 트래픽 상태를 확인합니다.
트래픽 상태는 허용 또는 거부될 수 있습니다. 거부됨 상태는 NSG가 AKS 클러스터와 스토리지 계정 간의 트래픽을 차단하고 있음을 의미합니다. 상태가 거부되면 NSG 이름이 표시됩니다.
솔루션: AKS와 스토리지 계정 간의 연결 허용
이 문제를 해결하려면 포트 445에서 AKS 클러스터와 스토리지 계정 간의 연결을 허용하도록 NSG 수준에서 적절하게 변경을 수행합니다.
원인 3: 가상 어플라이언스가 AKS와 스토리지 계정 간의 트래픽 차단
가상 어플라이언스(일반적으로 방화벽)를 사용하여 AKS 클러스터의 아웃바운드 트래픽을 제어하는 경우(예: 가상 어플라이언스에는 AKS 클러스터의 서브넷에 적용된 경로 테이블이 있고 경로 테이블에는 트래픽을 가상 어플라이언스로 보내는 경로가 있음), 가상 어플라이언스는 AKS 클러스터와 스토리지 계정 간의 트래픽을 차단할 수 있습니다.
문제를 격리하려면 스토리지 계정의 IP 주소에 대한 경로 테이블에 경로를 추가하여 트래픽을 인터넷으로 보냅니다.
AKS 클러스터의 트래픽을 제어하는 경로 테이블을 확인하려면 다음 단계를 따릅니다.
- Azure Portal에서 AKS 클러스터로 이동하여 속성>인프라 리소스 그룹을 선택합니다.
- 이러한 VM 집합 형식을 사용하는 경우 VMSS(가상 머신 확장 집합) 또는 가용성 집합의 VM에 액세스합니다.
- 가상 네트워크/서브넷 서브넷>을 선택하고 AKS 클러스터의 서브넷을 식별합니다. 오른쪽에 경로 테이블이 표시됩니다.
경로 테이블에 경로를 추가하려면 경로 만들기의 단계를 따르고 다음 필드를 입력합니다.
- 주소 접두사: <storage-account's-public-IP>/32
- 다음 홉 유형:인터넷
이 경로는 공용 인터넷을 통해 AKS 클러스터와 스토리지 계정 간의 모든 트래픽을 보냅니다.
경로를 추가한 후 nc
또는 telnet
명령을 사용하여 연결을 테스트하고 탑재 작업을 다시 수행합니다.
솔루션: 가상 어플라이언스가 AKS와 스토리지 계정 간의 트래픽을 허용하는지 확인
탑재 작업이 성공하면 네트워킹 팀에 문의하여 가상 어플라이언스가 포트 445에서 AKS 클러스터와 스토리지 계정 간의 트래픽을 허용할 수 있는지 확인하는 것이 좋습니다.
원인 4: FIPS 지원 노드 풀이 사용됨
FIPS(Federal Information Processing Standard) 사용 노드 풀을 사용하는 경우 FIPS가 CIFS 공유의 탑재를 방지하는 일부 인증 모듈을 사용하지 않도록 설정하기 때문에 탑재 작업이 실패합니다. 이 동작은 예상되는 동작이며 AKS에만 국한되지 않습니다.
이 문제를 해결하려면 다음 솔루션 중 하나를 사용합니다.
솔루션 1: FIPS가 아닌 노드 풀의 노드에서 Pod 예약
FIPS는 AKS 노드 풀에서 기본적으로 사용하지 않도록 설정되며 --enable-fips-image
매개 변수를 사용하여 노드 풀을 만드는 동안에만 사용하도록 설정할 수 있습니다.
오류를 해결하기 위해 FIPS가 아닌 노드 풀의 노드에서 Pod를 예약할 수 있습니다.
솔루션 2: FIPS 지원 노드에서 예약할 수 있는 Pod 만들기
FIPS 지원 노드에서 예약할 수 있는 Pod를 만들려면 다음 단계를 따릅니다.
Azure File CSI 드라이버를 사용하여 NFS 프로토콜을 사용하는 사용자 지정 StorageClass를 만듭니다.
다음 YAML 파일을 예로 참조하세요.
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: azurefile-sc-fips provisioner: file.csi.azure.com reclaimPolicy: Delete volumeBindingMode: Immediate allowVolumeExpansion: true parameters: skuName: Premium_LRS protocol: nfs
프리미엄 SKU는 NFS에 필요하므로 SKU는 YAML 파일에서 Premium_LRS로 설정됩니다. 자세한 내용은 동적 프로비전을 참조하세요.
프리미엄 SKU로 인해 파일 공유의 최소 크기는 100GB입니다. 자세한 내용은 스토리지 클래스 만들기를 참조하세요.
사용자 지정 StorageClass azurefile-sc-fips를 참조하는 PVC를 만듭니다.
다음 YAML 파일을 예로 참조하세요.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: azurefile-pvc-fips spec: accessModes: - ReadWriteMany storageClassName: azurefile-sc-fips resources: requests: storage: 100Gi
PVC azurefile-pvc-fips를 탑재하는 Pod를 만듭니다.
다음 YAML 파일을 예로 참조하세요.
kind: Pod apiVersion: v1 metadata: name: azurefile-pod-fips spec: containers: - name: azurefile-pod-fips image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine resources: requests: cpu: 100m memory: 128Mi limits: cpu: 250m memory: 256Mi volumeMounts: - mountPath: "/mnt/azure" name: volume volumes: - name: volume persistentVolumeClaim: claimName: azurefile-pvc-fips
탑재 오류(13): 권한이 거부됨
이 오류의 가능한 원인은 다음과 같습니다.
- 원인 1: Kubernetes 비밀이 올바른 스토리지 계정 이름 또는 키를 참조하지 않음
- 원인 2: 스토리지 계정에 대해 AKS의 VNet 및 서브넷이 허용되지 않음
- 원인 3: 연결은 프라이빗 링크를 통해 수행되지만 노드와 프라이빗 엔드포인트는 서로 다른 VNET에 있습니다.
- 원인 4: 스토리지 계정이 클라이언트가 지원하지 않는 암호화를 요구하도록 설정됨
- 원인 5: 스토리지 계정에 대한 최소 암호화 요구 사항이 충족되지 않음
- 원인 6: NTLM v2 인증을 사용하지 않고 보안 프로필이 사용됩니다.
참고 항목
- 원인 1은 공용 및 프라이빗 시나리오에 적용됩니다.
- 원인 2는 공용 시나리오에만 적용됩니다.
- 원인 3은 프라이빗 시나리오에만 적용됩니다.
- 원인 4는 공용 및 프라이빗 시나리오에 적용됩니다.
- 원인 5는 퍼블릭 및 프라이빗 시나리오에 적용됩니다.
- 원인 6은 퍼블릭 및 프라이빗 시나리오에 적용됩니다.
원인 1: Kubernetes 비밀이 올바른 스토리지 계정 이름 또는 키를 참조하지 않음
파일 공유가 동적으로 만들어지면 Kubernetes 비밀 리소스는 "azure-storage-account-storage-account-name-secret<>"이라는 이름으로 자동으로 만들어집니다.
파일 공유가 수동으로 만들어진 경우 Kubernetes 비밀 리소스는 수동으로 만들어져야 합니다.
만들기 방법에 관계없이 Kubernetes 비밀에서 참조되는 스토리지 계정 이름 또는 키가 실제 값과 일치하지 않으면 "권한 거부됨" 오류와 함께 탑재 작업이 실패합니다.
불일치의 가능한 원인
Kubernetes 비밀을 수동으로 만드는 경우 만들기 중에 오타가 발생할 수 있습니다.
스토리지 계정 수준에서 "키 회전" 작업이 수행되면 변경 내용이 Kubernetes 비밀 수준에 반영되지 않습니다. 이로 인해 스토리지 계정 수준의 키 값과 Kubernetes 비밀 수준의 값이 일치하지 않습니다.
"키 회전" 작업이 발생하면 "스토리지 계정 키 다시 생성"이라는 이름의 작업이 스토리지 계정의 활동 로그에 표시됩니다. 활동 로그 보존 기간 90일에 유의합니다.
불일치 확인
불일치를 확인하려면 다음 단계를 따릅니다.
Azure Portal에서 스토리지 계정을 검색하고 액세스합니다. 선택 선택 스토리지>계정에 키를 표시 합니다. 스토리지 계정 이름과 연결된 키가 표시됩니다.
AKS 클러스터로 이동하여 구성>비밀을 선택한 다음, 연결된 비밀을 검색하고 액세스합니다.
표시(눈 아이콘)를 선택하고 스토리지 계정 이름 및 연결된 키의 값을 1단계의 값과 비교합니다.
표시를 선택하기 전에 스토리지 계정 이름 및 연결된 키의 값이 base64 문자열로 인코딩됩니다. 표시를 선택하면 값이 디코딩됩니다.
Azure Portal에서 AKS 클러스터에 대한 액세스 권한이 없는 경우 kubectl 수준에서 2단계를 수행합니다.
Kubernetes 비밀의 YAML 파일을 가져와서 다음 명령을 실행하여 출력에서 스토리지 계정 이름 및 키의 값을 가져옵니다.
kubectl get secret <secret-name> -n <secret-namespace> -o <yaml-file-name>
echo
명령을 사용하여 스토리지 계정 이름 및 키 값을 디코딩하고 스토리지 계정 수준의 값과 비교합니다.스토리지 계정 이름을 디코딩하는 예제는 다음과 같습니다.
echo -n '<storage account name>' | base64 --decode ;echo
솔루션: Kubernetes 비밀을 조정하고 Pod를 다시 만들기
Kubernetes 비밀의 스토리지 계정 이름 또는 키 값이 스토리지 계정의 액세스 키 값과 일치하지 않는 경우 다음 명령을 실행하여 Kubernetes 비밀 수준에서 Kubernetes 비밀을 조정합니다.
kubectl edit secret <secret-name> -n <secret-namespace>
Kubernetes 비밀 구성에 추가된 스토리지 계정 이름 또는 키의 값은 base64로 인코딩된 값이어야 합니다. 인코딩된 값을 가져오려면 echo
명령을 사용합니다.
스토리지 계정 이름을 인코딩하는 예는 다음과 같습니다.
echo -n '<storage account name>'| base64 | tr -d '\n' ; echo
자세한 내용은 kubectl을 사용하여 비밀 관리를 참조하세요.
Kubernetes 비밀 azure-storage-account-<storage-account-name>-secret
에 올바른 값이 있으면 Pod을 다시 작성합니다. 그렇지 않으면 해당 Pod는 더 이상 유효하지 않은 이전 값을 계속 사용합니다.
원인 2: AKS의 VNet 및 서브넷이 스토리지 계정에 허용되지 않음
스토리지 계정의 네트워크가 선택한 네트워크로 제한되지만 AKS 클러스터의 VNet 및 서브넷이 선택한 네트워크에 추가되지 않은 경우 "권한 거부됨" 오류와 함께 탑재 작업이 실패합니다.
솔루션: 스토리지 계정에 AKS의 VNet 및 서브넷 허용
다음 명령을 실행하여 잘못된 Pod를 호스팅하는 노드를 식별합니다.
kubectl get pod <pod-name> -n <namespace> -o wide
명령 출력에서 노드를 확인합니다.
Azure Portal에서 AKS 클러스터로 이동하여 속성>인프라 리소스 그룹을 선택하고 노드와 연결된 VMSS에 액세스한 다음 가상 네트워크/서브넷을 확인하여 VNET 및 서브넷을 식별합니다.
Azure Portal에서 스토리지 계정에 액세스합니다. 네트워킹을 선택합니다. 액세스 허용이 선택한 네트워크로 설정된 경우 AKS 클러스터의 VNET 및 서브넷이 추가되었는지 확인합니다.
AKS 클러스터의 VNET 및 서브넷이 추가되지 않은 경우 기존 가상 네트워크 추가를 선택합니다. 네트워크 추가 페이지에서 AKS 클러스터의 VNET 및 서브넷을 입력한 다음 저장 추가>를 선택합니다.
변경 내용이 적용되려면 몇 분 정도 걸릴 수 있습니다. VNET 및 서브넷이 추가된 후 Pod 상태가 ContainerCreating에서 실행 중으로 변경되는지 확인합니다.
원인 3: 연결은 프라이빗 링크를 통해 이루어지지만 노드와 프라이빗 엔드포인트는 서로 다른 VNET에 있음
AKS 클러스터 및 스토리지 계정이 프라이빗 링크를 통해 연결되면 승인된 프라이빗 엔드포인트 연결이 사용됩니다.
이 시나리오에서 프라이빗 엔드포인트와 AKS 노드가 동일한 VNET에 있으면 Azure 파일 공유를 탑재할 수 있습니다.
프라이빗 엔드포인트와 AKS 클러스터가 서로 다른 VNET에 있는 경우 "권한 거부" 오류와 함께 탑재 작업이 실패합니다.
솔루션: 프라이빗 DNS 영역에서 AKS 클러스터의 VNET용 가상 네트워크 링크 만들기
노드 안으로 들어가 FQDN(정규화된 도메인 이름)이 공용 또는 개인 IP 주소를 통해 확인되는지 확인합니다. 이렇게 하려면 다음 명령을 실행합니다.
nslookup <storage-account-name>.privatelink.file.core.windows.net
FQDN이 공용 IP 주소를 통해 확인되는 경우(다음 스크린샷 참조) 프라이빗 DNS 영역("privatelink.file.core.windows.net") 수준에서 AKS 클러스터의 VNET에 대한 가상 네트워크 링크를 만듭니다. 스토리지 계정 프라이빗 엔드포인트의 VNET에 대해 가상 네트워크 링크가 이미 자동으로 만들어져 있습니다.
가상 네트워크 링크를 만들려면 다음 단계를 따릅니다.
프라이빗 DNS 영역에 액세스하고 가상 네트워크 링크>추가를 선택합니다.
필드를 입력하고 가상 네트워크에 대한 AKS 클러스터의 VNET을 선택합니다. AKS 클러스터의 VNET을 식별하는 방법은 솔루션: 스토리지 계정에 대한 AKS의 VNet 및 서브넷 허용 섹션을 참조하세요.
확인을 선택합니다.
가상 네트워크 링크가 추가된 후 FQDN은 개인 IP 주소를 통해 확인되어야 하며 탑재 작업이 성공해야 합니다. 예제는 다음 스크린샷을 참조하세요.
원인 4: 스토리지 계정이 클라이언트가 지원하지 않는 암호화를 요구하도록 설정됨
Azure Files 보안 설정에는 스토리지 계정의 보안 및 암호화 설정을 제어하기 위한 다양한 옵션이 포함되어 있습니다. 허용되는 방법과 알고리즘을 제한하면 클라이언트가 연결하지 못할 수 있습니다.
1.25 이전의 AKS 버전은 Linux 5.4 커널을 사용하고 AES-128-CCM 및 AES-128-GCM 암호화 알고리즘만 지원하는 Ubuntu 18.04 LTS를 기반으로 합니다. 최대 보안 프로필 또는 AES-128-GCM을 사용하지 않도록 설정하는 사용자 지정 프로필은 공유 매핑 실패를 유발합니다.
AKS 버전 1.25 이상 버전은 Linux 5.15 커널을 사용하고 AES-256-GCM을 지원하는 Ubuntu 22.04를 기반으로 합니다.
솔루션: AES-128-GCM 암호화 알고리즘을 사용하도록 허용
최대 호환성 프로필 또는 AES-128-GCM을 사용하도록 설정하는 사용자 지정 프로필을 사용하여 AES-128-GCM 알고리즘을 사용하도록 설정합니다. 자세한 내용은 Azure Files 보안 설정을 참조하세요.
원인 5: 스토리지 계정에 대한 최소 암호화 요구 사항이 충족되지 않음
해결 방법: 모든 스토리지 계정에 AES-128-GCM 암호화 알고리즘 사용
파일 공유를 성공적으로 탑재하거나 액세스하려면 모든 스토리지 계정에 대해 AES-128-GCM 암호화 알고리즘을 사용하도록 설정해야 합니다.
AES-256-GCM 암호화만 사용하려면 다음을 수행합니다.
Linux
다음 스크립트를 사용하여 클라이언트가 AES-256-GCM을 지원하는지 확인하고 이 스크립트를 적용하는 경우에만 적용합니다.
cifsConfPath="/etc/modprobe.d/cifs.conf"
echo "$(date) before change ${cifsConfPath}:"
cat ${cifsConfPath}
# Check if 'require_gcm_256' is already present in the configuration file
if ! grep -q "require_gcm_256" "${cifsConfPath}"; then
# Load the CIFS module
modprobe cifs
# Set the parameter at runtime
echo 1 > /sys/module/cifs/parameters/require_gcm_256
# Persist the configuration
echo "options cifs require_gcm_256=1" >> "${cifsConfPath}"
echo "$(date) after changing ${cifsConfPath}:"
cat "${cifsConfPath}"
else
echo "require_gcm_256 is already set in ${cifsConfPath}"
fi
Kubernetes DaemonSet을 사용하여 모든 노드에서 AES-256을 적용할 수도 있습니다. 다음 예제를 참조하십시오.
Windows
Set-SmbClientConfiguration PowerShell 명령을 사용하여 SMB 클라이언트에서 사용하는 암호화 암호화와 사용자 확인 없이 기본 설정 암호화 유형을 지정합니다.
Set-SmbClientConfiguration -EncryptionCiphers "AES_256_GCM" -Confirm:$false
참고 항목
이 EncryptionCiphers
매개 변수는 x64 기반 시스템(KB5014665)용 Windows Server 버전 21H2용 2022-06 누적 업데이트 및 Windows 11 버전 22H2(KB5014668)에 대한 누적 업데이트부터 사용할 수 있습니다.
원인 6: NTLM v2 인증을 사용하지 않고 보안 프로필이 사용됩니다.
NTLM v2 인증 메커니즘을 사용하지 않고 최대 보안 프로필 또는 사용자 지정 보안 프로필을 사용하면 "탑재 오류(13): 사용 권한 거부" 오류와 함께 탑재 작업이 실패합니다.
해결 방법: NTLM v2 인증을 사용하도록 설정하거나 "최대 호환성" 프로필 사용
AKS에 제대로 탑재하려면 사용자 지정 보안 프로필에 대해 NTLM v2 인증 메커니즘을 사용하도록 설정하거나 최대 호환성 보안 프로필을 사용해야 합니다.
자세한 정보
다른 탑재 오류가 발생하는 경우 Linux에서 Azure Files 문제 해결을 참조하세요.
도움을 요청하십시오.
질문이 있거나 도움이 필요한 경우 지원 요청을 생성하거나Azure 커뮤니티 지원에 문의하세요. Azure 피드백 커뮤니티에 제품 피드백을 제출할 수도 있습니다.