Kubernetes指南
Linux性能优化实战eBPF 核心技术与实战SDN指南个人博客
中文
中文
  • 序言
  • 基础入门
    • Kubernetes 简介
    • Kubernetes 基本概念
    • Kubernetes 101
    • Kubernetes 201
    • Kubernetes 集群
  • 核心原理
    • 核心原理
    • 架构原理
    • 设计理念
    • 核心组件
      • etcd
      • kube-apiserver
      • kube-scheduler
      • kube-controller-manager
      • kubelet
      • kube-proxy
      • kube-dns
      • Federation
      • kubeadm
      • hyperkube
      • kubectl
    • 资源对象
      • Autoscaling
      • ConfigMap
      • CronJob
      • CustomResourceDefinition
      • DaemonSet
      • Deployment
      • Ingress
      • Job
      • LocalVolume
      • Namespace
      • NetworkPolicy
      • Node
      • PersistentVolume
      • Pod
      • PodPreset
      • ReplicaSet
      • Resource Quota
      • Secret
      • SecurityContext
      • Service
      • ServiceAccount
      • StatefulSet
      • Volume
  • 部署配置
    • 部署指南
    • kubectl 安装
    • 单机部署
    • 特性开关
    • 最佳配置
    • 版本支持
    • 集群部署
      • kubeadm
      • kops
      • Kubespray
      • Azure
      • Windows
      • LinuxKit
      • kubeasz
    • 附加组件
      • Addon-manager
      • DNS
      • Dashboard
      • 监控
      • 日志
      • Metrics
      • GPU
      • Cluster Autoscaler
      • ip-masq-agent
    • Kubernetes-The-Hard-Way
      • 准备部署环境
      • 安装必要工具
      • 创建计算资源
      • 配置创建证书
      • 配置生成配置
      • 配置生成密钥
      • 部署 Etcd 群集
      • 部署控制节点
      • 部署计算节点
      • 配置 Kubectl
      • 配置网络路由
      • 部署 DNS 扩展
      • 烟雾测试
      • 删除集群
  • 插件扩展
    • API 扩展
      • Aggregation
      • CustomResourceDefinition
    • 访问控制
      • 认证
      • RBAC 授权
      • 准入控制
    • Scheduler 扩展
    • 网络插件
      • CNI
      • Flannel
      • Calico
      • Weave
      • Cilium
      • OVN
      • Contiv
      • SR-IOV
      • Romana
      • OpenContrail
      • Kuryr
    • 运行时插件 CRI
      • CRI-tools
      • Frakti
    • 存储插件
      • 容器存储接口 CSI
      • FlexVolume
      • glusterfs
    • 网络策略
    • Ingress Controller
      • Ingress + Letsencrypt
      • minikube Ingress
      • Traefik Ingress
      • Keepalived-VIP
    • Cloud Provider 扩展
    • Device 插件
  • 服务治理
    • 服务治理
      • 一般准则
      • 滚动升级
      • Helm
      • Operator
      • Service Mesh
      • Linkerd
      • Linkerd2
    • Istio
      • 安装
      • 流量管理
      • 安全管理
      • 策略管理
      • 度量管理
      • 排错
      • 社区
    • Devops
      • Draft
      • Jenkins X
      • Spinnaker
      • Kompose
      • Skaffold
      • Argo
      • Flux GitOps
  • 实践案例
    • 实践概览
    • 资源控制
    • 集群高可用
    • 应用高可用
    • 调试
    • 端口映射
    • 端口转发
    • 用户管理
    • GPU
    • HugePage
    • 安全
    • 审计
    • 备份恢复
    • 证书轮换
    • 大规模集群
    • 大数据与机器学习
      • Spark
      • Tensorflow
    • Serverless
  • 排错指南
    • 排错概览
    • 集群排错
    • Pod 排错
    • 网络排错
    • PV 排错
      • AzureDisk
      • AzureFile
    • Windows 排错
    • 云平台排错
      • Azure
    • 排错工具
  • 社区贡献
    • 开发指南
    • 单元测试和集成测试
    • 社区贡献
  • 附录
    • 生态圈
    • 学习资源
    • 国内镜像
    • 如何贡献
    • 参考文档
