Longhorn 云原生容器分布式存储 - 故障排除指南

613 阅读22分钟

内容来源于官方 Longhorn 1.1.2 英文技术手册。

系列

目录

  1. Longhorn 卷文件系统损坏时,Pod 卡在 creating 状态
  2. 非标准 Kubelet 目录
  3. Longhorn 默认设置不保留
  4. 分离和附加卷后,Recurring job 不会创建新 job
  5. 使用 Traefik 2.x 作为 ingress controller
  6. 使用 cURL 创建 Support Bundle
  7. Longhorn RWX 共享挂载所有权在 consumer Pod 中显示为 nobody
  8. 由于节点上的多路径,MountVolume.SetUp for volume 失败
  9. Longhorn-UI:WebSocket 握手期间出错:意外响应代码:200 #2265
  10. Longhorn 卷需要很长时间才能完成安装
  11. volume readonly or I/O error
  12. volume pvc-xxx not scheduled

1. 当 Longhorn 卷文件系统损坏时,Pod 卡在 creating 状态

适用版本

所有 Longhorn 版本。

症状

Pod 停留在容器 Creating 中,日志中有错误。

Warning  FailedMount             30s (x7 over 63s)  kubelet                  MountVolume.SetUp failed for volume "pvc-bb8582d5-eaa4-479a-b4bf-328d1ef1785d" : rpc error: code = Internal desc = 'fsck' found errors on device /dev/longhorn/pvc-bb8582d5-eaa4-479a-b4bf-328d1ef1785d but could not correct them: fsck from util-linux 2.31.1
ext2fs_check_if_mount: Can't check if filesystem is mounted due to missing mtab file while determining whether /dev/longhorn/pvc-bb8582d5-eaa4-479a-b4bf-328d1ef1785d is mounted.
/dev/longhorn/pvc-bb8582d5-eaa4-479a-b4bf-328d1ef1785d contains a file system with errors, check forced.
/dev/longhorn/pvc-bb8582d5-eaa4-479a-b4bf-328d1ef1785d: Inodes that were part of a corrupted orphan linked list found.  

/dev/longhorn/pvc-bb8582d5-eaa4-479a-b4bf-328d1ef1785d: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
  (i.e., without -a or -p options)

原因

Longhorn 卷的文件系统损坏时,Longhorn 无法重新挂载该卷。 因此,workload 无法重新启动。

Longhorn 无法自动修复此问题。发生这种情况时,您需要手动解决此问题。

解决方案

  1. 寻找迹象:
    • Longhorn UI 检查卷是否处于 error 状态。
    • 检查 Longhorn 管理器 pod 日志以了解系统损坏错误消息。

    如果卷未处于 error 状态,则 Longhorn 卷内的文件系统可能因外部原因而损坏。

  2. 缩减 workload
  3. UI 将卷附加到任何一个 node
  4. SSH 进入 node
  5. /dev/longhorn/ 下找到 Longhorn 卷对应的块设备。
  6. 运行 fsck 来修复文件系统。
  7. UI 分离卷。
  8. 扩大 workload

2. 非标准 Kubelet 目录

适用版本

所有 Longhorn 版本。

症状

Kubernetes 集群使用非标准的 Kubelet 目录时,longhorn-csi-plugin 无法启动。

ip-172-30-0-73:/home/ec2-user # kubectl -n longhorn-system get pod
NAME                                        READY   STATUS              RESTARTS   AGE
longhorn-ui-5b864949c4-4sgws                1/1     Running             0          7m35s
longhorn-manager-tx469                      1/1     Running             0          7m35s
longhorn-driver-deployer-5444f75b8f-kgq5v   1/1     Running             0          7m35s
longhorn-csi-plugin-s4fg7                   0/2     ContainerCreating   0          6m59s
instance-manager-r-d185a1e9                 1/1     Running             0          7m10s
instance-manager-e-b5e69e2d                 1/1     Running             0          7m10s
csi-attacher-7d975797bc-qpfrv               1/1     Running             0          7m
csi-snapshotter-7dbfc7ddc6-nqqtg            1/1     Running             0          6m59s
csi-attacher-7d975797bc-td6tw               1/1     Running             0          7m
csi-resizer-868d779475-v6jvv                1/1     Running             0          7m
csi-resizer-868d779475-2bbs2                1/1     Running             0          7m
csi-provisioner-5c6845945f-46qnb            1/1     Running             0          7m
csi-resizer-868d779475-n5vjn                1/1     Running             0          7m
csi-provisioner-5c6845945f-fjnrq            1/1     Running             0          7m
csi-snapshotter-7dbfc7ddc6-mhfpl            1/1     Running             0          6m59s
csi-provisioner-5c6845945f-4lx5c            1/1     Running             0          7m
csi-attacher-7d975797bc-flldq               1/1     Running             0          7m
csi-snapshotter-7dbfc7ddc6-cms2v            1/1     Running             0          6m59s
engine-image-ei-611d1496-dlqcs              1/1     Running             0          7m10s

