AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1132843
Accepted
halfer
halfer
Asked: 2023-06-08 03:59:01 +0800 CST2023-06-08 03:59:01 +0800 CST 2023-06-08 03:59:01 +0800 CST

当 MicroK8S 开始部署时,如何解决“无法在 snapshotter overlayfs 上解压图像:意外的媒体类型 text/html”?

  • 772

我继续沿着令人沮丧的学习 Kubernetes(特别是 MicroK8S)的道路走走停停。

因此,我在开发笔记本电脑上本地构建图像:

docker build -t k8s-workload .

这是一个简单的 PHP 网络应用程序,可报告一些请求元数据。它构建成功:

Sending build context to Docker daemon  13.82kB
Step 1/5 : FROM php:8.2-cli-alpine
 ---> c5f1f9770838
Step 2/5 : WORKDIR /root
 ---> Using cache
 ---> 492c997c963b
Step 3/5 : RUN apk update && apk upgrade
 ---> Using cache
 ---> f91505d5fe68
Step 4/5 : COPY src /root
 ---> 02bcc72dfc97
Step 5/5 : CMD ["sh", "/root/bin/start-server.sh"]
 ---> Running in 6bc3b72365e4
Removing intermediate container 6bc3b72365e4
 ---> 0c8a405b06af
Successfully built 0c8a405b06af
Successfully tagged k8s-workload:latest

我从中创建了一个 tarball,以便可以将其发送到我的三节点集群:

docker save k8s-workload > k8s-workload.docker.tar

然后我将它发送给集群中的领导者(尽管我假设它可以发送给他们中的任何一个):

scp k8s-workload.docker.tar 192.168.50.251:/home/myuser/

到目前为止,这一切看起来都很好。现在我想将图像旁加载到集群中的所有节点中:

root@arran:/home/myuser# microk8s images import < k8s-workload.docker.tar
Pushing OCI images to 192.168.50.251:25000
Pushing OCI images to 192.168.50.135:25000
Pushing OCI images to 192.168.50.74:25000

看起来很成功,我尝试创建一个工作负载:

root@arran:/home/myuser# microk8s kubectl create deployment k8s-workload --image=k8s-workload

最后让我们获取此 pod 的状态:

root@arran:/home/myuser# microk8s kubectl get pods
NAME                            READY   STATUS             RESTARTS   AGE
k8s-workload-6cdfbb6b59-zvgrl   0/1     ImagePullBackOff   0          35m

好吧,这看起来不太好。还有ErrImagePull的错误,不过现在好像已经换掉了。

如何调试图像无法启动的原因?

我发现了一种在节点上列出图像的方法。我在领导节点上找到了我新建的镜像:

root@arran:/home/myuser# microk8s ctr images list | grep workload
docker.io/library/k8s-workload:latest   application/vnd.docker.distribution.manifest.v2+json    sha256:725b...582b 103.5 MiB linux/amd64

所以图像是可用的。我可以得到一些关于这个问题的日志,但它没有透露任何我不知道的东西:

root@arran:/home/myuser# microk8s kubectl logs k8s-workload-1cdfaa6c49-zvgrl
Error from server (BadRequest): container "k8s-workload" in pod "k8s-workload-1cdfaa6c49-zvgrl" is waiting to start: trying and failing to pull image

接下来我可以尝试什么?据我所知,实际上没有节点需要拉取图像,因为它们在每个节点上都可用。

更新 1

我犹豫是否要在一个问题上添加太多问题,但总的来说我认为它们是值得添加的,因为它们都是获得一个结果的障碍:在 K8S 上成功部署一个微不足道的工作负载。

在描述单个部署中的单个 pod 时,我注意到它向我显示了这个错误:

kubelet 没有配置 ClusterDNS IP,无法使用“ClusterFirst”策略创建 Pod。回退到“默认”策略。

哎呀!开箱即用的另一件事。我已经使用此答案以 MicroK8S 方式修复了此问题。它并没有解决问题,但至少我在敲头上的路障,一个一个。

