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 提供支持
在本页
  • Azure 负载均衡
  • LoadBalancer Service 一直处于 pending 状态
  • 负载均衡公网 IP 无法访问
  • 内网负载均衡 BackendPool 为空
  • 外网负载均衡均衡 BackendPool 为空
  • Service 删除后 Azure 公网 IP 未自动删除
  • MSI 无法使用
  • Azure ARM API 调用请求过多
  • AKS kubectl logs connection timed out
  • 使用 Virtual Kubelet 后 LoadBalancer Service 无法分配公网 IP
  • Node 的 GPU 数总是 0
  • Azure ServicePrincipal 过期
  • Node 自动重启
  • AKS Periscope
  • 已知问题及修复版本
  • 参考文档
  1. 排错指南
  2. 云平台排错

Azure

上一页云平台排错下一页排错工具

最后更新于2年前

Azure 负载均衡

使用 Azure Cloud Provider 后,Kubernetes 会为 LoadBalancer 类型的 Service 创建 Azure 负载均衡器以及相关的 公网 IP、BackendPool 和 Network Security Group (NSG)。注意目前 Azure Cloud Provider 仅支持 Basic SKU 的负载均衡,并将在 v1.11 中支持 Standard SKU。Basic 与 Standard SKU 负载均衡相比有一定的:

Load Balancer
Basic
Standard

Back-end pool size

up to 100

up to 1,000

Back-end pool boundary

Availability Set

virtual network, region

Back-end pool design

VMs in Availability Set, virtual machine scale set in Availability Set

Any VM instance in the virtual network

HA Ports

Not supported

Available

Diagnostics

Limited, public only

Available

VIP Availability

Not supported

Available

Fast IP Mobility

Not supported

Available

Availability Zones scenarios

Zonal only

Zonal, Zone-redundant, Cross-zone load-balancing

Outbound SNAT algorithm

On-demand

Preallocated

Outbound SNAT front-end selection

Not configurable, multiple candidates

Optional configuration to reduce candidates

Network Security Group

Optional on NIC/subnet

Required

同样,对应的 Public IP 也是 Basic SKU,与 Standard SKU 相比也有一定的:

Public IP
Basic
Standard

Availability Zones scenarios

Zonal only

Zone-redundant (default), zonal (optional)

Fast IP Mobility

Not supported

Available

VIP Availability

Not supported

Available

Counters

Not supported

Available

Network Security Group

Optional on NIC

Required

在 Kubernetes 中,负载均衡的创建逻辑都在 kube-controller-manager 中,因而排查负载均衡相关的问题时,除了查看 Service 自身的状态,如

kubectl describe service <service-name>

还需要查看 kube-controller-manager 是否有异常发生:

PODNAME=$(kubectl -n kube-system get pod -l component=kube-controller-manager -o jsonpath='{.items[0].metadata.name}')
kubectl -n kube-system logs $PODNAME --tail 100

LoadBalancer Service 一直处于 pending 状态

查看 Service kubectl describe service <service-name> 没有错误信息,但 EXTERNAL-IP 一直是 <pending>,说明 Azure Cloud Provider 在创建 LB/NSG/PublicIP 过程中出错。一般按照前面的步骤查看 kube-controller-manager 可以查到具体失败的原因,可能的因素包括

  • clientId、clientSecret、tenandId 或 subscriptionId 配置错误导致 Azure API 认证失败:更新所有节点的 /etc/kubernetes/azure.json ,修复错误的配置即可恢复服务

  • 配置的客户端无权管理 LB/NSG/PublicIP/VM:可以为使用的 clientId 增加授权或创建新的 az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/<subscriptionID>/resourceGroups/<resourceGroupName>"

  • Kuberentes v1.8.X 中还有可能出现 Security rule must specify SourceAddressPrefixes, SourceAddressPrefix, or SourceApplicationSecurityGroups 的错误,这是由于 Azure Go SDK 的问题导致的,可以通过升级集群到 v1.9.X/v1.10.X 或者将 SourceAddressPrefixes 替换为多条 SourceAddressPrefix 规则来解决

负载均衡公网 IP 无法访问