由 GitBook 提供支持
在本页
  • AzureDisk 挂载失败
  • 挂载新的 AzureDisk 后,该 Node 中其他 Pod 已挂载的 AzureDisk 不可用
  • AzureDisk 挂载慢
  • Azure German Cloud 无法使用 AzureDisk
  • MountVolume.WaitForAttach failed
  • 在 mountOptions 中设置 uid 和 gid 时失败
  • 删除 pod 使用的 Azure 磁盘 PersistentVolumeClaim 时出错
  • 参考文档
  1. 排错指南
  2. PV 排错

AzureDisk

上一页PV 排错下一页AzureFile

最后更新于2年前

为 Azure 上面运行的虚拟机提供了弹性块存储服务,它以 VHD 的形式挂载到虚拟机中,并可以在 Kubernetes 容器中使用。AzureDisk 优点是性能高,特别是 Premium Storage 提供了非常好的;其缺点是不支持共享,只可以用在单个 Pod 内。

根据配置的不同,Kubernetes 支持的 AzureDisk 可以分为以下几类

  • Managed Disks: 由 Azure 自动管理磁盘和存储账户

  • Blob Disks:

    • Dedicated (默认):为每个 AzureDisk 创建单独的存储账户,当删除 PVC 的时候删除该存储账户

    • Shared:AzureDisk 共享 ResourceGroup 内的同一个存储账户,这时删除 PVC 不会删除该存储账户

注意:

  • AzureDisk 的类型必须跟 VM OS Disk 类型一致,即要么都是 Manged Disks,要么都是 Blob Disks。当两者不一致时,AzureDisk PV 会报无法挂载的错误。

  • 由于 Managed Disks 需要创建和管理存储账户,其创建过程会比 Blob Disks 慢(3 分钟 vs 1-2 分钟)。

  • 但节点最大支持同时挂载 16 个 AzureDisk。

使用 AzureDisk 推荐的版本:

Kubernetes version
Recommended version

1.12

1.12.9 或更高版本

1.13

1.13.6 或更高版本

1.14

1.14.2 或更高版本

>=1.15

>=1.15

使用 部署的 Kubernetes 集群,会自动创建两个 StorageClass,默认为managed-standard(即HDD):

kubectl get storageclass
NAME                PROVISIONER                AGE
default (default)   kubernetes.io/azure-disk   45d
managed-premium     kubernetes.io/azure-disk   53d
managed-standard    kubernetes.io/azure-disk   53d

AzureDisk 挂载失败

通过 kube-controller-manager 的日志,可以查看具体的错误原因。常见的错误日志为

Cannot attach data disk 'cdb-dynamic-pvc-92972088-11b9-11e8-888f-000d3a018174' to VM 'kn-edge-0' because the disk is currently being detached or the last detach operation failed. Please wait until the disk is completely detached and then try again or delete/detach the disk explicitly again.

临时性解决方法为

(1)更新所有受影响的虚拟机状态

使用powershell:

$vm = Get-AzureRMVM -ResourceGroupName $rg -Name $vmname
Update-AzureRmVM -ResourceGroupName $rg -VM $vm -verbose -debug

使用 Azure CLI:

# For VM:
az vm update -n <VM_NAME> -g <RESOURCE_GROUP_NAME>

# For VMSS:
az vmss update-instances -g <RESOURCE_GROUP_NAME> --name <VMSS_NAME> --instance-id <ID>

(2)重启虚拟机

  • kubectl cordon NODE

  • 如果 Node 上运行有 StatefulSet,需要手动删除相应的 Pod

  • kubectl drain NODE

  • Get-AzureRMVM -ResourceGroupName $rg -Name $vmname | Restart-AzureVM

  • kubectl uncordon NODE

挂载新的 AzureDisk 后,该 Node 中其他 Pod 已挂载的 AzureDisk 不可用

$ tree /dev/disk/azure
...
└── scsi1
    ├── lun0 -> ../../../sdk
    ├── lun1 -> ../../../sdj
    ├── lun2 -> ../../../sde
    ├── lun3 -> ../../../sdf
    ├── lun4 -> ../../../sdg
    ├── lun5 -> ../../../sdh
    └── lun6 -> ../../../sdi