原因

由于 Longhorn 无法检测到 Kubelet 的根目录设置在哪里。

解决方案

Longhorn 通过 longhorn.yaml 安装:

取消注释并编辑:

#- name: KUBELET_ROOT_DIR
#  value: /var/lib/rancher/k3s/agent/kubelet

Longhorn 通过 Rancher - App 安装:

点击 Customize Default Settings 设置 Kubelet 根目录

相关信息

3. Longhorn 默认设置不保留

适用版本

所有 Longhorn 版本。

症状

  • 通过 helmRancher App 升级 Longhorn 系统时,修改后的 Longhorn 默认设置不会保留。
  • 通过 kubectl -n longhorn-system edit configmap longhorn-default-setting 修改默认设置时,修改不会应用于 Longhorn 系统。

背景

此默认设置仅适用于尚未部署的 Longhorn 系统。 它对现有的 Longhorn 系统没有影响。

解决方案

我们建议使用 Longhorn UI 更改现有集群上的 Longhorn 设置。

您也可以使用 kubectl,但请注意这将绕过 Longhorn 后端验证。

kubectl edit settings <SETTING-NAME> -n longhorn-system

4. 分离和附加卷后,Recurring job 不会创建新 job

适用版本

所有 Longhorn 版本。

症状

当卷被分离很长时间后被附加时,循环作业不会创建新 job。

根据 Kubernetes CronJob 限制:

对于每个 CronJobCronJob 控制器会检查它在从上次调度时间到现在的持续时间内错过了多少个 schedule。 如果有超过 100 个错过的 schedule,则它不会启动 job 并记录 error

Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.

这意味着 recurring job 可以容忍的附加/分离操作的持续时间取决于调度的间隔(scheduled interval)。

例如,如果 recurring backup job 设置为每分钟运行一次,则容限为 100 分钟。

解决方案

直接删除卡住的 cronjob,让 Longhorn 重新创建。

ip-172-30-0-211:/home/ec2-user # kubectl -n longhorn-system get cronjobs
NAME                                                  SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
pvc-394e6006-9c34-47da-bf27-2286ae669be1-c-ptl8l1-c   * * * * *   False     1        47s             2m23s

ip-172-30-0-211:/home/ec2-user # kubectl -n longhorn-system delete cronjobs/pvc-394e6006-9c34-47da-bf27-2286ae669be1-c-ptl8l1-c
cronjob.batch "pvc-394e6006-9c34-47da-bf27-2286ae669be1-c-ptl8l1-c" deleted

ip-172-30-0-211:/home/ec2-user # kubectl -n longhorn-system get cronjobs
No resources found in longhorn-system namespace.

ip-172-30-0-211:/home/ec2-user # sleep 60

ip-172-30-0-211:/home/ec2-user # kubectl -n longhorn-system get cronjobs
NAME                                                  SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
pvc-394e6006-9c34-47da-bf27-2286ae669be1-c-ptl8l1-c   * * * * *   False     1        2s             3m21s

相关信息

5. 使用 Traefik 2.x 作为 ingress controller

适用版本

所有 Longhorn 版本。

症状

Longhorn GUI 前端 API 请求有时无法到达 longhorn-manager 后端。

原因

API 请求会改变 HTTPS/WSS 之间的协议,而这种改变会导致 CORS 问题。

解决方案

Traefik 2.x ingress controller 没有设置 WebSocket header。

  1. 将以下中间件添加到 Longhorn 前端 service 的路由中。
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: svc-longhorn-headers
  namespace: longhorn-system
spec:
  headers:
    customRequestHeaders:
      X-Forwarded-Proto: "https"
  1. 更新 ingress 以使用中间件规则。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: longhorn-ingress
  namespace: longhorn-system
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"       
    traefik.ingress.kubernetes.io/router.middlewares: longhorn-system-svc-longhorn-headers@kubernetescrd
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: longhorn-frontend
          servicePort: 80

相关信息

6. 使用 cURL 创建 Support Bundle

适用版本

所有 Longhorn 版本。

症状

无法使用 Web 浏览器创建 support bundle

