☰
k3s试用
2026/10/7 9:56:58 网站建设 项目流程

1、k3s有离线安装和在线安装

2、我是在qenu虚拟机(无kvm)的archlinux操作系统中安装k3s的。用的是在线安装。

2.1 首先确保https://rancher-mirror.rancher.cn/k3s/k3s-install.sh这个网址可以访问,否则要先解决网络问题。
2.2 其次确认防火墙和swap是否已经关闭了。
关闭swap sudo swapoff -a 检查swap是否开启, 可以用free 命令看 swap大小,也可以cat /etc/fstab 查看是否挂载swap分区。 k8s要求关闭swap,主要是怕swap导致k8s无法准确看到每个node的真实剩余内存,导致把pod调度到无剩余内存的node上。

关闭防火墙:生产环境建议保留防火墙,按需放行 6443、10250、8472 等端口。
sudo systemctl stop firewalld
sudo systemctl disable firewalld

2.3 安装依赖包

sudo pacman -S socat conntrack-tools iptables

2.4 确保主机名是合法的 DNS 格式(不能是 localhost 或含下划线),可以用cat /etc/hostname查看,或用 hostnamectl 命令查看
2.5 在线安装

首先配置镜像源
sudo mkdir -p /etc/rancher/k3s
sudo tee /etc/rancher/k3s/registries.yaml << ‘EOF’
mirrors:
docker.io:
endpoint:
- “https://dockerpull.org”
- “https://docker.1panel.live”
- “https://dockerproxy.com”
- “https://docker.unsee.tech”
EOF

然后安装k3s
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh |
INSTALL_K3S_MIRROR=cn
INSTALL_K3S_EXEC=“–write-kubeconfig-mode 644”
sh -

网速很慢,耐心等待,安装好之后是这样的

$ k3s -v k3s version v1.36.4+k3s1 (4dedb15b) go version go1.26.7 $ kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-54996dc9b4-5vd8f 1/1 Running 4 (20m ago) 8h kube-system helm-install-traefik-crd-nxfxp 0/1 Completed 0 35m kube-system helm-install-traefik-h4dk4 0/1 Completed 7 (32m ago) 8h kube-system local-path-provisioner-77b9867795-nsczj 1/1 Running 0 8h kube-system metrics-server-6dc596dfb8-pcsrw 1/1 Running 8 (20m ago) 8h kube-system svclb-traefik-95fc0daf-lrxqd 2/2 Running 0 26m kube-system traefik-59b7647586-62lcb 1/1 Running 0 26m

这些组件的功能是:
coredns 集群内部 DNS 服务,让 Pod 之间可以通过服务名互相访问
helm-install-traefik-crd Helm Job,负责安装 Traefik 所需的 CRD(自定义资源定义)
helm-install-traefik Helm Job,负责通过 Helm 部署 Traefik Ingress Controller
local-path-provisioner 本地存储控制器,当你创建 PVC 时自动在节点本地分配存储卷
metrics-server 集群资源指标采集器,kubectl top 命令的数据来源
traefik Ingress Controller,HTTP/HTTPS 反向代理,负责将外部流量路由到集群内的服务
svclb-traefik K3s 内置的 Service Load Balancer(Klipper-lb),为 Traefik 提供 LoadBalancer 类型的 Service

2.6 可以禁用一些不重要的组件

编辑 K3s 配置,禁用 traefik 和 metrics-server

sudo tee /etc/rancher/k3s/config.yaml << 'EOF' disable: - traefik - metrics-server EOF sudo systemctl restart k3s $ kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE coredns-54996dc9b4-5vd8f 1/1 Running 8 (10h ago) 19h local-path-provisioner-77b9867795-nsczj 1/1 Running 1 (10h ago) 19h
2.7 k3s 、containerd装在哪里

$ ls -lh /usr/local/bin
total 76M
lrwxrwxrwx 1 root root 3 Sep 6 23:58 crictl -> k3s
lrwxrwxrwx 1 root root 3 Sep 6 23:58 ctr -> k3s
-rwxr-xr-x 1 root root 76M Sep 6 23:58 k3s
-rwxr-xr-x 1 root root 2.3K Sep 6 23:58 k3s-killall.sh
-rwxr-xr-x 1 root root 2.0K Sep 6 23:58 k3s-uninstall.sh
lrwxrwxrwx 1 root root 3 Sep 6 23:58 kubectl -> k3s
可以看到这些软件都安装到/usr/local/bin目录了