这样,原来使用 lun0 磁盘的 Pod 就无法访问 AzureDisk 了

[root@admin-0 /]# ls /datadisk
ls: reading directory .: Input/output error

临时性解决方法是设置 AzureDisk StorageClass 的 cachingmode: None,如

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: managed-standard
provisioner: kubernetes.io/azure-disk
parameters:
  skuname: Standard_LRS
  kind: Managed
  cachingmode: None

AzureDisk 挂载慢

另外,如果 Node 使用了 Standard_B1s 类型的虚拟机,那么 AzureDisk 的第一次挂载一般会超时,等再次重复时才会挂载成功。这是因为在 Standard_B1s 虚拟机中格式化 AzureDisk 就需要很长时间(如超过 70 秒)。

$ kubectl describe pod <pod-name>
...
Events:
  FirstSeen     LastSeen        Count   From                                    SubObjectPath                           Type            Reason                  Message
  ---------     --------        -----   ----                                    -------------                           --------        ------                  -------
  8m            8m              1       default-scheduler                                                               Normal          Scheduled               Successfully assigned nginx-azuredisk to aks-nodepool1-15012548-0
  7m            7m              1       kubelet, aks-nodepool1-15012548-0                                               Normal          SuccessfulMountVolume   MountVolume.SetUp succeeded for volume "default-token-mrw8h"
  5m            5m              1       kubelet, aks-nodepool1-15012548-0                                               Warning         FailedMount             Unable to mount volumes for pod "nginx-azuredisk_default(4eb22bb2-0bb5-11e8-8
d9e-0a58ac1f0a2e)": timeout expired waiting for volumes to attach/mount for pod "default"/"nginx-azuredisk". list of unattached/unmounted volumes=[disk01]
  5m            5m              1       kubelet, aks-nodepool1-15012548-0                                               Warning         FailedSync              Error syncing pod
  4m            4m              1       kubelet, aks-nodepool1-15012548-0                                               Normal          SuccessfulMountVolume   MountVolume.SetUp succeeded for volume "pvc-20240841-0bb5-11e8-8d9e-0a58ac1f0
a2e"
  4m            4m              1       kubelet, aks-nodepool1-15012548-0       spec.containers{nginx-azuredisk}        Normal          Pulling                 pulling image "nginx"
  3m            3m              1       kubelet, aks-nodepool1-15012548-0       spec.containers{nginx-azuredisk}        Normal          Pulled                  Successfully pulled image "nginx"
  3m            3m              1       kubelet, aks-nodepool1-15012548-0       spec.containers{nginx-azuredisk}        Normal          Created                 Created container
  2m            2m              1       kubelet, aks-nodepool1-15012548-0       spec.containers{nginx-azuredisk}        Normal          Started                 Started container

Azure German Cloud 无法使用 AzureDisk

MountVolume.WaitForAttach failed

MountVolume.WaitForAttach failed for volume "pvc-f1562ecb-3e5f-11e8-ab6b-000d3af9f967" : azureDisk - Wait for attach expect device path as a lun number, instead got: /dev/disk/azure/scsi1/lun1 (strconv.Atoi: parsing "/dev/disk/azure/scsi1/lun1": invalid syntax)

在 mountOptions 中设置 uid 和 gid 时失败

默认情况下,Azure 磁盘使用 ext4、xfs filesystem 和 mountOptions,如 uid = x,gid = x 无法在装入时设置。 例如,如果你尝试设置 mountOptions uid = 999,gid = 999,将看到类似于以下内容的错误:

Warning  FailedMount             63s                  kubelet, aks-nodepool1-29460110-0  MountVolume.MountDevice failed for volume "pvc-d783d0e4-85a1-11e9-8a90-369885447933" : azureDisk - mountDevice:FormatAndMount failed with mount failed: exit status 32
Mounting command: systemd-run
Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/plugins/kubernetes.io/azure-disk/mounts/m436970985 --scope -- mount -t xfs -o dir_mode=0777,file_mode=0777,uid=1000,gid=1000,defaults /dev/disk/azure/scsi1/lun2 /var/lib/kubelet/plugins/kubernetes.io/azure-disk/mounts/m436970985
Output: Running scope as unit run-rb21966413ab449b3a242ae9b0fbc9398.scope.
mount: wrong fs type, bad option, bad superblock on /dev/sde,
       missing codepage or helper program, or other error

