Как исправить «не удалось распаковать изображение в overlayfs снапшоттера: неожиданный тип носителя text/html», когда MicroK8S начинает развертывание?

Я продолжаю идти по разочаровывающему пути изучения 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

Я создаю из этого архив, чтобы его можно было отправить в мой трехузловой кластер:

      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

Наконец, давайте получим статус этого модуля:

      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.

Описывая один модуль в одном развертывании, я заметил следующую ошибку:

В kubelet не настроен IP-адрес ClusterDNS, и он не может создать под, используя политику «ClusterFirst». Возврат к политике «По умолчанию».

Ура! Еще одна вещь, которая не работает из коробки. Я исправил это способом MicroK8S, используя этот ответ . Это не решило проблему, но, по крайней мере, я разбиваю препятствия один за другим.

Обновление 2

Я хотел проверить правильность загруженного неопубликованного изображения, поэтому сделал это с лидером:

      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, как и следовало ожидать от другой машины в локальной сети.

Обновление 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

Затем я описываю получившийся модуль и получаю знакомую ошибку:

      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

Да, я кое-что заметил. Как и следовало ожидать, архив изображений на всех узлах имеет одинаковую контрольную сумму. Но при импорте один узел сообщает неправильный тип изображения. Они слегка переформатированы для удобства сравнения:

Узел «Арран»:


Узел «Ямадзаки»:

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

Узел «Никка»:

      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, и это узел с поврежденным образом. Теперь, чтобы повторно импортировать изображение и привести его в соответствие с остальными...

0 ответов

Другие вопросы по тегам