已知问题

使用 kind 遇到问题?本指南涵盖了一些已知问题及其解决方案/变通方法。

此外,您可能需要

目录 🔗︎

排查 Kind 问题 🔗︎

如果集群无法创建,请尝试使用 --retain 选项(保留失败的容器)再次尝试,然后运行 kind export logs 将容器中的日志导出到主机上的临时目录。

Kubectl 版本偏差 🔗︎

如果您的客户端与 kind 节点版本偏差太大,您可能在与 kind 集群交互时遇到问题。Kubernetes 仅支持客户端与 API 服务器之间的有限偏差

这通常是在与 Docker For Mac 一起运行 kind 时出现的问题。

此问题与 macOS 上的 docker 中的错误 相关

如果您看到类似以下错误消息

$ kubectl edit deploy -n kube-system kubernetes-dashboard
error: SchemaError(io.k8s.api.autoscaling.v2beta1.ExternalMetricStatus): invalid object doesn't have additional properties

您可以通过运行以下命令检查您的客户端和服务器版本

kubectl version

如果服务器和客户端版本之间存在不匹配,您应该安装更新的客户端版本。

如果您使用的是 Mac,可以通过运行以下命令通过 homebrew 安装 kubectl

brew install kubernetes-cli

并通过运行以下命令覆盖 Docker For Mac 创建的符号链接

brew link --overwrite kubernetes-cli

较旧的 Docker 安装 🔗︎

注意:这仅适用于 kind 版本 v0.15.0 及更早版本:KIND v0.16.0 及更高版本将不再支持 1.15 之前的 Kubernetes,而 1.13 以下版本在 kind v0.9.0 中不再受支持。

kind 已知在使用以下 Docker 版本时与 Kubernetes 1.13 或更低版本存在问题

以及其他旧版本的 Docker。

对于这些版本,您必须使用 Kubernetes >= 1.14,或者更理想地升级 Docker。

kind 已通过最新的稳定 docker-ce 版本进行测试。

使用 Snap 安装的 Docker 🔗︎

如果您使用 snap 安装了 Docker,则 docker 命令可能无法访问 $TMPDIR。这可能会破坏一些依赖于使用临时目录的 kind 命令(kind build ...)。

目前,解决此问题的变通方法是在使用 kind 时将 TMPDIR 环境变量设置为 snap 可以访问的目录。例如,可以是 $HOME 下的某个目录。

无法构建节点镜像 🔗︎

构建 kind 的节点镜像可能会由于 Docker for Mac 或 Docker for Windows 上的内存不足而失败。请参阅 kind#229

如果您看到类似以下内容

    cmd/kube-scheduler
    cmd/kube-proxy
/usr/local/go/pkg/tool/linux_amd64/link: signal: killed
!!! [0116 08:30:53] Call tree:
!!! [0116 08:30:53]  1: /go/src/k8s.io/kubernetes/hack/lib/golang.sh:614 kube::golang::build_some_binaries(...)
!!! [0116 08:30:53]  2: /go/src/k8s.io/kubernetes/hack/lib/golang.sh:758 kube::golang::build_binaries_for_platform(...)
!!! [0116 08:30:53]  3: hack/make-rules/build.sh:27 kube::golang::build_binaries(...)
!!! [0116 08:30:53] Call tree:
!!! [0116 08:30:53]  1: hack/make-rules/build.sh:27 kube::golang::build_binaries(...)
!!! [0116 08:30:53] Call tree:
!!! [0116 08:30:53]  1: hack/make-rules/build.sh:27 kube::golang::build_binaries(...)
make: *** [all] Error 1
Makefile:92: recipe for target 'all' failed
!!! [0116 08:30:54] Call tree:
!!! [0116 08:30:54]  1: build/../build/common.sh:518 kube::build::run_build_command_ex(...)
!!! [0116 08:30:54]  2: build/release-images.sh:38 kube::build::run_build_command(...)
make: *** [quick-release-images] Error 1
ERRO[08:30:54] Failed to build Kubernetes: failed to build images: exit status 2
Error: error building node image: failed to build kubernetes: failed to build images: exit status 2
Usage:
  kind build node-image [flags]

