Kubernetes ErrImageNeverPull与k3和docker保存[关闭]

sqyvllje  于 12个月前  发布在  Docker
关注(0)|答案(2)|浏览(210)

**已关闭。**此问题为not about programming or software development。目前不接受回答。

此问题似乎与a specific programming problem, a software algorithm, or software tools primarily used by programmers无关。如果您认为此问题与another Stack Exchange site的主题相关,可以发表评论,说明在何处可以回答此问题。
19天前关闭。
截至19天前,社区正在审查是否重新讨论这个问题。
Improve this question
我正在尝试将本地镜像部署到我的raspberry pi kubernetes集群:

$ sudo kubectl get nodes
NAME          STATUS   ROLES                  AGE    VERSION
oren2         Ready    <none>                 40m    v1.28.4+k3s2
oren1         Ready    <none>                 39m    v1.28.4+k3s2
oren4         Ready    <none>                 42m    v1.28.4+k3s2
raspberrypi   Ready    control-plane,master   167m   v1.28.4+k3s2

字符串
Docker镜像已经准备好了:

$ sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
translator   latest    fd8afed3a99b   27 minutes ago   1.04GB


我上传了它:

$ sudo docker save translator | sudo k3s ctr images import -
$ sudo k3s ctr images ls | grep translator
docker.io/library/translator:latest
# ... omitted ...


我使用下面的yaml(从here采用):

apiVersion: v1
kind: Pod
metadata:
  name: translator
  labels:
    component: web
spec:
  containers:
    - name: translator
      image: translator
      imagePullPolicy: Never
      ports:
        - containerPort: 3000
  restartPolicy: Never


当我试图得到我的豆荚它不工作:

$ sudo kubectl create -f config.yml 
pod/translator created
$ sudo kubectl get pods
NAME               READY   STATUS              RESTARTS   AGE
translator-g9rlh   0/1     ErrImageNeverPull   0          20m
translator         0/1     ErrImageNeverPull   0          12s


我的问题类似于this post,但不 * 使用 * Minikube

5w9g7ksd

5w9g7ksd1#

您有:

+----------------+             +---------------------+           
|                |             |                     |           
|   Docker Host  |             | Kubernetes Cluster  |           
|                |             | (Raspberry Pi, k3s) |          
+-------+--------+             +------+----------+---+          
        |                             |          |             
        |                             |          |             
        |  docker save                | kubectl  |             
        +---------------------------> | create   |             
        |                             |          |             
        |  Docker Image: translator   |          |             
        +---------------------------> |          |             
                                      +----------+

字符串
由于您使用的是本地镜像,因此需要确保Kubernetes YAML中的镜像名称与Docker环境中使用的名称匹配:docker.io/library/translator:latest

apiVersion: v1
kind: Pod
metadata:
  name: translator
  labels:
    component: web
spec:
  containers:
    - name: translator
      image: docker.io/library/translator:latest  # Use the full image name
      imagePullPolicy: Never
      ports:
        - containerPort: 3000
  restartPolicy: Never


并检查每个节点上的图像是否可用:

#!/bin/bash

# Fetch the list of node names from Kubernetes
NODES=$(kubectl get nodes -o jsonpath='{.items[*].metadata.name}')

# Loop through each node
for NODE in $NODES; do
    echo "Checking image on $NODE..."

    # Run the command to check for the image and store the output
    # Replace 'username' with the appropriate username for SSH access
    IMAGE_CHECK=$(ssh username@"$NODE" 'docker images | grep translator')

    # Check if the output contains the image name
    if [[ -z "$IMAGE_CHECK" ]]; then
        echo "Image 'translator' is MISSING on node $NODE"
    else
        echo "Image 'translator' is PRESENT on node $NODE"
    fi

    echo "-----------------------------------"
done