可以通过执行以下操作之一来缓解此问题

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 0
    fsGroup: 0

备注: 因为 gid 和 uid 默认装载为 root 或0。如果 gid 或 uid 设置为非根(例如1000),则 Kubernetes 将使用 chown 更改该磁盘下的所有目录和文件。此操作可能非常耗时,并且可能会导致装载磁盘的速度非常慢。

  • 使用 initContainers 中的 chown 设置 gid 和 uid。例如:

initContainers:
- name: volume-mount
  image: busybox
  command: ["sh", "-c", "chown -R 100:100 /data"]
  volumeMounts:
  - name: <your data volume>
    mountPath: /data

删除 pod 使用的 Azure 磁盘 PersistentVolumeClaim 时出错

如果尝试删除 pod 使用的 Azure 磁盘 PersistentVolumeClaim,可能会看到错误。例如:

$ kubectl describe pv pvc-d8eebc1d-74d3-11e8-902b-e22b71bb1c06
...
Message:         disk.DisksClient#Delete: Failure responding to request: StatusCode=409 -- Original Error: autorest/azure: Service returned an error. Status=409 Code="OperationNotAllowed" Message="Disk kubernetes-dynamic-pvc-d8eebc1d-74d3-11e8-902b-e22b71bb1c06 is attached to VM /subscriptions/{subs-id}/resourceGroups/MC_markito-aks-pvc_markito-aks-pvc_westus/providers/Microsoft.Compute/virtualMachines/aks-agentpool-25259074-0."

在 Kubernetes 版本1.10 及更高版本中,默认情况下已启用 PersistentVolumeClaim protection 功能以防止此错误。如果你使用的 Kubernetes 版本不能解决此问题,则可以通过在删除 PersistentVolumeClaim 前使用 PersistentVolumeClaim 删除 pod 来缓解此问题。

参考文档

在 AzureDisk 从一个 Pod 迁移到另一 Node 上面的 Pod 时或者同一台 Node 上面使用了多块 AzureDisk 时有可能会碰到这个问题。这是由于 kube-controller-manager 未对 AttachDisk 和 DetachDisk 操作加锁从而引发了竞争问题( )。

该问题的修复 已包含在 v1.10 中。

在 Kubernetes v1.7 中,AzureDisk 默认的缓存策略修改为 ReadWrite,这会导致在同一个 Node 中挂载超过 5 块 AzureDisk 时,已有 AzureDisk 的盘符会随机改变( )。比如,当挂载第六块 AzureDisk 后,原来 lun0 磁盘的挂载盘符有可能从 sdc 变成 sdk:

该问题的修复 将包含在 v1.10 中。

AzureDisk PVC 的挂载过程一般需要 1 分钟的时间,这些时间主要消耗在 Azure ARM API 的调用上(查询 VM 以及挂载 Disk)。 为 Azure VM 增加了一个缓存,消除了 VM 的查询时间,将整个挂载过程缩短到大约 30 秒。该修复包含在v1.9.2+ 和 v1.10 中。

Azure German Cloud 仅在 v1.7.9+、v1.8.3+ 以及更新版本中支持(),升级 Kubernetes 版本即可解决。

仅在 Kubernetes v1.10.0 和 v1.10.1 中存在,将在 v1.10.2 中修复。

通过在 fsGroup 中的 runAsUser 和 gid 中设置 uid 来。例如,以下设置会将 pod 设置为 root,使其可供任何文件访问:

AzureDisk
性能
aks-engine
kubernetes#60101
acs-engine#2002
ACS#12
#60183
kubernetes#60344
kubernetes#57444
AKS#201
acs-engine#1918
#60346
#57432
#50673
该问题
配置 pod 的安全上下文
Known kubernetes issues on Azure
Introduction of AzureDisk
AzureDisk volume examples
High-performance Premium Storage and managed disks for VMs