使用 Raspberry Pi 构建 Kubernetes 集群

在多个 Raspberry Pi 上安装 Kubernetes,以构建您自己的“家庭私有云”容器服务。
332 位读者喜欢这篇文章。
Coding the Raspberry Pi in a web emulator

Opensource.com

Kubernetes 是一个企业级容器编排系统,从一开始就设计为云原生。它已成长为事实上的云容器平台,并随着它拥抱新技术(包括容器原生虚拟化和无服务器计算)而不断扩展。

Kubernetes 管理容器以及更多内容,从边缘的微型规模到公共和私有云环境中的大规模。对于“家庭私有云”项目来说,它是一个完美的选择,它既提供了强大的容器编排,又提供了学习一项需求量大且与云如此彻底集成的技术的机会,以至于它的名字实际上已成为“云计算”的代名词。

没有什么比 Kubernetes 更能代表“云”了,也没有什么比 Raspberry Pi 更能呼唤“集群我!”了。在廉价的 Raspberry Pi 硬件上运行本地 Kubernetes 集群是获得管理和开发真正的云技术巨头经验的好方法。

在 Raspberry Pi 上安装 Kubernetes 集群

本练习将在运行 Ubuntu 20.04 的三个或更多 Raspberry Pi 4 上安装 Kubernetes 1.18.2 集群。Ubuntu 20.04 (Focal Fossa) 提供了一个以 Raspberry Pi 为中心的 64 位 ARM (ARM64) 镜像,其中包含 64 位内核和用户空间。由于目标是使用这些 Raspberry Pi 运行 Kubernetes 集群,因此运行 AArch64 容器镜像的能力非常重要:很难找到常见软件甚至标准基础镜像的 32 位镜像。借助其 ARM64 镜像,Ubuntu 20.04 允许您将 64 位容器镜像与 Kubernetes 一起使用。

AArch64 与 ARM64;32 位与 64 位;ARM 与 x86

请注意,AArch64 和 ARM64 实际上是同一回事。名称不同是由于它们在不同社区中的使用而产生的。许多容器镜像被标记为 AArch64,并且可以在标记为 ARM64 的系统上正常运行。具有 AArch64/ARM64 架构的系统能够运行 32 位 ARM 镜像,但反之则不然:32 位 ARM 系统无法运行 64 位容器镜像。这就是 Ubuntu 20.04 ARM64 镜像如此有用的原因。

在不深入解释不同架构类型的情况下,值得注意的是 ARM64/AArch64 和 x86_64 架构不同,并且在 64 位 ARM 架构上运行的 Kubernetes 节点无法运行为 x86_64 构建的容器镜像。在实践中,您会发现一些镜像没有为这两种架构构建,并且可能无法在您的集群中使用。您还需要在基于 AArch64 的系统上构建自己的镜像,或者费一番周折才能让您的常规 x86_64 系统构建 AArch64 镜像。在“家庭私有云”项目的未来文章中,我将介绍如何在您的常规系统上构建 AArch64 镜像。

为了兼顾两者,在本教程中设置 Kubernetes 集群后,您可以稍后向其添加 x86_64 节点。您可以通过使用 Kubernetes 污点和容忍度,通过 Kubernetes 调度器将给定架构的镜像调度到适当的节点上运行。

关于架构和 镜像 就说这么多。现在是安装 Kubernetes 的时候了,开始行动吧!

要求

本练习的要求非常简单。您将需要

  • 三台(或更多)Raspberry Pi 4(最好是 4GB RAM 型号)
  • 在所有 Raspberry Pi 上安装 Ubuntu 20.04 ARM64

为了简化初始设置,请阅读修改磁盘镜像以创建基于 Raspberry Pi 的家庭实验室,以便在将 Ubuntu 镜像写入 SD 卡并在 Raspberry Pi 上安装之前,向其添加用户和 SSH authorized_keys。

配置主机

一旦 Ubuntu 安装在 Raspberry Pi 上并且可以通过 SSH 访问,您需要进行一些更改才能安装 Kubernetes。

安装和配置 Docker

截至撰写本文时,Ubuntu 20.04 在基本存储库中附带了最新版本的 Docker v19.03,可以直接使用 apt 命令安装。请注意,软件包名称是 docker.io。在所有 Raspberry Pi 上安装 Docker

# Install the docker.io package
$ sudo apt install -y docker.io

安装软件包后,您需要进行一些更改以启用 cgroups(控制组)。Cgroups 允许 Linux 内核限制和隔离资源。实际上,这允许 Kubernetes 更好地管理其运行的容器使用的资源,并通过将容器彼此隔离来提高安全性。

在对所有 RPi 进行以下更改之前,请检查 docker info 的输出

# Check `docker info`
# Some output omitted
$ sudo docker info
(...)
 Cgroup Driver: cgroups
(...)
WARNING: No memory limit support
WARNING: No swap limit support
WARNING: No kernel memory limit support
WARNING: No kernel memory TCP limit support
WARNING: No oom kill disable support

上面的输出突出显示了需要更改的部分:cgroup 驱动程序和限制支持。

首先,将 Docker 使用的默认 cgroups 驱动程序从 cgroups 更改为 systemd,以允许 systemd 充当 cgroups 管理器,并确保只使用一个 cgroup 管理器。这有助于系统稳定性,并且是 Kubernetes 推荐的。为此,创建或替换 /etc/docker/daemon.json 文件,内容为

# Create or replace the contents of /etc/docker/daemon.json to enable the systemd cgroup driver

$ sudo cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

启用 cgroups 限制支持

接下来,启用限制支持,如上面 docker info 输出中的警告所示。您需要修改内核命令行以在启动时启用这些选项。对于 Raspberry Pi 4,将以下内容添加到 /boot/firmware/cmdline.txt 文件中

  • cgroup_enable=cpuset
  • cgroup_enable=memory
  • cgroup_memory=1
  • swapaccount=1

确保将它们添加到 cmdline.txt 文件行的末尾。这可以使用 sed 在一行中完成

# Append the cgroups and swap options to the kernel command line
# Note the space before "cgroup_enable=cpuset", to add a space after the last existing item on the line
$ sudo sed -i '$ s/$/ cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 swapaccount=1/' /boot/firmware/cmdline.txt

sed 命令匹配行的终止符(由第一个 $ 表示),并将其替换为列出的选项(它有效地将选项附加到该行)。

通过这些更改,Docker 和内核应该已配置为 Kubernetes 所需。重新启动 Raspberry Pi,当它们重新启动后,再次检查 docker info 的输出。Cgroups driver 现在是 systemd,并且警告已消失。

允许 iptables 查看桥接流量

根据文档,Kubernetes 需要配置 iptables 以查看桥接网络流量。您可以通过更改 sysctl 配置来执行此操作

# Enable net.bridge.bridge-nf-call-iptables and -iptables6
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sudo sysctl --system

安装 Ubuntu 的 Kubernetes 软件包

由于您使用的是 Ubuntu,因此可以从 Kubernetes.io Apt 存储库安装 Kubernetes 软件包。当前没有 Ubuntu 20.04 (Focal) 的存储库,但 Kubernetes 1.18.2 在上一个 Ubuntu LTS 存储库 Ubuntu 18.04 (Xenial) 中可用。最新的 Kubernetes 软件包可以从那里安装。

将 Kubernetes 存储库添加到 Ubuntu 的源

# Add the packages.cloud.google.com atp key
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

# Add the Kubernetes repo
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

当 Kubernetes 添加 Focal 存储库时——也许在下一个 Kubernetes 版本发布时——请确保切换到它。

将存储库添加到源列表后,安装三个必需的 Kubernetes 软件包:kubelet、kubeadm 和 kubectl

# Update the apt cache and install kubelet, kubeadm, and kubectl
# (Output omitted)
$ sudo apt update && sudo apt install -y kubelet kubeadm kubectl

最后,使用 apt-mark hold 命令禁用这三个软件包的定期更新。Kubernetes 的升级需要比通用更新过程更多的手动干预,并且需要人工关注

# Disable (mark as held) updates for the Kubernetes packages
$ sudo apt-mark hold kubelet kubeadm kubectl
kubelet set on hold.
kubeadm set on hold.
kubectl set on hold.

主机配置就到此为止!现在您可以继续设置 Kubernetes 本身了。

创建 Kubernetes 集群

安装 Kubernetes 软件包后,您可以继续创建集群。在开始之前,您需要做出一些决定。首先,需要将其中一个 Raspberry Pi 指定为控制平面(即主)节点。其余节点将被指定为计算节点。

您还需要选择一个网络 CIDR 用于 Kubernetes 集群中的 Pod。在集群创建期间设置 pod-network-cidr 可确保设置 podCIDR 值,并且稍后可以由容器网络接口 (CNI) 插件使用。本练习使用 Flannel CNI。您选择的 CIDR 不应与您家庭网络中当前使用的任何 CIDR 或由您的路由器或 DHCP 服务器管理的 CIDR 重叠。确保使用大于您预期需要的子网:Pod 总是比您最初计划的要多!在本示例中,我将使用 10.244.0.0/16,但请选择适合您的子网。

在做出这些决定之后,您可以初始化控制平面节点。SSH 或以其他方式登录到您已指定为控制平面的节点。

初始化控制平面

Kubernetes 使用引导令牌来验证正在加入集群的节点。在初始化控制平面节点时,需要将此令牌传递给 kubeadm init 命令。生成一个令牌以与 kubeadm token generate 命令一起使用

# Generate a bootstrap token to authenticate nodes joining the cluster
$ TOKEN=$(sudo kubeadm token generate)
$ echo $TOKEN
d584xg.xupvwv7wllcpmwjy

现在您可以初始化控制平面,使用 kubeadm init 命令

# Initialize the Control Plane
# (output omitted)
$ sudo kubeadm init --token=${TOKEN} --kubernetes-version=v1.18.2 --pod-network-cidr=10.244.0.0/16

如果一切顺利,您应该在输出末尾看到类似于这样的内容

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.ac.cn/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.2.114:6443 --token zqqoy7.9oi8dpkfmqkop2p5 \
    --discovery-token-ca-cert-hash sha256:71270ea137214422221319c1bdb9ba6d4b76abfa2506753703ed654a90c4982b

请注意两件事:首先,Kubernetes kubectl 连接信息已写入 /etc/kubernetes/admin.conf。此 kubeconfig 文件可以复制到 ~/.kube/config,用于主节点上的 root 用户或普通用户,或者复制到远程计算机。这将允许您使用 kubectl 命令控制您的集群。

其次,输出的最后一行以 kubernetes join 开头,是您可以运行以将更多节点加入集群的命令。

将新的 kubeconfig 复制到您的用户可以使用的位置后,您可以使用 kubectl get nodes 命令验证控制平面是否已安装。

# Show the nodes in the Kubernetes cluster
# Your node name will vary
$ kubectl get nodes
NAME         STATUS   ROLES    AGE     VERSION
elderberry   Ready    master   7m32s   v1.18.2

安装 CNI 插件

CNI 插件处理 Pod 网络的配置和清理。如前所述,本练习使用 Flannel CNI 插件。由于 podCIDR 值已设置,您只需下载 Flannel YAML 并使用 kubectl apply 将其安装到集群中。这可以使用 kubectl apply -f - 在一行中完成,以从标准输入获取数据。这将创建管理 Pod 网络所需的 ClusterRoles、ServiceAccounts 和 DaemonSets(等等)。

下载 Flannel YAML 数据并将其应用到集群

# Download the Flannel YAML data and apply it
# (output omitted)
$ curl -sSL https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml | kubectl apply -f -

将计算节点加入集群

在 CNI 插件就位后,现在是时候将计算节点添加到集群了。加入计算节点只是运行在 kube init 命令末尾提供的 kubeadm join 命令的问题,该命令用于初始化控制平面节点。对于您要加入集群的其他 Raspberry Pi,请登录到主机并运行该命令

# Join a node to the cluster - your tokens and ca-cert-hash will vary
$ sudo kubeadm join 192.168.2.114:6443 --token zqqoy7.9oi8dpkfmqkop2p5 \
    --discovery-token-ca-cert-hash sha256:71270ea137214422221319c1bdb9ba6d4b76abfa2506753703ed654a90c4982b

在每个节点上完成加入过程后,您应该能够在 kubectl get nodes 的输出中看到新节点

# Show the nodes in the Kubernetes cluster
# Your node name will vary
$ kubectl get nodes
NAME         STATUS   ROLES    AGE     VERSION
elderberry   Ready    master   7m32s   v1.18.2
gooseberry    Ready    <none>   2m39s   v1.18.2
huckleberry   Ready    <none>   17s     v1.18.2

验证集群

此时,您拥有一个功能齐全的 Kubernetes 集群。您可以运行 Pod、创建部署和作业等。您可以使用 服务 从集群中的任何节点访问集群中运行的应用程序。您可以使用 NodePort 服务或 Ingress 控制器实现外部访问。

为了验证集群是否正在运行,请创建一个新的命名空间、部署和服务,并检查部署中运行的 Pod 是否按预期响应。此部署使用 quay.io/clcollins/kube-verify:01 镜像 - 一个监听请求的 Nginx 容器(实际上,与文章 使用 Cloud-init 向您的私有云添加节点 中使用的镜像相同)。您可以在 此处 查看镜像 Containerfile。

创建一个名为 kube-verify 的命名空间用于部署

# Create a new namespace
$ kubectl create namespace kube-verify
# List the namespaces
$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   63m
kube-node-lease   Active   63m
kube-public       Active   63m
kube-system       Active   63m
kube-verify       Active   19s

现在,在新命名空间中创建一个部署

# Create a new deployment
$ cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-verify
  namespace: kube-verify
  labels:
    app: kube-verify
spec:
  replicas: 3
  selector:
    matchLabels:
      app: kube-verify
  template:
    metadata:
      labels:
        app: kube-verify
    spec:
      containers:
      - name: nginx
        image: quay.io/clcollins/kube-verify:01
        ports:
        - containerPort: 8080
EOF
deployment.apps/kube-verify created

Kubernetes 现在将开始创建 deployment,其中包含三个 pod,每个 pod 运行 quay.io/clcollins/kube-verify:01 镜像。大约一分钟后,新的 pod 应该会运行起来,您可以使用 kubectl get all -n kube-verify 查看它们,以列出在新命名空间中创建的所有资源。

# Check the resources that were created by the deployment
$ kubectl get all -n kube-verify
NAME                               READY   STATUS              RESTARTS   AGE
pod/kube-verify-5f976b5474-25p5r   0/1     Running             0          46s
pod/kube-verify-5f976b5474-sc7zd   1/1     Running             0          46s
pod/kube-verify-5f976b5474-tvl7w   1/1     Running             0          46s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kube-verify   3/3     3            3           47s

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/kube-verify-5f976b5474   3         3         3       47s

您可以看到新的 deployment、deployment 创建的 replicaset,以及 replicaset 创建的三个 pod,以满足 deployment 中 replicas: 3 的请求。您可以看到 Kubernetes 内部机制正在工作。

现在,创建一个 Service 来暴露运行在三个 pod 中的 Nginx “应用程序”(或者,在本例中,是欢迎页面)。这将充当一个单一的端点,您可以通过它连接到这些 pod。

# Create a service for the deployment
$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
  name: kube-verify
  namespace: kube-verify
spec:
  selector:
    app: kube-verify
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
EOF
service/kube-verify created

创建 service 后,您可以检查它并获取新 service 的 IP 地址。

# Examine the new service
$ kubectl get -n kube-verify service/kube-verify
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kube-verify   ClusterIP   10.98.188.200   <none>        80/TCP    30s

您可以看到 kube-verify service 已被分配一个 ClusterIP(仅在集群内部可用),地址为 10.98.188.200。此 IP 地址可以从您的任何节点访问,但不能从集群外部访问。您可以通过连接到此 IP 地址来验证 deployment 中的容器是否正常工作。

# Use curl to connect to the ClusterIP:
# (output truncated for brevity)
$ curl 10.98.188.200
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

成功!您的 service 正在运行,容器内的 Nginx 正在响应您的请求。

至此,您已经在 Raspberry Pi 上拥有一个正在运行的 Kubernetes 集群,并安装了 CNI 插件 (Flannel),以及一个运行 Nginx Web 服务器的测试 deployment 和 service。在大型公共云中,Kubernetes 具有不同的 Ingress 控制器来与不同的解决方案进行交互,例如最近介绍的 Skipper 项目。同样,私有云也具有 Ingress 控制器,用于与硬件负载均衡器设备(如 F5 Networks 的负载均衡器)或 Nginx 和 HAProxy 控制器交互,以处理进入节点的流量。

在以后的文章中,我将探讨如何通过安装您自己的 Ingress 控制器,将集群中的服务暴露给外部世界。我还将研究动态存储 provisioner 和 StorageClass,用于为应用程序分配持久存储,包括利用您在之前的文章《将您的 Raspberry Pi 家庭实验室变成网络文件系统》中设置的 NFS 服务器,为您的 pod 创建按需存储。

前进吧,Kubernetes!

“Kubernetes”(κυβερνήτης)在希腊语中是“舵手”的意思——但这是否意味着既指驾驶船只的人,也指引导船只的动作?嗯,不是。“Kubernan”(κυβερνάω)在希腊语中是“驾驶”或“掌舵”的意思,所以前进并 Kubernan 吧,如果您在会议或其他场合看到我,请原谅我尝试将名词动词化。来自另一种语言。我不说的语言。

免责声明:如前所述,我不阅读或说希腊语,尤其是古代希腊语,所以我选择相信我在互联网上读到的东西。您知道是怎么回事。请持保留态度,并稍稍体谅我,因为我没有开“这对我来说就像希腊语一样”的玩笑。然而,仅仅提到它,我就因此能够开这个玩笑,而实际上并没有开,所以我要么是鬼鬼祟祟,要么是聪明,要么两者都是。或者,两者都不是。我没有声称这是一个笑话。

所以,前进吧,像专业人士一样使用您自己的 Kubernetes 容器服务在家中的私有云中驾驶您的容器!随着您越来越得心应手,您可以修改您的 Kubernetes 集群以尝试不同的选项,例如前面提到的 Ingress 控制器和用于持久卷的动态 StorageClass。

这种持续学习是 DevOps 的核心,而新服务的持续集成和交付反映了敏捷方法,我们都已经接受了这两种方法,因为我们已经学会了应对云所实现的大规模,并发现我们传统的实践无法跟上步伐。

看看!技术、策略、哲学、一点点希腊语,以及一个糟糕的元笑话,都在一篇文章中!

接下来阅读什么
Chris Collins
Chris Collins 是 Red Hat 的 SRE 和 OpenSource.com 的通讯员,热衷于自动化、容器编排及其周围的生态系统,并且喜欢为了乐趣在家中重现企业级技术。

25 条评论

绝对想试用一下!!太酷了!你能想象在新的 Rasp 4 8GB 上会怎么样吗?!

我现在绝对想买一堆 8GB 型号。有些工作负载有时需要超过 4 GB 的 RAM,如果任何节点一开始都没有 4 GB,您就无法在集群上运行这些工作负载!

Raspberry Pi 非常适合在家中玩 Kubernetes 集群。它们非常便宜,而且支持良好。很容易获得一些它们,并复制 Kubernetes 在生产环境中的部署方式。

回复 ,作者:brunoamuniz

Chris,

精彩的文章,正合时宜,今天我买了 4 个 Raspberry Pi 4 8GB 来创建一个集群。我将尝试一下,看看根据您的文章效果如何

回复 ,作者:clcollins

我一直在寻找像这样详细的文章。我找到了。

如果您只是为了教育目的而玩玩,您最好将 pod 网络 cidr 指定为 10.244.0.0/16,否则您可能会遇到问题。
已测试 :)

感谢您的反馈!您能详细说明一下吗?我没有直接设置 pod 网络 cidr,但它是使用 10.244.0.0/24 创建的。(不是像您建议的 /16。)我确实看到 flannel 配置硬编码为 10.244.0.0/16。

我遗漏了什么吗?

谢谢!

回复 ,作者:huberttrz (未验证)

非常清晰的教程 - 谢谢

只有一个问题... 在验证步骤中,我应该能够从 master 节点 curl ClusterIP 地址吗?
我似乎只能从 worker 节点(我只有一个)做到这一点,不确定这是否是预期的?

谢谢

您应该能够从 master 节点 curl ClusterIP,没有任何问题。我不确定为什么您不能。我在我用来写这篇文章的集群上验证过,它可以正常工作,没有任何问题。有没有可能是路由问题?也许是与 ClusterIP 的 IP 冲突?

回复 ,作者:pdunn467 (未验证)

完全新手的问题:这(Raspberry Pi 集群上的 Kubernetes)是否是“负载均衡”多个 ssh 登录到三到四个 Raspberry Pi 的合理方法?我希望支持一组需要远程基本访问 64 位 Raspberry Pi 的学生。

谢谢。

在我看来,对于负载均衡 SSH 登录来说,这将完全是过度杀伤,即使这样,那也将是 SSH 登录到容器中,而不是直接登录到 Pi 本身。除非,这就是您的意图。但我仍然认为这会带来很多开销。

您最好使用类似轮询 DNS 设置的东西 - 这是我们之前的工作中所做的事情。您也可以使用像 HAProxy 这样的代理来处理负载均衡。这可能是我对此类情况的建议。

回复 ,作者:bobmon (未验证)

谢谢!
我无法控制 DNS(我得到一个 IP 地址)。我将深入研究 HAProxy。

回复 ,作者:clcollins

刚刚尝试编辑文件 /boot/firmware/cmdline.txt,在我的 Raspberry Pi 4 上不存在。

感谢您分享。是的,我认为 /boot/firmware 目录是较新的东西。我认为这是一个发行版的东西,但我可能是错的。

回复 ,作者:cmills

我很确定我正确地应用了这些 cgroups 设置,但它们似乎没有生效。

docker info

警告:不支持交换限制
警告:不支持 cpu cfs 额度
警告:不支持 cpu cfs 周期

pi@k8wk-2:~ $ cat /boot/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=38313a2a-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 swapaccount=1

回复 ,作者:cmills

pi@k8wk-2:~ $ uname -a
Linux k8wk-2 4.19.118-v7l+ #1311 SMP Mon Apr 27 14:26:42 BST 2020 armv7l GNU/Linux

回复 ,作者:cmills

我遇到了 kubeadm 拒绝在我的 Pi 4 上初始化的issue

[wait-control-plane] 等待 kubelet 从目录 "/etc/kubernetes/manifests" 以静态 Pod 的形式启动控制平面。这可能需要长达 4 分钟
[kubelet-check] 初始超时 40 秒已过。
[kubelet-check] 看起来 kubelet 没有运行或不健康。
[kubelet-check] 等于 'curl -sSL http://localhost:10248/healthz' 的 HTTP 调用失败,错误为:Get http://localhost:10248/healthz: dial tcp 127.0.0.1:10248: connect: connection refused。

不幸的是,发生了一个错误
等待条件超时

此错误可能是由以下原因引起的
- kubelet 没有运行
- kubelet 由于节点配置错误(禁用了必需的 cgroups)而不健康

我相信我在某个地方读到过 etcd 失败是因为它实际上没有针对 arm64 进行测试 - 但如果真是这样,那么每个人都会遇到同样的问题。

有人以前见过这个问题吗?

我也遇到了同样的问题。主要区别在于我正在使用 Raspberry OS 10 (debian buster),因为我需要支持 SDD 启动。

我尝试过 Ubuntu 20.04,它可以工作

回复 ,作者:vjvalenti

你好,非常好的文章。我的所有 Kubernetes 集群都工作正常,但是当我在 service 上执行 curl 时,我没有响应。您有什么想法吗?
感谢这篇文章

你好。非常好的文章。我的 raspi 集群工作正常,但是当我完成 curl 时,我没有响应。您知道为什么吗?
此致

再次感谢您的帖子。
考虑替换
`sudo cat > /etc/docker/daemon.json <

很棒的文章。在创建 `/etc/docker/daemon.json` 时,我遇到了权限问题。这对我有用

```bash
$ sudo tee -a /etc/docker/daemon.json >/dev/null <<'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
```

Chris,

非常好的文章!只是关于版本控制的 FYI。看起来 Kubelet 在 6 天前被提升到仓库中的 1.19.0,这导致了错误。您可能需要在 `apt install` 中包含软件包版本,因为下一个次要版本即将发布。

sudo kubeadm init --token=${TOKEN} --kubernetes-version=v1.18.2 --pod-network-cidr=10.244.0.0/16
W0831 21:35:28.472959 1108 configset.go:348] 警告:kubeadm 无法验证 API 组 [kubelet.config.k8s.io kubeproxy.config.k8s.io] 的组件配置
[init] 使用 Kubernetes 版本:v1.18.2
[preflight] 运行预检
[WARNING SystemVerification]: 缺少可选的 cgroups:hugetlb
错误执行阶段 preflight:[preflight] 发生了一些致命错误
[ERROR Swap]: 不支持在启用 swap 的情况下运行。请禁用 swap
[ERROR KubeletVersion]: kubelet 版本高于控制平面版本。这是不受支持的版本偏差,可能会导致集群功能失常。Kubelet 版本:"1.19.0" 控制平面版本:"1.18.2"
[preflight] 如果您知道自己在做什么,可以使用 `--ignore-preflight-errors=...` 使检查变为非致命的
要查看此错误的堆栈跟踪,请使用 --v=5 或更高版本执行

© . All rights reserved.