Kubernetes 开启 Fedora 使用 k3s 的物联网

Fedora 物联网是一个即将到来的 Fedora 针对物联网的版本。 它是去年推出的 Fedora 杂志中的文章如何打开 LED Fedora 物联网。 从那时起,它一直在不断改进,与 Fedora Silverblue 提供针对以容器为中心的工作流的不可变基础操作系统。

Kubernetes 是一个非常流行的容器编排系统。 它可能最常用于处理巨大工作负载的强大硬件。 但是,它也可以在 Raspberry Pi 3 等轻量级设备上使用。继续阅读以了解具体方法。

为什么选择 Kubernetes?

虽然 Kubernetes 在云中风靡一时,但在小型单板计算机上运行它可能并不明显。 但这样做肯定是有原因的。 首先,这是学习和熟悉 Kubernetes 的好方法,无需昂贵的硬件。 其次,由于它的受欢迎程度,有 大量的应用程序 预先打包好在 Kubernetes 集群中运行。 更不用说大型社区在您遇到困难时提供帮助。

最后但并非最不重要的一点是,容器编排实际上可能使事情变得更容易,即使在家庭实验室中的小规模也是如此。 这在处理学习曲线时可能并不明显,但这些技能将在未来处理任何集群时有所帮助。 不管是单节点 Raspberry Pi 集群还是大型机器学习农场。

K3s——轻量级 Kubernetes

Kubernetes 的“正常”安装(如果可以说存在这样的东西)对于物联网来说有点沉重。 建议每台机器至少有 2 GB RAM! 但是,有很多替代品,其中一位新人是 k3s – 轻量级 Kubernetes 发行版。

K3s 的特殊之处在于它已将 etcd 替换为 SQLite 以满足其键值存储需求。 需要注意的另一件事是,k3s 作为单个二进制文件而不是每个组件一个二进制文件提供。 这减少了内存占用并简化了安装。 多亏了上述,k3s 应该能够以 512 MB 的 RAM 运行 k3s,非常适合小型单板计算机!

你需要什么

  1. Fedora 虚拟机或物理设备中的物联网。 请参阅出色的入门指南 这里. 一台机器就足够了,但两台机器可以让您测试向集群添加更多节点。
  2. 配置防火墙 允许端口 6443 和 8472 上的流量。或者只是通过运行“systemctl stop firewalld”来禁用它。

安装 k3s

安装 k3s 非常简单。 只需运行安装脚本:

curl -sfL https://get.k3s.io | sh -

这将下载、安装和启动 k3s。 安装后,通过运行以下命令从服务器获取节点列表:

kubectl get nodes

请注意,有几个选项可以通过环境变量传递给安装脚本。 这些可以在 文件. 当然,没有什么可以阻止您通过直接下载二进制文件来手动安装 k3s。

虽然非常适合实验和学习,但单节点集群并不是一个集群。 幸运的是,添加另一个节点并不比设置第一个节点难。 只需将两个环境变量传递给安装脚本,使其找到第一个节点,避免运行k3s的服务器部分

curl -sfL https://get.k3s.io | K3S_URL=https://example-url:6443 
K3S_TOKEN=XXX sh -

这 example上面的 -url 应替换为第一个节点的 IP 地址或完全限定域名。 在该节点上,令牌(由 XXX 表示)位于文件 /var/lib/rancher/k3s/server/node-token 中。

部署一些容器

现在我们有了一个 Kubernetes 集群,我们实际上可以用它做什么呢? 让我们从部署一个简单的 Web 服务器开始。

kubectl create deployment my-server --image nginx

这将创建一个 部署 从容器映像“nginx”中命名为“my-server”(默认使用 docker hub 作为注册表和最新标签)。 您可以看到通过运行以下命令创建的 Pod。

kubectl get pods

为了访问 pod 中运行的 nginx 服务器,首先通过一个 服务. 以下命令将创建一个与部署同名的服务。

kubectl expose deployment my-server --port 80

该服务用作 Pod 的一种负载平衡器和 DNS 记录。 例如,当运行第二个 Pod 时,我们将能够 curl 只需指定 my-server (服务的名称)即可使用 nginx 服务器。 见 example 下面是如何做到这一点。

# Start a pod and run bash interactively in it
kubectl run debug --generator=run-pod/v1 --image=fedora -it -- bash
# Wait for the bash prompt to appear
curl my-server
# You should get the "Welcome to nginx!" page as output

入口控制器和外部 IP

默认情况下,Service 只能获取 ClusterIP(只能在集群内部访问),但您也可以通过将其类型设置为 负载均衡器. 但是,并非所有应用程序都需要自己的 IP 地址。 相反,通常可以通过基于主机标头或路径路由请求在多个服务之间共享一个 IP 地址。 您可以在 Kubernetes 中使用 入口,这就是我们要做的。 Ingress 还提供额外的功能,例如流量的 TLS 加密,而无需修改您的应用程序。

Kubernetes 需要一个入口控制器来使入口资源正常工作,k3s 包括 特拉菲克 以此目的。 它还包括一个简单的服务负载均衡器,可以为集群中的服务获取外部 IP。 这 文件 像这样描述服务:

k3s 包含一个使用可用主机端口的基本服务负载均衡器。 如果您尝试创建一个侦听端口 80 的负载均衡器,对于 example,它将尝试在集群中为端口 80 查找空闲主机。如果没有可用的端口,负载均衡器将停留在 Pending 状态。

k3s 自述文件

入口控制器已使用此负载均衡器服务公开。 您可以使用以下命令找到它正在使用的 IP 地址。

$ kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.43.0.1 443/TCP 33d
default my-server ClusterIP 10.43.174.38 80/TCP 30m
kube-system kube-dns ClusterIP 10.43.0.10 53/UDP,53/TCP,9153/TCP 33d
kube-system traefik LoadBalancer 10.43.145.104 10.0.0.8 80:31596/TCP,443:31539/TCP 33d

查找名为 traefik 的服务。 在上述 example 我们感兴趣的IP是10.0.0.8。

路由传入请求

让我们创建一个 Ingress,根据主机标头将请求路由到我们的 Web 服务器。 这 example 用途 xip.io 以避免必须设置 DNS 记录。 它通过将 IP 地址包含为子域来工作,以使用 10.0.0.8.xip.io 的任何子域来访问 IP 10.0.0.8。 换句话说,my-server.10.0.0.8.xip.io 用于到达集群中的入口控制器。 您可以立即尝试(使用您自己的 IP 而不是 10.0.0.8)。 如果没有入口,您应该到达“默认后端”,它只是一个显示“404 页面未找到”的页面。

我们可以告诉入口控制器使用以下入口将请求路由到我们的 Web 服务器服务。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-server
spec:
rules:
- host: my-server.10.0.0.8.xip.io
https:
paths:
- path: /
backend:
serviceName: my-server
servicePort: 80

Save 上面的代码片段在名为 my-ingress.yaml 的文件中,并通过运行以下命令将其添加到集群中:

kubectl apply -f my-ingress.yaml

您现在应该能够访问您选择的完全限定域名上的默认 nginx 欢迎页面。 在我的 example 这将是 my-server.10.0.0.8.xip.io。 Ingress 控制器根据 Ingress 中的信息路由请求。 对 my-server.10.0.0.8.xip.io 的请求将被路由到 Ingress 中定义为后端的服务和端口(本例中为 my-server 和 80)。

那么物联网呢?

想象以下场景。 您的家或农场周围分布着数十台设备。 它是物联网设备的异构集合,具有各种硬件功能、传感器和执行器。 也许其中一些有摄像头、天气或光传感器。 其他人可能被连接来控制通风、灯光、百叶窗或闪烁的 LED。

在这种情况下,您希望从所有传感器收集数据,可能在最终使用它来做出决策和控制执行器之前对其进行处理和分析。 除此之外,您可能希望通过设置仪表板来可视化正在发生的事情。 那么Kubernetes如何帮助我们管理这样的事情呢? 我们如何确保 Pod 在合适的设备上运行?

简单的答案是标签。 您可以根据功能标记节点,如下所示:

kubectl label nodes <node-name> <label-key>=<label-value>
# Example
kubectl label nodes node2 camera=available

一旦它们被标记,就很容易为您的工作负载选择合适的节点 节点选择器. 拼图的最后一块,如果你想在所有合适的节点上运行你的 Pod 是使用 守护程序集 而不是部署。 换句话说,为每个使用某些独特传感器的数据收集应用程序创建一个 DaemonSet,并使用 nodeSelector 确保它们仅在具有适当硬件的节点上运行。

允许 Pod 简单地通过服务名称找到彼此的服务发现功能使得处理这些类型的分布式系统变得非常容易。 您无需知道或配置应用程序的 IP 地址或自定义端口。 相反,它们可以通过集群中的命名服务轻松找到彼此。

利用备用资源

随着集群启动并运行,收集数据并控制您的灯光和气候控制,您可能会觉得您已经完成了。 但是,集群中仍有大量计算资源可用于其他项目。 这就是 Kubernetes 真正闪耀的地方。

您不必担心这些资源的确切位置,也不必计算是否有足够的内存来容纳额外的应用程序。 这正是编排解决的问题! 您可以轻松地在集群中部署更多应用程序,并让 Kubernetes 确定它们适合的位置(或是否适合)。

为什么不自己运行 下一云 实例? 或许 吉蒂亚? 您还可以为所有这些 IoT 容器设置 CI/CD 管道。 毕竟,如果可以在集群中本地进行,为什么还要在主计算机上构建和交叉编译它们?

这里的重点是 Kubernetes 可以更轻松地利用您通常以其他方式结束的“隐藏”资源。 Kubernetes 根据可用资源和容错处理集群中 Pod 的调度,因此您不必这样做。 但是,为了帮助 Kubernetes 做出合理的决定,您绝对应该添加 资源请求 到您的工作量。

概括

虽然 Kubernetes 或一般的容器编排通常可能与物联网无关,但在处理分布式系统时拥有一个编排器肯定很有意义。 不仅允许您以统一的方式处理多样化和异构的设备群,而且还简化了它们之间的通信。 此外,Kubernetes 可以更轻松地利用备用资源。

容器技术使构建可以“在任何地方运行”的应用程序成为可能。 现在 Kubernetes 可以更轻松地管理“任何地方”部分。 作为构建这一切的不可变基础,我们有 Fedora 物联网。