$ ls -l /var/lib/rancher/k3s/data/current/bin/containerd
lrwxrwxrwx 1 root root 3 Sep 6 23:59 /var/lib/rancher/k3s/data/current/bin/containerd -> k3s
可以看到containerd被编译到k3s中了,就像busybox一样,一个软件包含了很多个软件的功能

另外,k3s进程中还把Flannel (CNI)编译进去了,用以支持Pod 网络,给每个 Pod 分配 IP,实现 Pod 间通信

** 最后,看一下k3s这个文件,可以看到k3s是一个静态编译的可执行文件,不依赖其它so文件 **

$ ldd /usr/local/bin/k3s not a dynamic executable $ file /usr/local/bin/k3s /usr/local/bin/k3s: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=6aycnyA_71ISj3_HJg7o/GpHAbw4ulNCCLvqe0SzK/2d5drffqdmr2MyNyq333/9XA--GyeOCo6NXKtBBnD, BuildID[sha1]=4182bc65bce33c39f1b377bf54d95fc2fcda29ee, stripped
2.8 启动一个pod,并验证dns功能

kubectl run dns-test --image=busybox:1.36 --restart=Never – sleep 3600
kubectl exec -it dns-test – sh

/bin # nslookup www.zzz.com.cn
Server: 10.43.0.10
Address: 10.43.0.10:53

www.zzz.com.cn canonical name = www.dtc.zzz.com.cn

www.zzz.com.cn canonical name = www.dtc.zzz.com.cn
Name: www.dtc.zzz.com.cn
Address: 10.40.13.26

/bin # nslookup kubernetes
Server: 10.43.0.10
Address: 10.43.0.10:53

** server can’t find kubernetes.svc.cluster.local: NXDOMAIN

Name: kubernetes.default.svc.cluster.local
Address: 10.43.0.1

** server can’t find kubernetes.cluster.local: NXDOMAIN

** server can’t find kubernetes.svc.cluster.local: NXDOMAIN

** server can’t find kubernetes.cluster.local: NXDOMAIN

2.9 kubectl命令很慢,因为qenu是纯指令模拟,tls握手很慢
$ time kubectl get pod NAME READY STATUS RESTARTS AGE dns-test 1/1 Running 0 42s real 0m2.433s user 0m2.265s sys 0m0.879s # 使用kube proxy 跳过tls的测试 $ kubectl proxy & $ time curl -s http://localhost:8001/api/v1/pods | head -n 20 { "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion": "29486" }, "items": [ { "metadata": { "name": "dns-test", "namespace": "default", "uid": "135ef2b7-590d-4db8-a98b-4bb3b058732c", "resourceVersion": "29366", "generation": 1, "creationTimestamp": "2026-09-07T10:46:24Z", "labels": { "run": "dns-test" }, "managedFields": [ { real 0m0.662s user 0m0.307s sys 0m0.172s

另外,查看镜像

$ time sudo crictl images IMAGE TAG IMAGE ID SIZE docker.io/library/busybox 1.36 b116e15507444 2.22MB docker.io/rancher/klipper-helm v0.13.3-build20260727 8e0d8d2218ec8 74.2MB docker.io/rancher/klipper-lb v0.4.17 eaa1212a2b456 5.28MB docker.io/rancher/local-path-provisioner v0.0.37 683316f41426e 15.1MB docker.io/rancher/mirrored-coredns-coredns 1.14.6 520212b8b0fcd 23.8MB docker.io/rancher/mirrored-library-traefik 3.7.8 7a652b1846f78 54.5MB docker.io/rancher/mirrored-metrics-server v0.9.0 d7b01abacd67f 23.3MB docker.io/rancher/mirrored-pause 3.10.2 4a83b15d3ecfe 321kB real 0m3.558s user 0m0.439s sys 0m0.268s

3、离线安装k3s

“笨办法”部署 K3s,通常指的就是在目标节点没有网络连接,或你希望完全掌控部署过程的离线部署(Airgap Installation)。这种方法“笨”在每一步都需要手动操作,但能让你对集群的组成有最清晰的理解。

核心思路很简单:在有网的地方准备好所有“零件”,然后搬到没网的服务器上“组装”起来。整个过程可以分为三步:

📦 第一步:在有网的环境下准备“零件”

你需要在一台能访问互联网的机器上,准备好所有安装文件。

  1. 获取核心文件:从 K3s 的 GitHub Release 页面(https://github.com/k3s-io/k3s/releases)下载与你想安装版本对应的两个文件 :
    • K3s 二进制文件(k3s):这是 K3s 本身的可执行程序。
    • 离线镜像压缩包(k3s-airgap-images-amd64.tar.gz):这个文件包含了运行 K3s 所需的所有容器镜像。注意根据你服务器的 CPU 架构(如amd64,arm64)选择正确的版本 。
  2. 获取安装脚本:下载官方的安装脚本install.sh。你可以通过以下命令在本地保存一份 :
    curl-sfLhttps://get.k3s.io-oinstall.sh
    如果你在中国大陆,可以使用国内镜像源以获得更快的下载速度 :
    curl-sfLhttps://rancher-mirror.rancher.cn/k3s/k3s-install.sh-oinstall.sh
  3. 打包传输:将下载好的k3s二进制文件、k3s-airgap-images-amd64.tar.gz和install.sh脚本通过 U 盘、SCP 命令或其他任何方式,一并复制到你的离线目标服务器上。

🚀 第二步:在离线服务器上“组装”安装

登录到你的离线服务器,开始进行手动配置。

  1. 安置二进制文件:
    • 将k3s二进制文件移动到系统的程序目录,并赋予执行权限 :
      sudocpk3s /usr/local/bin/sudochmod+x /usr/local/bin/k3s
  2. 导入容器镜像:
    • 创建 K3s 专用的镜像目录,然后将下载好的离线镜像包放进去 :
      sudomkdir-p/var/lib/rancher/k3s/agent/images/sudocp./k3s-airgap-images-*.tar /var/lib/rancher/k3s/agent/images/
  3. 运行安装脚本:
    • 执行安装脚本,但需要使用INSTALL_K3S_SKIP_DOWNLOAD=true这个关键参数,告诉脚本“不要从网上下载任何东西,就用当前目录下我准备好的文件” 。
    • 安装 Server 节点(控制平面):
      sudoINSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
      安装成功后,你可以看到节点的状态信息。节点的 Token 位于/var/lib/rancher/k3s/server/node-token,这个稍后添加 Agent 节点时会用到 。
    • 安装 Agent 节点(工作节点):
      在其他的工作节点上,同样执行前两步(放置二进制和镜像),然后使用 Server 节点的地址和 Token 进行注册 :
      # 将 <SERVER_IP> 替换为你的Server节点IP,<YOUR_TOKEN> 替换为实际的Token值sudoINSTALL_K3S_SKIP_DOWNLOAD=trueK3S_URL=https://<SERVER_IP>:6443K3S_TOKEN=<YOUR_TOKEN>./install.sh

✅ 第三步:验证安装结果

在所有节点上安装完成后,回到你的Server 节点,执行以下命令来查看集群状态 :

kubectl get nodes

如果一切顺利,你会看到所有节点都处于Ready状态,一个属于你的离线 K3s 集群就部署成功了。

💡 一些补充的“笨”办法

  • 使用配置文件:如果想指定更多参数(如 Pod 网段、禁用默认的 Traefik 等),可以提前在/etc/rancher/k3s/config.yaml创建配置文件,然后再运行安装脚本 。
  • 使用私有镜像仓库:如果节点很多,手动在每个节点导入镜像会比较繁琐。更高效的方法是搭建一个私有的镜像仓库,将镜像推送到仓库中,然后配置 K3s 从该私有仓库拉取镜像 。
  • 升级也是“笨”办法:日后需要升级时,重复一遍上面的步骤即可:下载新版本的二进制和镜像包,替换旧文件,重新运行安装脚本,最后重启 K3s 服务 。

2026-9-18
离线方式安装了k3s,但启动后会自动重启。AI定位是本机cgroup是v1,新版k3s需要cgroup v2.
于是重新下载了1.28.15老版本,然后就正常了。

k3s装在这个目录下,有3个子目录

$sudodu-h/var/lib/rancher/k3s-d11.6G /var/lib/rancher/k3s/agent 195M /var/lib/rancher/k3s/data 11M /var/lib/rancher/k3s/server1.8G /var/lib/rancher/k3s $sudodu-h/var/lib/rancher/k3s/server-d18.0K /var/lib/rancher/k3s/server/etc 184K /var/lib/rancher/k3s/server/tls 32K /var/lib/rancher/k3s/server/cred9.9M /var/lib/rancher/k3s/server/db 120K /var/lib/rancher/k3s/server/static 56K /var/lib/rancher/k3s/server/manifests 11M /var/lib/rancher/k3s/server $sudodu-h/var/lib/rancher/k3s/data-d10/var/lib/rancher/k3s/data/cni 195M var/lib/rancher/k3s/data/ef4db44d834f98f27bc2d7cf944dcac51055966a52fe848f16ba44caa1202f89 195M /var/lib/rancher/k3s/data

images下面是离线镜像。containerd下放了一份镜像(520M),一份容器运行时的分层文件系统,这个系统中的只读层就是镜像内容(520M)

$sudodu-h/var/lib/rancher/k3s/agent/-d1520M /var/lib/rancher/k3s/agent/images1.1G /var/lib/rancher/k3s/agent/containerd 16K /var/lib/rancher/k3s/agent/etc0/var/lib/rancher/k3s/agent/pod-manifests1.6G /var/lib/rancher/k3s/agent/

拷贝了一个alpine.3.20.1.f10.tar镜像
用$ sudo ctr -n k8s.io images import alpine.3.20.1.f10.tar 导入,结果在ctr命令中能看到,在crictl命令中看不到

AI说k3s中,应该用这个命令重新导入,果然好使

$sudoctr--address/run/k3s/containerd/containerd.sock-nk8s.io imagesimportalpine.3.20.1.f10.tar $sudocrictl images IMAGE TAG IMAGE ID SIZE docker.io/library/alpine3.20.1.f10 177956ee946768.09MB docker.io/rancher/klipper-helm v0.9.3-build20241008 4e0aed78b287d 191MB docker.io/rancher/klipper-lb v0.4.9 11a5d8a9f31aa12.7MB docker.io/rancher/local-path-provisioner v0.0.30 b580d47bc23dd 52MB docker.io/rancher/mirrored-coredns-coredns1.11.3 c69fa2e9cbf5f63.3MB docker.io/rancher/mirrored-library-busybox1.36.1 6fd955f66c2314.5MB docker.io/rancher/mirrored-library-traefik2.11.10 1741c0b1ff49b 169MB docker.io/rancher/mirrored-metrics-server v0.7.2 48d9cfaaf390468.1MB docker.io/rancher/mirrored-pause3.66270bb605e12e 686kB

2026-10-6
想下载一个pmail镜像,要改/etc/rancher/k3s/registries.yaml,增加下的内容,并重启k3s。 注意yaml格式必须正确,否则k3s启动后不太正常,比如kubectl get node 返回节点no ready。
ghcr.io:
endpoint:
- “https://ghcr.m.daocloud.io” # DaoCloud 镜像站,通常对 ghcr.io 支持较好
- “https://ghcr.io” # 原始地址作为备选

然后就可以下载成功了。k3s ctr images pull ghcr.io/jinnrry/pmail:latest

经验2 在root账号下,crictl images 命令可以查看到镜像。但ctr imagesls就查不到任何镜像。 K3s 使用独立的 containerd 实例,其 socket 文件路径通常为 /run/k3s/containerd/containerd.sock,而系统原生的 ctr 默认连接的是 /run/containerd/containerd.sock。因此,直接运行 ctr 可能会报错“failed to connect”或连接到一个空的/不同的 containerd 实例。 解决方案1、使用 K3s 内置的 ctr(推荐) K3s 提供了一个封装好的 k3s ctr 命令,它已经自动配置好了正确的 socket 路径和默认命名空间(通常默认为 k8s.io,但显式指定更稳妥)。 解决方案2、使用原生 ctr 并指定 Socket ctr--address/run/k3s/containerd/containerd.sock-nk8s.io imagesls用方案1试了一下,果然好使(base)Desktop$ k3s ctr imagesls|wc211467287(base)Desktop$ k3s ctr-nk8s.io imagesls|wc211467287

编写一个pod.yaml文件

$catpod.yaml apiVersion: v1 kind: Pod metadata: name: my-alpine spec: containers: - name: alpine image: docker.io/library/alpine:3.20.1.f10 command:["sh","-c","echo 'Hello from Alpine!' && sleep infinity"]imagePullPolicy: Never $ kubectl apply-fpod.yaml pod/my-alpine created $ kubectl get pod NAME READY STATUS RESTARTS AGE my-alpine1/1 Running08s $ kubectlexec-itmy-alpinesh

进入容器后,可以ping通外部网站

从节点上也可以ping通容器 ping 10.42.0.11

再看k3s创建的虚拟网络
4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default
link/ether 56:9f:e8:6f:ba:23 brd ff:ff:ff:ff:ff:ff
inet 10.42.0.0/32 scope global flannel.1
valid_lft forever preferred_lft forever
inet6 fe80::549f:e8ff:fe6f:ba23/64 scope link
valid_lft forever preferred_lft forever
5: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default qlen 1000
link/ether 2a:aa:cc:e4:d7:47 brd ff:ff:ff:ff:ff:ff
inet 10.42.0.1/24 brd 10.42.0.255 scope global cni0
valid_lft forever preferred_lft forever
inet6 fe80::28aa:ccff:fee4:d747/64 scope link
valid_lft forever preferred_lft forever

这两个接口都是Flannel CNI 插件创建的,但它们的角色完全不同:

1.flannel.1——Overlay 隧道接口(虚拟网卡)

  • 类型:VXLAN隧道接口(虽然这里显示为BROADCAST,MULTICAST,但本质是 Flannel 的 VXLAN 设备)。
  • IP 地址:10.42.0.0/32。注意这个 IP 是/32掩码,它不是给容器用的网关,而是本节点在 Overlay 网络中的唯一标识。
  • 作用:负责跨节点通信。当 Pod A(在节点 1)需要访问 Pod B(在节点 2)时,数据包会被封装在 VXLAN 包中,通过flannel.1发送到对端节点的flannel.1接口。
  • 简单理解:它是节点之间的“高速公路”,用于在不同物理机之间传输 Pod 流量。

2.cni0——本地网桥接口(虚拟交换机)

  • 类型:Linux Bridge(网桥)。
  • IP 地址:10.42.0.1/24。这是本节点上所有 Pod 的默认网关。
  • 作用:负责本节点内部通信。
    • 当 Pod 启动时,它的虚拟网卡(veth pair 的一端)会连接到cni0网桥上。
    • 如果 Pod 要访问同一节点上的其他 Pod,流量直接通过cni0转发,不经过flannel.1。
    • 如果 Pod 要访问外部网络或其他节点,流量先到达cni0,然后通过路由表转发到flannel.1(或其他出口)。
  • 简单理解:它是本节点内部的“局域网交换机”,连接着该节点上所有的 Pod。

数据流向示例

假设Pod A (10.42.0.5)在当前节点,想访问Pod B (10.42.1.5)在另一台节点:

  1. Pod A发送数据包 ->cni0(本节点网桥,发现目标不在本子网)。
  2. cni0根据路由表将数据包转发给flannel.1(隧道接口)。
  3. flannel.1将数据包封装成 VXLAN 包,通过物理网卡发送到另一台节点。
  4. 另一台节点的flannel.1收到并解封装。
  5. 另一台节点的cni0将数据包转发给Pod B。

总结对比

特性flannel.1cni0
类型VXLAN 隧道设备Linux Bridge (网桥)
IP 地址10.42.0.0/32(节点标识)10.42.0.1/24(Pod 网关)
主要功能跨节点通信(Overlay 隧道)本节点内通信(Pod 互联)
连接对象其他节点的flannel.1本节点所有 Pod 的 veth 网卡
类比城市间的高速公路小区内的内部道路

一句话总结:cni0管的是本节点内的 Pod 互联,flannel.1管的是跨节点的 Pod 互联。两者配合实现了 Kubernetes 集群的全网互通。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询