最后,如果您的本地Docker镜像translator仅在Kubernetes集群中的特定节点(或节点子集)上可用,则需要确保您的Pod在镜像所在的节点上调度。这一点特别重要,因为集群中有多个节点(oren2oren1oren4raspberrypi)。
要实现这一点,您可以在Kubernetes配置中使用Node AffinityTaints and Toleration

*节点亲和度允许您根据节点上的标签来限制您的pod可以调度到哪些节点上。

例如,如果translator映像仅在oren2上可用,则可以向oren2添加标签,并更新pod规范以包含此标签的节点关联。

*污点和容忍度是指在没有translator镜像的节点上应用污点,并在pod规范中添加相应的容忍度。这样,Kubernetes就不会将pod调度到有pod不能容忍的污点的节点上。

例如,这里是如何将节点亲和性添加到Kubernetes配置中,假设oren2被正确标记(例如,has-translator-image=true):

apiVersion: v1
kind: Pod
metadata:
  name: translator
  labels:
    component: web
spec:
  containers:
    - name: translator
      image: docker.io/library/translator:latest
      imagePullPolicy: Never
      ports:
        - containerPort: 3000
  restartPolicy: Never
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: has-translator-image
            operator: In
            values:
            - "true"


通过添加节点亲和性或污点和容忍度,您可以确保您的pod被调度在具有必要Docker镜像的节点上,这将防止与集群中不同节点的镜像可用性相关的潜在问题。
除了名称修复之外,我认为您的回答让我意识到我错过了一些东西:我必须为每个工作节点运行sudo docker save translator | sudo k3s ctr images import -,对吗?
我在想我的工作节点只需要安装Docker,实际的镜像(翻译器)就会“自动”发送给它们。
在Kubernetes集群中,特别是不使用集中式容器注册表的集群中,如果imagePullPolicy设置为Never,则每个工作节点都需要在本地提供所需的Docker镜像:这意味着Kubernetes不会尝试从远程注册表中提取镜像。
由于您使用的是k3s,它有自己的容器运行时(containerd),因此您需要将Docker镜像导入到每个节点上的k3s镜像存储中。Kubernetes或k3s不会自动处理这一点。命令sudo docker save translator | sudo k3s ctr images import -为执行它的节点执行此操作,但它不会将镜像分发到集群中的其他节点。
如果您的节点被标记,以识别您想要部署映像的节点(例如,has-translator-image=true),您可以编写以下脚本(chmod +x deploy_image.sh):

#!/bin/bash

# Label that identifies the nodes where the image should be deployed
LABEL_SELECTOR="has-translator-image=true"

# Docker image to be saved and transferred
DOCKER_IMAGE="translator"

# Save the Docker image as a tarball
sudo docker save "$DOCKER_IMAGE" > "$DOCKER_IMAGE.tar"

# Fetch the list of node names that have the specified label
NODES=$(kubectl get nodes -l $LABEL_SELECTOR -o jsonpath='{.items[*].metadata.name}')

# Loop through each node
for NODE in $NODES; do
    echo "Transferring image to $NODE"

    # Transfer the tarball to the node
    scp "$DOCKER_IMAGE.tar" username@"$NODE":~

    echo "Importing image on $NODE"
    # SSH into the node, import the image, and then optionally remove the tarball
    ssh username@"$NODE" "sudo k3s ctr images import ~/$DOCKER_IMAGE.tar && rm ~/$DOCKER_IMAGE.tar"

    echo "Image imported successfully on $NODE"
    echo "------------------------------------"
done

# Optionally remove the tarball from the local machine
rm "$DOCKER_IMAGE.tar"


请确保您已设置SSH密钥,以便对每个节点进行无密码访问。
这将通过网络将图像tarball传输到每个节点,并且在源机器和目标节点上都需要足够的磁盘空间。

46scxncf

46scxncf2#

您的容器规范中似乎缺少镜像标记。请将Pod配置镜像定义更改为:docker.io/library/translator:latest。您还可以验证此镜像是否存在于工作节点上,因为您已将镜像拉取策略设置为Never

相关问题