Azure Cloud Provider 会为负载均衡器创建探测器,只有探测正常的服务才可以响应用户的请求。负载均衡公网 IP 无法访问一般是探测失败导致的,可能原因有:

  • 后端 VM 本身不正常(可以重启 VM 恢复)

  • 后端容器未监听在设置的端口上(可通过配置正确的端口解决)

  • 防火墙或网络安全组阻止了要访问的端口(可通过增加安全规则解决)

  • 后端容器不响应(部分或者全部)外部请求时也会导致负载均衡 IP 无法访问。注意这里包含部分容器不响应的场景,这是由于 Azure 探测器与 Kubernetes 服务发现机制共同导致的结果:

    • (1)Azure 探测器定期去访问 service 的端口(即 NodeIP:NodePort)

    • (2)Kubernetes 将其负载均衡到后端容器中

    • (3)当负载均衡到异常容器时,访问失败会导致探测失败,进而 Azure 可能会将 VM 移出负载均衡

内网负载均衡 BackendPool 为空

外网负载均衡均衡 BackendPool 为空

在使用不支持 Cloud Provider 的工具(如 kubeadm)部署的集群中,如果未给 Kubelet 配置 --cloud-provider=azure --cloud-config=/etc/kubernetes/cloud-config,那么 Kubelet 会以 hostname 将其注册到集群中。此时,查看该 Node 的信息(kubectl get node -o yaml),可以发现其 externalID 与 hostname 相同。此时,kube-controller-manager 也无法将其加入到负载均衡的后端中。

一个简单的确认方式是查看 Node 的 externalID 和 name 是否不同:

$ kubectl get node -o jsonpath='{.items[*].metadata.name}'
k8s-agentpool1-27347916-0
$ kubectl get node -o jsonpath='{.items[*].spec.externalID}'
/subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.Compute/virtualMachines/k8s-agentpool1-27347916-0

该问题的解决方法是先删除 Node kubectl delete node <node-name>,为 Kubelet 配置 --cloud-provider=azure --cloud-config=/etc/kubernetes/cloud-config,最后再重启 Kubelet。

Service 删除后 Azure 公网 IP 未自动删除

MSI 无法使用

Azure ARM API 调用请求过多

有时 kube-controller-manager 或者 kubelet 会因请求调用过多而导致 Azure ARM API 失败的情况,比如

"OperationNotAllowed",\r\n    "message": "The server rejected the request because too many requests have been received for this subscription.

一般来说,如果该问题重复出现可以考虑

  • 使用 Azure instance metadata,即为所有 Node 的 /etc/kubernetes/azure.json 设置 "useInstanceMetadata": true 并重启 kubelet

  • 为 kube-controller-manager 增大 --route-reconciliation-period(默认为 10s),比如在 /etc/kubernetes/manifests/kube-controller-manager.yaml 中设置 --route-reconciliation-period=1m 后 kubelet 会自动重新创建 kube-controller-manager Pod。

AKS kubectl logs connection timed out

$ kubectl --v=8 logs x
I0308 10:32:21.539580   26486 round_trippers.go:417] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: kubectl/v1.8.1 (linux/amd64) kubernetes/f38e43b" -H "Authorization: Bearer x" https://x:443/api/v1/namespaces/default/pods/x/log?container=x
I0308 10:34:32.790295   26486 round_trippers.go:436] GET https://X:443/api/v1/namespaces/default/pods/x/log?container=x 500 Internal Server Error in 131250 milliseconds
I0308 10:34:32.790356   26486 round_trippers.go:442] Response Headers:
I0308 10:34:32.790376   26486 round_trippers.go:445]     Content-Type: application/json
I0308 10:34:32.790390   26486 round_trippers.go:445]     Content-Length: 275
I0308 10:34:32.790414   26486 round_trippers.go:445]     Date: Thu, 08 Mar 2018 09:34:32 GMT
I0308 10:34:32.790504   26486 request.go:836] Response Body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Get https://aks-nodepool1-53392281-1:10250/containerLogs/default/x: dial tcp 10.240.0.6:10250: getsockopt: connection timed out","code":500}
I0308 10:34:32.790999   26486 helpers.go:207] server response object: [{
  "metadata": {},
  "status": "Failure",
  "message": "Get https://aks-nodepool1-53392281-1:10250/containerLogs/default/x/x: dial tcp 10.240.0.6:10250: getsockopt: connection timed out",
  "code": 500
}]
F0308 10:34:32.791043   26486 helpers.go:120] Error from server: Get https://aks-nodepool1-53392281-1:10250/containerLogs/default/x/x: dial tcp 10.240.0.6:10250: getsockopt: connection timed out

在 AKS 中,kubectl logs, exec, and attach 等命令需要 Master 与 Nodes 节点之间建立隧道连接。在 kube-system namespace 中可以看到 tunnelfront 和 kube-svc-redirect Pod:

$ kubectl -n kube-system get po -l component=tunnel
NAME                           READY     STATUS    RESTARTS   AGE
tunnelfront-7644cd56b7-l5jmc   1/1       Running   0          2d

$ kubectl -n kube-system get po -l component=kube-svc-redirect
NAME                      READY     STATUS    RESTARTS   AGE
kube-svc-redirect-pq6kf   1/1       Running   0          2d
kube-svc-redirect-x6sq5   1/1       Running   0          2d
kube-svc-redirect-zjl7x   1/1       Running   1          2d

如果它们不是处于 Running 状态或者 Exec/Logs/PortForward 等命令报 net/http: TLS handshake timeout 错误,删除 tunnelfront Pod,稍等一会就会自动创建新的出来,如:

$ kubectl -n kube-system delete po -l component=tunnel
pod "tunnelfront-7644cd56b7-l5jmc" deleted

使用 Virtual Kubelet 后 LoadBalancer Service 无法分配公网 IP

使用 Virtual Kubelet 后,LoadBalancer Service 可能会一直处于 pending 状态,无法分配 IP 地址。查看该服务的事件(如 kubectl describe svc)会发现错误 CreatingLoadBalancerFailed 4m (x15 over 45m) service-controller Error creating load balancer (will retry): failed to ensure load balancer for service default/nginx: ensure(default/nginx): lb(kubernetes) - failed to ensure host in pool: "instance not found"。这是由于 Virtual Kubelet 创建的虚拟 Node 并不存在于 Azure 云平台中,因而无法将其加入到 Azure Load Balancer 的后端中。

解决方法是开启 ServiceNodeExclusion 特性,即设置 kube-controller-manager --feature-gates=ServiceNodeExclusion=true。开启后,所有带有 alpha.service-controller.kubernetes.io/exclude-balancer 标签的 Node 都不会加入到云平台负载均衡的后端中。

注意该特性仅适用于 Kubernetes 1.9 及以上版本。

Node 的 GPU 数总是 0

当在 AKS 集群中运行 GPU 负载时,发现它们无法调度,这可能是由于 Node 容量中的 nvidia.com/gpu 总是0。

解决方法是重新部署 nvidia-gpu 设备插件扩展:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  labels:
    kubernetes.io/cluster-service: "true"
  name: nvidia-device-plugin
  namespace: kube-system
spec:
  template:
    metadata:
      # Mark this pod as a critical add-on; when enabled, the critical add-on scheduler
      # reserves resources for critical add-on pods so that they can be rescheduled after
      # a failure.  This annotation works in tandem with the toleration below.
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ""
      labels:
        name: nvidia-device-plugin-ds
    spec:
      tolerations:
      # Allow this pod to be rescheduled while the node is in "critical add-ons only" mode.
      # This, along with the annotation above marks this pod as a critical add-on.
      - key: CriticalAddonsOnly
        operator: Exists
      containers:
      - image: nvidia/k8s-device-plugin:1.10
        name: nvidia-device-plugin-ctr
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
        volumeMounts:
          - name: device-plugin
            mountPath: /var/lib/kubelet/device-plugins
      volumes:
        - name: device-plugin
          hostPath:
            path: /var/lib/kubelet/device-plugins
      nodeSelector:
        beta.kubernetes.io/os: linux
        accelerator: nvidia

Azure ServicePrincipal 过期

默认情况下,Service Principal 的过期时间是 1 年,可以通过以下的命令延长过期时间:

az ad sp credential reset --name <clientId> --password <clientSecret> --years <newYears>

Node 自动重启

AKS Periscope

使用方法:

az extension add --name aks-preview
az aks kollect -g MyResourceGroup -n MyManagedCluster --storage-account MyStorageAccount --sas-token "MySasToken"