解决方案

  1. 暴露 Longhorn 后端服务。下面是一个使用 NodePort 的示例,如果设置了负载均衡器,您也可以通过负载均衡器暴露。
ip-172-30-0-21:~ # kubectl -n longhorn-system     patch svc longhorn-backend -p '{"spec":    {"type":"NodePort"}}'
service/longhorn-backend patched
ip-172-30-0-21:~ # kubectl -n longhorn-system get     svc/longhorn-backend
NAME               TYPE       CLUSTER-IP          EXTERNAL-IP   PORT(S)          AGE
longhorn-backend   NodePort   10.43.136.157       <none>        9500:32595/TCP   156m
  1. 运行以下脚本以创建和下载 support bundle。您需要替换 BACKEND_URLISSUE_URLISSUE_DESCRIPTION
# Replace this block ====>
BACKEND_URL="18.141.237.97:32595"

ISSUE_URL="https://github.com/longhorn/longhorn/issues/dummy"
ISSUE_DESCRIPTION="dummy description"
# <==== Replace this block

# Request to create the support bundle
REQUEST_SUPPORT_BUNDLE=$( curl -sSX POST -H 'Content-Type: application/json' -d '{ "issueURL": "'"${ISSUE_URL}"'", "description": "'"${ISSUE_DESCRIPTION}"'" }' http://${BACKEND_URL}/v1/supportbundles )

ID=$( jq -r '.id' <<< ${REQUEST_SUPPORT_BUNDLE} )
SUPPORT_BUNDLE_NAME=$( jq -r '.name' <<< ${REQUEST_SUPPORT_BUNDLE} )
echo "Creating support bundle ${SUPPORT_BUNDLE_NAME} on Node ${ID}"

while [ $(curl -sSX GET http://${BACKEND_URL}/v1/supportbundles/${ID}/${SUPPORT_BUNDLE_NAME} | jq -r '.state' ) != "ReadyForDownload" ]; do
  echo "Progress: $(curl -sSX GET http://${BACKEND_URL}/v1/supportbundles/${ID}/${SUPPORT_BUNDLE_NAME} | jq -r '.progressPercentage' )%"
  sleep 1s
done

curl -i -X GET http://${BACKEND_URL}/v1/supportbundles/${ID}/${SUPPORT_BUNDLE_NAME}/download --output /tmp/${SUPPORT_BUNDLE_NAME}.zip
echo "Downloaded support bundle to /tmp/${SUPPORT_BUNDLE_NAME}.zip"

相关信息

7. Longhorn RWX 共享挂载所有权在 consumer Pod 中显示为 nobody

适用版本

Longhorn 版本 = v1.1.0

症状

Pod 使用 RWX 卷挂载时,Pod 共享挂载目录及其 recurring contents 的所有 ownership 显示为 nobody,但在 share-manager 中显示为 root

root@ip-172-30-0-139:/home/ubuntu# kubectl exec -it rwx-test-2pml2 -- ls -l /data
total 16
drwx------ 2 nobody 42949672 16384 Mar 31 04:16 lost+found

root@ip-172-30-0-139:~# kubectl -n longhorn-system exec -it share-manager-pvc-f3775852-1e27-423f-96ab-95ccd04e4777 -- ls -l /export/pvc-f3775852-1e27-423f-96ab-95ccd04e4777
total 16
drwx------ 2 root root 16384 Mar 31 04:42 lost+found

背景

share-manager 中的 nfs-ganesha 使用 idmapd 进行 NFSv4 ID 映射,并设置为使用 localdomain 作为其导出域。

原因

client(host)server(share-manager) 之间 /etc/idmapd.conf 中的内容不匹配导致 ownership 更改。

让我们看一个例子:

我们假设您没有修改集群主机上的 /etc/idmapd.conf。对于某些操作系统,Domain = localdomain 被注释掉,默认情况下它使用 FQDN 减去 hostname

当主机名为 ip-172-30-0-139FQDNip-172-30-0-139.lan 时,主机 idmapd 将使用 lan 作为 Domain

root@ip-172-30-0-139:/home/ubuntu# hostname
ip-172-30-0-139

root@ip-172-30-0-139:/home/ubuntu# hostname -f
ip-172-30-0-139.lan

这导致 share-manager(localdomain) 和集群主机(lan)之间的域不匹配。 因此触发文件权限更改为使用 nobody

[Mapping] section variables

Nobody-User
Local user name to be used when a mapping cannot be completed.
Nobody-Group
Local group name to be used when a mapping cannot be completed.

解决方案

  1. 在所有群集主机上的 /etc/idmapd.conf 中取消注释或添加 Domain = localdomain
root@ip-172-30-0-139:~# cat /etc/idmapd.conf 
[General]

Verbosity = 0
Pipefs-Directory = /run/rpc_pipefs
# set your own domain here, if it differs from FQDN minus hostname
Domain = localdomain

[Mapping]

Nobody-User = nobody
Nobody-Group = nogroup
  1. 删除并重新创建 RWX 资源堆栈(pvc + pod)。
root@ip-172-30-0-139:/home/ubuntu# kubectl exec -it volume-test -- ls -l /data
total 16
drwx------    2 root     root         16384 Mar 31 04:42 lost+found

相关信息

8. 由于节点上的多路径,MountVolume.SetUp for volume 失败

适用版本

所有 Longhorn 版本。

症状

带有卷的 pod 未启动并在 longhorn-csi-plugin 中遇到错误消息:

time="2020-04-16T08:49:27Z" level=info msg="GRPC request: {\"target_path\":\"/var/lib/kubelet/pods/cf0a0b5b-106e-4793-a74a-28bfae21be1a/volumes/kubernetes.io~csi/pvc-d061512e-870a-4ece-bd45-2f04672d5256/mount\",\"volume_capability\":{\"AccessType\":{\"Mount\":{\"fs_type\":\"ext4\"}},\"access_mode\":{\"mode\":1}},\"volume_context\":{\"baseImage\":\"\",\"fromBackup\":\"\",\"numberOfReplicas\":\"3\",\"staleReplicaTimeout\":\"30\",\"storage.kubernetes.io/csiProvisionerIdentity\":\"1586958032802-8081-driver.longhorn.io\"},\"volume_id\":\"pvc-d061512e-870a-4ece-bd45-2f04672d5256\"}"
time="2020-04-16T08:49:27Z" level=info msg="NodeServer NodePublishVolume req: volume_id:\"pvc-d061512e-870a-4ece-bd45-2f04672d5256\" target_path:\"/var/lib/kubelet/pods/cf0a0b5b-106e-4793-a74a-28bfae21be1a/volumes/kubernetes.io~csi/pvc-d061512e-870a-4ece-bd45-2f04672d5256/mount\" volume_capability:<mount:<fs_type:\"ext4\" > access_mode:<mode:SINGLE_NODE_WRITER > > volume_context:<key:\"baseImage\" value:\"\" > volume_context:<key:\"fromBackup\" value:\"\" > volume_context:<key:\"numberOfReplicas\" value:\"3\" > volume_context:<key:\"staleReplicaTimeout\" value:\"30\" > volume_context:<key:\"storage.kubernetes.io/csiProvisionerIdentity\" value:\"1586958032802-8081-driver.longhorn.io\" > "
E0416 08:49:27.567704 1 mount_linux.go:143] Mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t ext4 -o defaults /dev/longhorn/pvc-d061512e-870a-4ece-bd45-2f04672d5256 /var/lib/kubelet/pods/cf0a0b5b-106e-4793-a74a-28bfae21be1a/volumes/kubernetes.io~csi/pvc-d061512e-870a-4ece-bd45-2f04672d5256/mount
Output: mount: /var/lib/kubelet/pods/cf0a0b5b-106e-4793-a74a-28bfae21be1a/volumes/kubernetes.io~csi/pvc-d061512e-870a-4ece-bd45-2f04672d5256/mount: /dev/longhorn/pvc-d061512e-870a-4ece-bd45-2f04672d5256 already mounted or mount point busy.
E0416 08:49:27.576477 1 mount_linux.go:487] format of disk "/dev/longhorn/pvc-d061512e-870a-4ece-bd45-2f04672d5256" failed: type:("ext4") target:("/var/lib/kubelet/pods/cf0a0b5b-106e-4793-a74a-28bfae21be1a/volumes/kubernetes.io~csi/pvc-d061512e-870a-4ece-bd45-2f04672d5256/mount") options:(["defaults"])error:(exit status 1)
time="2020-04-16T08:49:27Z" level=error msg="GRPC error: rpc error: code = Internal desc = exit status 1"

详情

这是由于多路径为任何符合条件的设备路径创建了多路径设备,包括未明确列入黑名单的每个 Longhorn 卷设备。

故障排除

  1. 查找 Longhorn 设备的 major:minor 编号。在节点上,尝试 ls -l /dev/longhorn/major:minor 编号将显示在设备名称前,例如 832
ls -l /dev/longhorn
brw-rw---- 1 root root 8, 32 Aug 10 21:50 pvc-39c0db31-628d-41d0-b05a-4568ec02e487
  1. 查找 Linux 为相同的 major:minor 编号生成的设备是什么。 使用 ls -l /dev 并找到相同 major:minor 编号的设备,例如 /dev/sde
brw-rw---- 1 root disk      8,  32 Aug 10 21:50 sdc
  1. 找到进程。使用 lsof 获取正在使用的文件处理程序列表,然后使用 grep 获取设备名称(例如 sde/dev/longhorn/xxx。您应该在那里找到一个。
lsof | grep sdc
multipath 514292                              root    8r      BLK               8,32        0t0        534 /dev/sdc
multipath 514292 514297 multipath             root    8r      BLK               8,32        0t0        534 /dev/sdc
multipath 514292 514299 multipath             root    8r      BLK               8,32        0t0        534 /dev/sdc
multipath 514292 514300 multipath             root    8r      BLK               8,32        0t0        534 /dev/sdc
multipath 514292 514301 multipath             root    8r      BLK               8,32        0t0        534 /dev/sdc
multipath 514292 514302 multipath             root    8r      BLK               8,32        0t0        534 /dev/sdc
multipath 514292 514304 multipath             root    8r      BLK               8,32        0t0        534 /dev/sdc

解决方案

按照以下步骤防止多路径守护进程(multipath daemon)添加由 Longhorn 创建的额外块设备。

首先使用 lsblk 检查 Longhorn 创建的设备:

root@localhost:~# lsblk
NAME MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda    8:0    0 79.5G  0 disk /
sdb    8:16   0  512M  0 disk [SWAP]
sdc    8:32   0    1G  0 disk /var/lib/kubelet/pods/c2c2b848-1f40-4727-8a52-03a74f9c76b9/volumes/kubernetes.io~csi/pvc-859bc3c9-faa8-4f54-85e4-b12935b5ae3c/mount
sdd    8:48   0    1G  0 disk /var/lib/kubelet/pods/063a181a-66ac-4644-8268-9215305f9b73/volumes/kubernetes.io~csi/pvc-837eb6ac-45fe-4de7-9c97-8d371eb02190/mount
sde    8:64   0    1G  0 disk /var/lib/kubelet/pods/4c80842d-7257-4b91-b668-bb5b111da003/volumes/kubernetes.io~csi/pvc-c01cee3e-f292-4979-b183-6546d6397fbd/mount
sdf    8:80   0    1G  0 disk /var/lib/kubelet/pods/052dadd9-042a-451c-9bb1-2d9418f0381f/volumes/kubernetes.io~csi/pvc-ba7a5c9a-d84d-4cb0-959d-3db39f34d81b/mount
sdg    8:96   0    1G  0 disk /var/lib/kubelet/pods/7399b073-c262-4963-8c7f-9e481272ea36/volumes/kubernetes.io~csi/pvc-2b122b42-141a-4181-b8fd-ce3cf91f6a64/mount
sdh    8:112  0    1G  0 disk /var/lib/kubelet/pods/a63d919d-201b-4eb1-9d84-6440926211a9/volumes/kubernetes.io~csi/pvc-b7731785-8364-42a8-9e7d-7516801ab7e0/mount
sdi    8:128  0    1G  0 disk /var/lib/kubelet/pods/3e056ee4-bab4-4230-9054-ab214bdf711f/volumes/kubernetes.io~csi/pvc-89d37a02-8480-4317-b0f1-f17b2a886d1d/mount

请注意,Longhorn 设备名称以 /dev/sd[x] 开头

  • 如果不存在,则创建默认配置文件 /etc/multipath.conf
  • 将以下行添加到黑名单部分 devnode "^sd[a-z0-9]+"
blacklist {
    devnode "^sd[a-z0-9]+"
}
  • 重启多路径服务
systemctl restart multipathd.service
  • 验证是否应用了配置
multipath -t

多路径黑名单部分的默认配置默认阻止以下设备名称 ^(ram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9] ^(td|hd|vd)[a-z]

相关信息

9. Longhorn-UI:WebSocket 握手期间出错:意外响应代码:200 #2265

适用版本

现有 Longhorn 版本 < v1.1.0 升级到 Longhorn >= v1.1.0

症状

Longhorn 升级到版本 >= v1.1.0 后,遇到如下情况:

入口消息:

{"level":"error","msg":"vulcand/oxy/forward/websocket: Error dialing \"10.17.1.246\": websocket: bad handshake with resp: 200 200 OK","time":"2021-03-09T08:29:03Z"}

Longhorn UI 消息:

10.46.0.3 - - [19/Feb/2021:11:33:24 +0000] "GET /node/v1/ws/1s/engineimages HTTP/1.1" 200 578 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.68"
10.46.0.3 - - [19/Feb/2021:11:33:29 +0000] "GET /node/v1/ws/1s/volumes HTTP/1.1" 200 578 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.68"
10.46.0.3 - - [19/Feb/2021:11:33:32 +0000] "GET /node/v1/ws/1s/nodes HTTP/1.1" 200 578 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.68"
10.46.0.3 - - [19/Feb/2021:11:33:37 +0000] "GET /node/v1/ws/1s/events HTTP/1.1" 200 578 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.68"
10.46.0.3 - - [19/Feb/2021:11:33:38 +0000] "GET /node/v1/ws/1s/engineimages HTTP/1.1" 200 578 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.68"
10.46.0.3 - - [19/Feb/2021:11:33:41 +0000] "GET /node/v1/ws/1s/volumes HTTP/1.1" 200 578 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.68"

原因

为了支持不同的路由(Rancher-ProxyNodePortIngressNginx),Longhorn v1.1.0 重新构建了 UI 以使用 hash history,原因有两个:

  • 支持 Longhorn UI 路由到不同路径。例如,/longhorn/#/dashboard
  • 通过分离前端和后端来支持单页应用程序。

结果,<LONGHORN_URL>/<TAG> 更改为 <LONGHORN_URL>/#/<TAG>

之后,输出消息应类似于以下内容:

Ingress 消息应该没有 websocket 错误:

time="2021-03-16T04:54:23Z" level=debug msg="websocket: open" id=6809628160892941023 type=events
time="2021-03-16T04:54:23Z" level=debug msg="websocket: open" id=3234910863291903636 type=engineimages
time="2021-03-16T04:54:23Z" level=debug msg="websocket: open" id=2117763315178050120 type=backingimages
time="2021-03-16T04:54:23Z" level=debug msg="websocket: open" id=621105775322000457 type=volumes

Longhorn UI 消息:

使用 Ingress:

10.42.0.8 - - [16/Mar/2021:04:54:34 +0000] "GET /v1/nodes HTTP/1.1" 200 6729 "http://10.17.0.169/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.8 - - [16/Mar/2021:04:54:34 +0000] "GET /v1/backingimages HTTP/1.1" 200 117 "http://10.17.0.169/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.8 - - [16/Mar/2021:04:54:34 +0000] "GET /v1/volumes HTTP/1.1" 200 162 "http://10.17.0.169/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.8 - - [16/Mar/2021:04:54:34 +0000] "GET /v1/engineimages HTTP/1.1" 200 1065 "http://10.17.0.169/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.8 - - [16/Mar/2021:04:54:34 +0000] "GET /v1/settings HTTP/1.1" 200 30761 "http://10.17.0.169/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.8 - - [16/Mar/2021:04:54:34 +0000] "GET /v1/events HTTP/1.1" 200 62750 "http://10.17.0.169/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"

使用 Proxy:

10.42.0.0 - - [16/Mar/2021:05:03:51 +0000] "GET /v1/engineimages HTTP/1.1" 200 1070 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.0 - - [16/Mar/2021:05:03:51 +0000] "GET /v1/events HTTP/1.1" 200 62904 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.0 - - [16/Mar/2021:05:03:52 +0000] "GET /v1/engineimages HTTP/1.1" 200 1071 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.0 - - [16/Mar/2021:05:03:52 +0000] "GET /v1/nodes HTTP/1.1" 200 6756 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.0 - - [16/Mar/2021:05:03:52 +0000] "GET /v1/settings HTTP/1.1" 200 30882 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.0 - - [16/Mar/2021:05:03:52 +0000] "GET /v1/volumes HTTP/1.1" 200 168 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.0 - - [16/Mar/2021:05:03:52 +0000] "GET /v1/backingimages HTTP/1.1" 200 120 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
10.42.0.0 - - [16/Mar/2021:05:03:52 +0000] "GET /v1/events HTTP/1.1" 200 62900 "http://localhost:8001/api/v1/namespaces/longhorn-system/services/http:longhorn-frontend:80/proxy/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"

解决方案

  1. 清除浏览器缓存。
  2. <LONGHORN_URL>/# 访问/重新收藏 Longhorn URL

相关信息

10. Longhorn 卷需要很长时间才能完成安装

适用版本

所有 Longhorn 版本。

症状

启动使用 Longhorn 卷的工作负载 pod 时,Longhorn UI 显示 Longhorn 卷连接很快,但卷完成挂载和工作负载能够启动需要很长时间。

仅当 Longhorn 卷具有许多文件/目录并且在工作负载 pod 中设置 securityContext.fsGroup 时才会发生此问题,如下所示:

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000

原因

默认情况下,当看到 fsGroup 字段时,每次挂载卷时,Kubernetes 都会对卷内的所有文件和目录递归调用 chown()chmod()。即使卷的组所有权已经与请求的 fsGroup 匹配,也会发生这种情况,并且对于包含大量小文件的较大卷来说可能非常昂贵,这会导致 pod 启动需要很长时间。

解决方案

Kubernetes v1.19.x 及之前版本中没有解决此问题的方法。

自从版本 1.20.x 以来,Kubernetes 引入了一个新的 beta 特性:字段 fsGroupChangePolicy。即,

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    fsGroupChangePolicy: "OnRootMismatch"

fsGroupChangePolicy 设置为 OnRootMismatch 时,如果卷的根已具有正确的权限,则将跳过递归权限和所有权更改。这意味着,如果用户在 pod 启动之间不更改 pod.spec.securityContext.fsGroupK8s 只需检查根目录的权限和所有权,与总是递归地更改卷的所有权和权限相比,装载过程将快得多。

相关信息

11. volume readonly or I/O error

适用版本

所有 Longhorn 版本。

症状

当应用程序将数据写入现有文件或在 Longhorn 卷的挂载点创建文件时,将显示以下消息:

/ # cd data
/data # echo test > test
sh: can't create test: I/O error

在相关 pod 或节点主机中运行 dmesg 时,会显示以下消息:

[1586907.286218] EXT4-fs (sdc): mounted filesystem with ordered data mode. Opts: (null)
[1587396.152106] EXT4-fs warning (device sdc): ext4_end_bio:323: I/O error 10 writing to inode 12 (offset 0 size 4096 starting block 33026)
[1587403.789877] EXT4-fs error (device sdc): ext4_find_entry:1455: inode #2: comm sh: reading directory lblock 0
[1587404.353594] EXT4-fs warning (device sdc): htree_dirblock_to_tree:994: inode #2: lblock 0: comm ls: error -5 reading directory block
[1587404.353598] EXT4-fs error (device sdc): ext4_journal_check_start:61: Detected aborted journal
[1587404.355087] EXT4-fs (sdc): Remounting filesystem read-only
......

使用 `kubectl -n longhorn-system get event 检查事件时 | grep ,显示如下事件:

使用 kubectl -n longhorn-system get event | grep <volume name> 检查事件时,显示如下事件:

2m26s       Warning   DetachedUnexpectly       volume/pvc-342edde0-d3f4-47c6-abf6-bf8eeda3c32c               Engine of volume pvc-342edde0-d3f4-47c6-abf6-bf8eeda3c32c dead unexpectedly, reattach the volume

通过运行 kubectl -n longhorn-system logs <longhorn manager pod name> | grep <volume name>,在工作负载运行的节点上检查 Longhorn manager pod 的日志时,显示以下消息:

time="2021-01-05T11:20:46Z" level=debug msg="Instance handler updated instance pvc-342edde0-d3f4-47c6-abf6-bf8eeda3c32c-e-0fe2dac3 state, old state running, new state error"
time="2021-01-05T11:20:46Z" level=warning msg="Instance pvc-342edde0-d3f4-47c6-abf6-bf8eeda3c32c-e-0fe2dac3 crashed on Instance Manager instance-manager-e-a1fd54e4 at shuo-cluster-0-worker-3, try to get log"
......
time="2021-01-05T11:20:46Z" level=warning msg="Engine of volume dead unexpectedly, reattach the volume" accessMode=rwo controller=longhorn-volume frontend=blockdev node=shuo-cluster-0-worker-3 owner=shuo-cluster-0-worker-3 state=attached volume=pvc-342edde0-d3f4-47c6-abf6-bf8eeda3c32c
......
time="2021-01-05T11:20:46Z" level=info msg="Event(v1.ObjectReference{Kind:\"Volume\", Namespace:\"longhorn-system\", Name:\"pvc-342edde0-d3f4-47c6-abf6-bf8eeda3c32c\", UID:\"69bb0f94-da48-4d15-b861-add435f25d00\", APIVersion:\"longhorn.io/v1beta1\", ResourceVersion:\"7466467\", FieldPath:\"\"}): type: 'Warning' reason: 'DetachedUnexpectly' Engine of volume pvc-342edde0-d3f4-47c6-abf6-bf8eeda3c32c dead unexpectedly, reattach the volume"

失败原因

一旦 Longhorn 卷意外崩溃,Longhorn 卷的挂载点将失效。那么就无法通过挂载点读取或写入 Longhorn 卷中的数据。

根本原因

引擎崩溃通常是由于失去与每个副本的连接而导致的。 以下是发生这种情况的可能原因:

  1. 节点上的 CPU 利用率过高。 如果 Longhorn 引擎没有足够的 CPU 资源来处理请求,则请求可能会超时,导致与副本的连接丢失。 您可以参考下面文档,了解如何为 Longhorn 实例管理器 Pod 预留适当数量的 CPU 资源。
  2. 网络带宽不够。通常,如果所有这些卷都运行高密集型工作负载,则 1Gbps 网络将只能为 3 个卷提供服务。
  3. 网络延迟相对较高。如果一个节点上同时有多个卷 r/w,最好保证延迟小于 20ms
  4. 网络中断。它可能导致所有副本断开连接,然后引擎崩溃。
  5. 磁盘性能太低,无法及时完成请求。我们不建议在 Longhorn 系统中使用低 IOPS 磁盘(例如旋转磁盘)。

自动恢复

对于 v1.1.0 之前的 Longhorn 版本,Longhorn 会尝试自动重新挂载卷,但它可以处理的场景有限。

Longhorn v1.1.0 版本开始,引入了一个新设置“卷意外分离时自动删除工作负载 Pod(Automatically Delete Workload Pod when The Volume Is Detached Unexpectedly)”,以便 Longhorn 将自动删除由控制器管理的工作负载 Pod(例如 deploymentstatefulsetdaemonset 等)。

手动恢复

如果工作负载是一个简单的 pod,您可以删除并重新部署 pod。 如果回收策略不是 Retain,请确保相关 PVCPV 未被删除。否则,一旦相关的 PVC/PV 消失,Longhorn 卷将被删除。

如果工作负载 Pod 属于 Deployment/StatefulSet,您可以通过缩减然后扩展工作负载副本来重新启动 Pod

对于 Longhorn v1.1.0 或更高版本,您可以启用设置“卷意外分离时自动删除工作负载 Pod(Automatically Delete Workload Pod when The Volume Is Detached Unexpectedly)”

其他原因

当相关工作负载仍在使用卷时,用户意外或手动分离了 Longhorn 卷。

相关信息

  1. 最小资源需求调查和结果:
  2. 设置 Automatically Delete Workload Pod when The Volume Is Detached Unexpectedly 的讨论

12. volume pvc-xxx not scheduled

适用版本

所有 Longhorn 版本。

症状

使用 Longhorn Volume 作为 PVC 创建 Pod 时,Pod 无法启动。

使用 kubectl describe <pod> 检查错误消息时,会显示以下消息:

Warning  FailedAttachVolume  4m29s (x3 over 5m33s)  attachdetach-controller     AttachVolume.Attach failed for volume "pvc-xxx" : rpc error: code = Internal desc = Bad response statusCode [500]. Status [500 Internal Server Error]. Body: [message=unable to attach volume pvc-xxx to node-xxx: volume pvc-xxx not scheduled, code=Server Error, detail=] from [http://longhorn-backend:9500/v1/volumes/pvc-xxx?action=attach]

在上面的错误中注意到 Longhorn 返回的消息:

unable to attach volume pvc-xxx to node-xxx: volume pvc-xxx not scheduled

详情

这是由于 Longhorn 在不同节点上找不到足够的空间来存储卷的数据,导致卷调度失败。

最常见的原因

对于 Longhorn v1.0.x,默认 Longhorn 安装有以下设置:

  1. Node Level Soft Anti-affinity: false
  2. 默认 StorageClass longhorn 的副本计数设置为 3

这意味着 Longhorn 将始终尝试在三个不同节点上为三个副本分配足够的空间。

如果无法满足此要求,例如 由于集群中的节点少于 3 个,卷调度将失败。

解决方案

如果是这种情况,您可以:

  1. 要么将节点级软反亲和性(Node Level Soft Anti-affinity)设置为 true
  2. 或者,创建一个副本数设置为 12 的新 StorageClass
  3. 或者,向集群添加更多节点。

其他原因

有关调度策略的详细说明,请参阅 Longhorn 文档中的调度部分。

相关信息

Longhorn v1.1.0 开始,我们将引入一个新设置 Allow Volume Creation With Degraded Availability(默认为 true),以帮助处理较小集群上的用例。