更新 2

我想检查侧载图像是否有效,所以我在 leader 上做了这个:

root@arran:/home/myuser# docker load < k8s-workload.docker.tar

解包很好:

bb01bd7e32b5: Loading layer [==================================================>]  7.618MB/7.618MB
e759f13eb8bc: Loading layer [==================================================>]  6.015MB/6.015MB
1a72c946ba2b: Loading layer [==================================================>]  12.29kB/12.29kB
9bbacedbd5e4: Loading layer [==================================================>]  6.144kB/6.144kB
53b5e1394bc2: Loading layer [==================================================>]  12.08MB/12.08MB
aff825926dad: Loading layer [==================================================>]  4.096kB/4.096kB
c76bce6229c6: Loading layer [==================================================>]   71.7MB/71.7MB
0503c7346508: Loading layer [==================================================>]   12.8kB/12.8kB
8c2f9e7d94bb: Loading layer [==================================================>]  65.54kB/65.54kB
7e0ad9ed4982: Loading layer [==================================================>]  10.97MB/10.97MB
b99f234d8751: Loading layer [==================================================>]  5.632kB/5.632kB
Loaded image: k8s-workload:latest

然后我在自定义端口上的领导者上运行它(即这是在 Docker 中,而不是 K8S 中):

root@arran:/home/myuser# docker run -p 9000:80 -it k8s-workload

这通过 cURL 响应,正如我期望从 LAN 上的另一台机器响应的那样。

更新 3

我突然想到“命名空间”图像名称可能不同 - 我应该指定而docker.io/library/k8s-workload:latest不是k8s-workload?我都试过了,我发现我得到了相同的结果。

所以这是最新的错误:

Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Scheduled  4m46s                  default-scheduler  Successfully assigned default/k8s-workload-68c899df98-qhmhr to yamazaki
  Normal   Pulling    3m17s (x4 over 4m45s)  kubelet            Pulling image "k8s-workload"
  Warning  Failed     3m15s (x4 over 4m43s)  kubelet            Failed to pull image "k8s-workload": rpc error: code = NotFound desc = failed to pull and unpack image "docker.io/library/k8s-workload:latest": failed to unpack image on snapshotter overlayfs: unexpected media type text/html for sha256:e823...45c8: not found
  Warning  Failed     3m15s (x4 over 4m43s)  kubelet            Error: ErrImagePull
  Warning  Failed     2m52s (x6 over 4m43s)  kubelet            Error: ImagePullBackOff
  Normal   BackOff    2m37s (x7 over 4m43s)  kubelet            Back-off pulling image "k8s-workload"

好的,所以我现在有更多的细节。“无法解压图像”错误实际上是什么意思?

更新 4

下面的一个有用的答案表明我可能需要设置一个拉取策略来让 K8S 期望图像在每个节点上可用,并且它不应该尝试拉取它们(它不存在于远程的任何地方)。

然而,在接受提供的建议时,虽然我得到了不同的错误代码 ( CreateContainerError),但根本原因是相同的:

Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  64s               default-scheduler  Successfully assigned default/k8s-workload to yamazaki
  Normal   Pulled     6s (x7 over 62s)  kubelet            Container image "k8s-workload" already present on machine
  Warning  Failed     6s (x7 over 62s)  kubelet            Error: failed to create containerd container: error unpacking image: unexpected media type text/html for sha256:1f2c...753e1: not found

更新 5

我暂时将此报告为一个错误,但我仍然欢迎在这里得到答案。

更新 6

基于顽强的坚持水平对灵魂有神奇的好处,我尝试使用子ctr命令删除图像。这是在跟随者节点上:

root@yamazaki:/home/myuser# microk8s ctr images rm docker.io/library/k8s-workload:latest
docker.io/library/k8s-workload:latest

然后使用我重新导入的相同子命令:

root@yamazaki:/home/myuser# microk8s ctr images import k8s-workload.docker.tar 
unpacking docker.io/library/k8s-workload:latest (sha256:725b...582b)...done

由于这是在节点级别而不是群集级别运行的,因此我对三个节点中的每一个节点都执行了此操作。

然后我使用了run命令,因为这允许设置拉取策略,而且我不想将解包问题与上面的拉取问题混为一谈。这又回到了集群领导者身上:

root@arran:/home/myuser# microk8s kubectl run k8s-workload --image=k8s-workload --image-pull-policy='Never' --port=80
pod/k8s-workload created

然后我描述生成的 pod,并得到一个熟悉的错误:

Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  36s               default-scheduler  Successfully assigned default/k8s-workload to yamazaki
  Normal   Pulled     6s (x5 over 35s)  kubelet            Container image "k8s-workload" already present on machine
  Warning  Failed     6s (x5 over 35s)  kubelet            Error: failed to create containerd container: error unpacking image: unexpected media type text/html for sha256:5f76...a3aa: not found

矛盾的是,这是令人安心的——将图像单独发送到每个节点是一件很麻烦的事情,因此我希望集群级图像导入能够工作。我怀疑一旦我弄清了解压问题的根源,它就会出现。

更新 7

对了,我发现了一些东西。正如人们所期望的那样,所有节点上的图像 tarball 都具有相同的校验和。但是当它被导入时,一个节点针对图像报告了错误的类型。为了便于比较,对这些进行了轻微的重新格式化:

节点“Arran”:

docker.io/library/k8s-workload:latest  
application/vnd.docker.distribution.manifest.v2+json  
sha256:725b...582b 103.5 MiB  
linux/amd64  
io.cri-containerd.image=managed

节点“山崎”:

docker.io/library/k8s-workload:latest  
text/html  
sha256:5f76...a3aa 218.4 KiB  
-  
io.cri-containerd.image=managed

节点“Nikka”:

docker.io/library/k8s-workload:latest  
application/vnd.docker.distribution.manifest.v2+json  
sha256:725b...582b 103.5 MiB  
linux/amd64  
io.cri-containerd.image=managed

看起来工作负载一直被选为在 Yamazaki 上运行,这就是图像损坏的节点。现在重新导入图像并使其与其他图像相匹配......

docker
  • 2 2 个回答
  • 106 Views

2 个回答

  • Voted
  1. mfinni
    2023-06-08T04:52:32+08:002023-06-08T04:52:32+08:00

    https://stackoverflow.com/questions/59980445/setting-image-pull-policy-using-kubectl

    kubectl run将--image-pull-policy作为命令行参数

    • 1
  2. Best Answer
    halfer
    2023-06-10T23:45:37+08:002023-06-10T23:45:37+08:00

    我的最后一次更新暗示了这个问题——一个节点的图像损坏了。巧合的是,这是 K8S 想要运行工作负载的节点。要解决此问题,我所要做的就是在本地重新导入图像:

    root@yamazaki:/home/myuser# microk8s ctr images import k8s-workload.docker.tar 
    unpacking docker.io/library/k8s-workload:latest (sha256:725b...582b)...done
    

    根据问题更新,我以两种方式导入此图像,均涉及 MicroK8S:

    • microk8s images执行全局集群导入
    • microk8s ctr images import执行每个节点导入

    我想我可以高度肯定地说,MicroK8S 或 containerd 损坏了图像(即它不能归咎于 scp 或错误的文件处理)。对于每个节点的导入,我使用 验证了本地 tarball sha256sum,它与所有其他的都一样。不幸的是,我希望这不再是一个可调查的错误,因为命令的确切历史现在如此复杂以至于可以被认为丢失了。

    也就是说,我将尝试从所有 containerd 实例切换图像,并再次使用集群导入器。该错误可能会再次触发。

    • 0

相关问题

  • 当你让一个进程监听 0.0.0.0 而不是 127.0.0.1 时,为什么 docker 工作仍然很困惑

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve