以独立模式运行 Kubelet

本教程向你展示如何运行一个独立的 kubelet 实例。

运行独立 kubelet 的动机可能有很多。本教程旨在向你介绍 Kubernetes,即使你对此没有太多经验。你可以按照本教程学习节点设置、基本(静态)Pod 以及 Kubernetes 如何管理容器。

完成本教程后,你可以尝试使用一个具有控制平面的集群来管理 Pod 和节点,以及其他类型的对象。例如,Hello, minikube

你也可以以独立模式运行 kubelet,以适应生产用例,例如为高可用、弹性部署的集群运行控制平面。本教程不涵盖运行弹性控制平面所需的详细信息。

目标

  • 在 Linux 系统上安装 `cri-o` 和 `kubelet`,并将它们作为 `systemd` 服务运行。
  • 启动一个运行 `nginx` 的 Pod,该 Pod 监听 Pod IP 地址上的 TCP 端口 80 请求。
  • 了解解决方案的不同组件之间如何交互。

准备工作

  • 管理 Linux 系统(使用 `systemd` 和 `iptables`(或使用 `iptables` 模拟的 nftables))的 `root` 权限。
  • 访问互联网以下载本教程所需的组件,例如:

准备系统

Swap 配置

默认情况下,如果节点上检测到交换内存,kubelet 将无法启动。这意味着应该禁用交换或由 kubelet 容忍。

如果启用了交换内存,请禁用它或将 `failSwapOn: false` 添加到 kubelet 配置文件中。

检查是否启用了交换

sudo swapon --show

如果该命令没有输出,则交换内存已被禁用。

临时禁用交换

sudo swapoff -a

使此更改在重启后仍然有效

确保在 `/etc/fstab` 或 `systemd.swap` 中禁用交换,具体取决于系统上的配置方式。

启用 IPv4 数据包转发

检查是否启用了 IPv4 数据包转发

cat /proc/sys/net/ipv4/ip_forward

如果输出为 `1`,则已启用。如果输出为 `0`,则按照以下步骤操作。

要启用 IPv4 数据包转发,请创建一个配置文件,将 `net.ipv4.ip_forward` 参数设置为 `1`

sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
EOF

应用更改到系统

sudo sysctl --system

输出类似于:

...
* Applying /etc/sysctl.d/k8s.conf ...
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.conf ...

下载、安装和配置组件

安装容器运行时

下载所需软件包的最新可用版本(推荐)。

本教程建议安装 CRI-O 容器运行时(外部链接)。

CRI-O 容器运行时有多种安装方式,具体取决于你使用的 Linux 发行版。虽然 CRI-O 建议使用 `deb` 或 `rpm` 软件包,但本教程使用 CRI-O Packaging project 的*静态二进制包*脚本,以简化整个过程并保持与发行版无关。

该脚本安装并配置其他所需的软件,例如用于容器网络的 `cni-plugins`,以及用于运行容器的 `crun``runc`

该脚本将自动检测你的系统处理器架构(`amd64` 或 `arm64`)并选择安装最新版本的软件包。

设置 CRI-O

访问 releases 页面(外部链接)。

下载静态二进制包脚本

curl https://raw.githubusercontent.com/cri-o/packaging/main/get > crio-install

运行安装脚本

sudo bash crio-install

启用并启动 `crio` 服务

sudo systemctl daemon-reload
sudo systemctl enable --now crio.service

快速测试

sudo systemctl is-active crio.service

输出类似于:

active

详细服务检查

sudo journalctl -f -u crio.service

安装网络插件

`cri-o` 安装程序会安装并配置 `cni-plugins` 软件包。你可以运行以下命令验证安装:

/opt/cni/bin/bridge --version

输出类似于:

CNI bridge plugin v1.5.1
CNI protocol versions supported: 0.1.0, 0.2.0, 0.3.0, 0.3.1, 0.4.0, 1.0.0

检查默认配置

cat /etc/cni/net.d/11-crio-ipv4-bridge.conflist

输出类似于:

{
  "cniVersion": "1.0.0",
  "name": "crio",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "cni0",
      "isGateway": true,
      "ipMasq": true,
      "hairpinMode": true,
      "ipam": {
        "type": "host-local",
        "routes": [
            { "dst": "0.0.0.0/0" }
        ],
        "ranges": [
            [{ "subnet": "10.85.0.0/16" }]
        ]
      }
    }
  ]
}

下载并设置 kubelet

下载 kubelet 的最新稳定版本


curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubelet"


curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubelet"

配置

sudo mkdir -p /etc/kubernetes/manifests
sudo tee /etc/kubernetes/kubelet.yaml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  webhook:
    enabled: false # Do NOT use in production clusters!
authorization:
  mode: AlwaysAllow # Do NOT use in production clusters!
enableServer: false
logging:
  format: text
address: 127.0.0.1 # Restrict access to localhost
readOnlyPort: 10255 # Do NOT use in production clusters!
staticPodPath: /etc/kubernetes/manifests
containerRuntimeEndpoint: unix:///var/run/crio/crio.sock
EOF

安装

chmod +x kubelet
sudo cp kubelet /usr/bin/

创建 `systemd` 服务单元文件

sudo tee /etc/systemd/system/kubelet.service <<EOF
[Unit]
Description=Kubelet

[Service]
ExecStart=/usr/bin/kubelet \
 --config=/etc/kubernetes/kubelet.yaml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

在服务配置文件中故意省略了命令行参数 `--kubeconfig`。该参数设置了指向kubeconfig文件的路径,该文件指定了如何连接到 API 服务器,从而启用 API 服务器模式。省略它会启用独立模式。

启用并启动 `kubelet` 服务

sudo systemctl daemon-reload
sudo systemctl enable --now kubelet.service

快速测试

sudo systemctl is-active kubelet.service

输出类似于:

active

详细服务检查

sudo journalctl -u kubelet.service

检查 kubelet 的 API `/healthz` 端点

curl https://:10255/healthz?verbose

输出类似于:

[+]ping ok
[+]log ok
[+]syncloop ok
healthz check passed

查询 kubelet 的 API `/pods` 端点

curl https://:10255/pods | jq '.'

输出类似于:

{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {},
  "items": null
}

在 kubelet 中运行 Pod

在独立模式下,你可以使用 Pod manifest 运行 Pod。这些 manifest 可以位于本地文件系统上,也可以通过 HTTP 从配置源获取。

创建 Pod 的 manifest

cat <<EOF > static-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
EOF

将 `static-web.yaml` 清单文件复制到 `/etc/kubernetes/manifests` 目录。

sudo cp static-web.yaml /etc/kubernetes/manifests/

查找关于 kubelet 和 Pod 的信息

Pod 网络插件会创建一个网络桥接 (`cni0`) 和一对 `veth` 接口(其中一个在新建的 Pod 内部,另一个在主机层面)。

查询 kubelet 的 API 端点 `https://:10255/pods`

curl https://:10255/pods | jq '.'

获取 `static-web` Pod 的 IP 地址

curl https://:10255/pods | jq '.items[].status.podIP'

输出类似于:

"10.85.0.4"

连接到 `nginx` 服务器 Pod(地址为 `http://:`,端口 80 是默认值),在本例中

curl http://10.85.0.4

输出类似于:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

在哪里查找更多细节

如果你需要诊断此教程在运行时遇到的问题,可以在以下目录中查找监控和故障排除信息:

/var/lib/cni
/var/lib/containers
/var/lib/kubelet

/var/log/containers
/var/log/pods

清理

kubelet

sudo systemctl disable --now kubelet.service
sudo systemctl daemon-reload
sudo rm /etc/systemd/system/kubelet.service
sudo rm /usr/bin/kubelet
sudo rm -rf /etc/kubernetes
sudo rm -rf /var/lib/kubelet
sudo rm -rf /var/log/containers
sudo rm -rf /var/log/pods

容器运行时

sudo systemctl disable --now crio.service
sudo systemctl daemon-reload
sudo rm -rf /usr/local/bin
sudo rm -rf /usr/local/lib
sudo rm -rf /usr/local/share
sudo rm -rf /usr/libexec/crio
sudo rm -rf /etc/crio
sudo rm -rf /etc/containers

网络插件

sudo rm -rf /opt/cni
sudo rm -rf /etc/cni
sudo rm -rf /var/lib/cni

总结

此页面涵盖了在独立模式下部署 kubelet 的基本方面。现在你可以部署 Pod 并测试其他功能。

请注意,在独立模式下,kubelet **不**支持从控制平面获取 Pod 配置(因为没有控制平面连接)。

你也不能使用 ConfigMapSecret 来配置静态 Pod 中的容器。

下一步

  • 按照Hello, minikube了解如何运行带有控制平面的 Kubernetes。minikube 工具可帮助你在自己的计算机上设置一个实践集群。
  • 了解更多关于网络插件的信息
  • 了解更多关于容器运行时的信息
  • 了解更多关于kubelet的信息
  • 了解更多关于静态 Pod 的信息

本页上的项目指的是提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅 CNCF 网站指南

在提议添加额外第三方链接的更改之前,你应该阅读内容指南

上次修改时间:2024 年 11 月 06 日太平洋标准时间下午 5:33: 修复 kubelet-standalone.md 中的项目符号缩进和拼写错误 (a7c9e0bbc9)