Flags:
      --base-image string   name:tag of the base image to use for the build (default "kindest/base:v20181203-d055041")
  -h, --help                help for node-image
      --image string        name:tag of the resulting image to be built (default "kindest/node:latest")
      --kube-root string    Path to the Kubernetes source directory (if empty, the path is autodetected)
      --type string         build type, default is docker (default "docker")

Global Flags:
      --loglevel string   logrus log level [panic, fatal, error, warning, info, debug] (default "warning")

error building node image: failed to build kubernetes: failed to build images: exit status 2

那么您可以尝试增加 Mac 或 Windows 上 Docker 引擎的资源限制。

建议您至少分配 8GB 的 RAM 来构建 Kubernetes。

打开首选项菜单。

转到高级设置页面,并更改那里的设置,请参阅 更改 Docker 的资源限制

Setting 8Gb of memory in Docker for Mac Setting 8Gb of memory in Docker for Windows

无法正常启动集群 🔗︎

此问题类似于 构建节点镜像时出现故障。如果集群创建过程成功,但您无法看到任何正在运行的 Kubernetes 资源,例如

$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED              STATUS              PORTS                      NAMES
c0261f7512fd        kindest/node:v1.12.2   "/usr/local/bin/entr…"   About a minute ago   Up About a minute   0.0.0.0:64907->64907/tcp   kind-1-control-plane
$ docker exec -it c0261f7512fd /bin/sh
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
#

kubectl 无法连接到集群,

$ kind export kubeconfig
$ kubectl cluster-info

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Unable to connect to the server: EOF

那么,如 kind#156 中所述,您可以通过运行以下命令来解决此问题,方法是通过删除 Docker 引擎遗留的未使用的數據或镜像来回收一些机器上的空间

docker system prune

以及/或者

docker image prune

您可以通过导出日志(kind export logs)并查看 kubelet 日志来验证问题,日志中可能包含以下内容

Dec 07 00:37:53 kind-1-control-plane kubelet[688]: I1207 00:37:53.229561     688 eviction_manager.go:340] eviction manager: must evict pod(s) to reclaim ephemeral-storage
Dec 07 00:37:53 kind-1-control-plane kubelet[688]: E1207 00:37:53.229638     688 eviction_manager.go:351] eviction manager: eviction thresholds have been met, but no pods are active to evict

无法使用 Cgroups v2 创建集群 🔗︎

对 Cgroups v2 的支持是在 Kubernetes 1.19 中引入的(请参阅 发行说明)。因此,仅支持在使用 Cgroups v2 的主机上运行 Kubernetes 版本 >= 1.19。

您可以通过导出日志(kind export logs)并查看 kubelet 日志来验证您是否遇到了此问题,日志中可能包含以下内容

Feb 23 08:39:04 kind-control-plane kubelet[3031]: W0223 08:39:04.644052    3031 server.go:616] failed to get the kubelet's cgroup: mountpoint for cpu not found.  Kubelet system container metrics may be missing.
Feb 23 08:39:04 kind-control-plane kubelet[3031]: F0223 08:39:04.644296    3031 server.go:274] failed to run Kubelet: mountpoint for  not found

由于“打开文件过多”导致的 Pod 错误 🔗︎

这可能是由于 inotify 资源不足造成的。资源限制由 fs.inotify.max_user_watchesfs.inotify.max_user_instances 系统变量定义。例如,在 Ubuntu 中,这些变量的默认值分别为 8192 和 128,这不足以创建具有多个节点的集群。

要临时增加这些限制,请在主机上运行以下命令

sudo sysctl fs.inotify.max_user_watches=524288
sudo sysctl fs.inotify.max_user_instances=512

要使更改持久化,请编辑文件 /etc/sysctl.conf 并添加以下行

fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 512

Docker 权限被拒绝 🔗︎

使用 kind 时,我们假设您以其身份执行 kind 的用户有权使用 docker。如果您最初使用 sudo 运行 Docker CLI 命令,您可能会看到以下错误,这表明您的 ~/.docker/ 目录由于 sudo 命令而以错误的权限创建。

WARNING: Error loading config file: /home/user/.docker/config.json
open /home/user/.docker/config.json: permission denied

要解决此问题,请按照 docker 文档 以非 root 用户身份管理 docker 中的说明操作,或者尝试在命令之前使用 sudo(如果您收到 command not found,请查看 关于 kind 中 sudo 的此评论)。

Docker 初始化守护程序配置 🔗︎

请确保在使用 kind 时,您的 /etc/docker/daemon.json 中不能包含 "init": true,因为这会导致 /sbin/init 显示以下神秘消息找不到用于生成进程的替代 telinit 实现。这与 /sbin/init 未以进程 ID 1 运行有关。

Windows 容器 🔗︎

适用于 Windows 的 Docker Desktop 支持运行 Linux(默认)和 Windows Docker 容器。

适用于 Windows 的 kind 需要 Linux 容器。要切换 Linux 和 Windows 容器,请参阅 此页面

Windows 容器与 Linux 容器不同,不支持在容器中运行 docker,因此不支持 kind。

不支持的架构 🔗︎

KIND 目前为 AMD64 和 ARM64 架构提供预构建的镜像。将来我们可能会支持其他架构,但目前需求量较低,构建成本较高。

要在其他架构上使用 kind,您需要先构建基础镜像,然后构建节点镜像。

运行 images/base/build.sh,然后记下构建的镜像名称,使用 kind build node-image --base-image=kindest/base:tag-i-built

有关如何执行此操作的更多详细信息,请参阅 快速入门 指南。

无法拉取镜像 🔗︎

当使用命名的 KIND 实例时,您有时可能会看到您的镜像无法在 Pod 上正确拉取。这通常会在执行 kubectl describe pod my-pod 时显示以下输出。

Failed to pull image "docker.io/my-custom-image:tag": rpc error: code = Unknown desc = failed to resolve image "docker.io/library/my-custom-image:tag": no available registry endpoint: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

如果此镜像已使用命令 kind load docker-image my-custom-image 加载到您的 KIND 集群中,那么您可能没有提供名称参数。

重新运行命令,这次添加 --name my-cluster-name 参数。

kind load docker-image my-custom-image --name my-cluster-name

Chrome OS 🔗︎

要在 Chrome OS 中运行 Kubernetes,LXC 容器必须允许嵌套。在 Crosh 会话中(ctrl+alt+t)

crosh> vmc launch termina
(termina) chronos@localhost ~ $ lxc config set penguin security.nesting true
(termina) chronos@localhost ~ $ lxc restart penguin

然后 KIND 集群必须使用 KubeletInUserNamespace 特性门(从 Kubernetes 1.22 开始可用)。

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  KubeletInUserNamespace: true

AppArmor 🔗︎

如果您的主机启用了 AppArmor,您可能会遇到 moby/moby/issues/7512

您可能需要在主机上禁用 AppArmor,或者至少禁用与您尝试在 KIND 中运行的应用程序相关的任何配置文件。

查看之前的讨论:kind#1179

IPv6 端口转发 🔗︎

Docker 假设所有 IPv6 地址都应该是可访问的,因此没有使用 NAT 实现端口映射 moby#17666

您可能需要使用 Kubernetes 服务(如 NodePort 或 LoadBalancer)通过节点的 IPv6 地址访问集群内的负载。

查看之前的讨论:kind#1326

无法获取 rootfs 信息 / “stat failed on /dev/…” 🔗︎

在某些系统上,创建集群会超时,并在 kubelet.log 中出现这些错误(设备有所不同)。

stat failed on /dev/nvme0n1p3 with error: no such file or directory
"Failed to start ContainerManager" err="failed to get rootfs info: failed to get device for dir \"/var/lib/kubelet\": could not find device with major: 0, minor: 40 in cached partitions map"

Kubernetes 需要访问存储设备节点才能执行某些操作,例如跟踪可用磁盘空间。因此,Kind 需要将必要的设备节点从主机挂载到控制平面容器中 - 但是,它并不总是能够确定 Kubernetes 需要哪个设备,因为这会因主机操作系统和文件系统而异。例如,上述错误发生在 Fedora Desktop 35 上的 BTRFS 文件系统中。

可以通过在集群配置文件中包含必要的设备作为额外挂载来解决此问题。

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraMounts:
    - hostPath: /dev/nvme0n1p3
      containerPath: /dev/nvme0n1p3
      propagation: HostToContainer

要确定必须列出的设备,已观察到两种变体。

查看之前的讨论:kind#2411

Fedora 🔗︎

Firewalld 🔗︎

在 Fedora 32 上,firewalld 默认情况下迁移到 nftables 后端。这似乎与 Docker 不兼容,导致 KIND 集群节点无法相互访问。

您可以通过将 /etc/firewalld/firewalld.conf 文件中的 FirewallBackendnftables 更改为 iptables 并重新启动 firewalld 来解决此问题。

sed -i /etc/firewalld/firewalld.conf 's/FirewallBackend=.*/FirewallBackend=iptables/'
systemctl restart firewalld

查看 #1547 (comment)Docker and Fedora 32 article

SELinux 🔗︎

在 Fedora 33 上,SELinux 策略的更新导致 kind create cluster 失败,并出现类似以下的错误。

docker: Error response from daemon: open /dev/dma_heap: permission denied.

虽然该策略已在 Fedora 34 中修复,但截至 2021 年 6 月 28 日,该修复尚未移植到 Fedora 33。将 SELinux 设置为允许模式(setenforce 0)是一种已知的解决方法。这将禁用 SELinux 直到下次启动。有关更多详细信息,请查看 kind#2296

使用 Docker Desktop 作为容器运行时无法创建集群 🔗︎

Docker Desktop 4.3.0+ 使用 Cgroups v2(查看 发布说明),并且只能与 Kubernetes 版本 >= 1.19 协同工作(查看 使用 Cgroups v2 无法创建集群)。

有几种方法可以解决 Docker Desktop 的此限制。您可以将 Docker Desktop 降级到 4.2.0 版本。这是最后一个默认使用 cgroupv1 的版本。

您也可以对 Docker Desktop 设置进行配置更改。从 Docker Desktop 4.4.2 开始,已添加一个已弃用的选项来支持那些需要 cgroupv1 的用户。如 4.4.2 发布说明 中所述,可以在 settings.json 中将设置 deprecatedCgroupv1 设置为 true。重新启动 Docker Engine 后,Docker Desktop 使用的 VM 将使用 cgroupv1。

适用于 macOS 和 Windows 的 Docker Desktop 🔗︎

Docker 容器无法在 macOS 和 Windows 上本地执行,因此 Docker Desktop 在 Linux VM 中运行它们。因此,容器网络不会公开到主机,您无法通过 IP 访问 KIND 节点。您可以通过配置 额外的端口映射 来解决此限制。

较旧的 Linux 发行版 🔗︎

KIND 使用 cgroupns=private 的 cgroup 设置。cgroup 命名空间功能是在 2016 年添加的,因此一些使用较旧内核的较旧 Linux 发行版没有 KIND 工作所需的必要功能。特别是,像 Red Hat Enterprise Linux 7 及其克隆这样的发行版。

尝试在具有较旧内核的系统上创建 KIND 集群会导致失败,并出现类似以下的错误消息。

Command Output: WARNING: Your kernel does not support cgroup namespaces.  Cgroup namespace setting discarded.

在这些环境中使用 KIND 需要将您的操作系统升级到支持 cgroup 命名空间的更新版本。另一种选择是使用更新的内核运行虚拟机。