已知问题及修复版本

  1. 手动更新 VMSS VM 到最新时 Azure LoadBalancer 后端丢失问题

    • Basic LoadBalancer 修复版本: v1.14.7, v1.15.4, v1.16.0 及更高版本

    • Standard LoadBalancer 修复版本: v1.15.12, v1.16.9, v1.17.5, v1.18.1 及更高版本

  2. Service 未配置 DNS 标签导致公网 IP 上 DNS 标签丢失问题

    • 受影响版本:v1.17.0-v1.17.2, v1.16.0-v1.16.6, v1.15.7-v1.15.9, v1.14.10

    • 修复版本:v1.15.10, v1.16.7, v1.17.3, v1.18.0 及更高版本

  3. 路由表并发更新冲突问题

    • 修复版本:v1.15.11, v1.16.8, v1.17.4, v1.18.0 及更高版本

  4. VMSS VM 并发更新冲突问题

    • 修复版本:v1.15.11, v1.16.8, v1.17.4, v1.18.0 及更高版本

  5. VMSS 缓存不一致问题

    • 受影响版本:v1.15.8-v1.15.11, v1.16.5-v1.16.8, v1.17.1-v1.17.4

    • 修复版本:v1.15.12, v1.16.9, v1.17.5, v1.18.0 及更高版本

参考文档

在创建 Service 时,可以通过 metadata.annotation 来自定义 Azure 负载均衡的行为,可选的 Annotation 列表请参考 。

当使用内网负载均衡时,从同一个 ILB 的后端 VM 上访问 ILB VIP 时也会失败,这是 Azure 的(此时可以访问 service 的 clusterIP)

该问题的解决方法是使用,保证异常容器自动从服务的后端(endpoints)中删除。

Kubernetes 1.9.0-1.9.3 中会有这个问题( ),这是由于一个查找负载均衡所属 AvaibilitySet 的缺陷导致的。

该问题的修复( )将包含到 v1.9.4 和 v1.10 中。

Kubernetes 1.9.0-1.9.3 中会有这个问题():当创建超过 10 个 LoadBalancer Service 后有可能会碰到由于超过 FrontendIPConfiguations Quota(默认为 10)导致负载均衡无法创建的错误。此时虽然负载均衡无法创建,但公网 IP 已经创建成功了,由于 Cloud Provider 的缺陷导致删除 Service 后公网 IP 却未删除。

该问题的修复()将包含到 v1.9.4 和 v1.10 中。

另外,超过 FrontendIPConfiguations Quota 的问题可以参考 增加 Quota 来解决。

配置 "useManagedIdentityExtension": true 后,可以使用 来管理 Azure API 的认证授权。但由于 Cloud Provider 的缺陷( 未定义 useManagedIdentityExtension yaml 标签导致无法解析该选项。

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

特别是在 Kubernetes 集群创建或者批量增加 Nodes 的时候。从 开始, Azure cloud provider 为一些列的 Azure 资源(如 VM、VMSS、安全组和路由表等)增加了缓存,大大缓解了这个问题。

kubectl logs 命令报 getsockopt: connection timed out 的错误():

为了保护 AKS 群集,安全更新自动应用于所有的 Linux 节点。 这些更新包括 OS 安全修复项或内核更新,其中的部分更新需要重启节点才能完成。 AKS 不会自动重新启动这些 Linux 节点,但你可以参考配置 来自动重启节点。

除此之外,如果你还想收到节点需要重启的通知,可以参考 进行配置。

是一个用于排查 AKS 集群问题的调试工具,开源在 <github.com/Azure/aks-periscope>。

问题链接: 和

问题链接:

问题链接:

问题链接:

仅包含在 v1.18.0 或更高版本中的性能优化:

问题链接:

更多的 AKS 排错信息可以参考 。

局限
局限
Cloud Provider Azure 文档
预期行为
健康探针
kubernetes#59746
kubernetes#60060
acs-engine#2151
kubernetes#59747
kubernetes#59083
kubernetes#59255
kubernetes#59340
Azure subscription and service limits, quotas, and constraints
Managed Service Identity (MSI)
kubernetes #60691
kubernetes#60775
v1.9.2 和 v1.10
AKS#232
这里
kured
Dashboard and notifications on AKS for required worker nodes reboots
AKS Periscope
https://github.com/kubernetes/kubernetes/issues/80365
https://github.com/kubernetes/kubernetes/issues/89336
https://github.com/kubernetes/kubernetes/issues/87127
https://github.com/kubernetes/kubernetes/issues/88151
https://github.com/kubernetes/kubernetes/pull/88094
https://github.com/kubernetes/kubernetes/pull/88699
https://github.com/kubernetes/kubernetes/issues/89025
AKS 常见问题
AKS troubleshooting
Azure subscription and service limits, quotas, and constraints
Virtual Kubelet - Missing Load Balancer IP addresses for services
Troubleshoot Azure Load Balancer
Troubleshooting CustomScriptExtension (CSE) and acs-engine
Setting up azure firewall for analysing outgoing traffic in AKS
Dashboard and notifications on AKS for required worker nodes reboots