ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

k3s试用

k3s试用 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 firewalldsudo systemctl disable firewalld2.3 安装依赖包sudo pacman -S socat conntrack-tools iptables2.4 确保主机名是合法的 DNS 格式不能是 localhost 或含下划线可以用cat /etc/hostname查看或用 hostnamectl 命令查看2.5 在线安装首先配置镜像源sudo mkdir -p /etc/rancher/k3ssudo 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然后安装k3scurl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh |INSTALL_K3S_MIRRORcnINSTALL_K3S_EXEC“–write-kubeconfig-mode 644”sh -网速很慢耐心等待安装好之后是这样的$ k3s -v k3s version v1.36.4k3s1 (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 Controllerlocal-path-provisioner 本地存储控制器当你创建 PVC 时自动在节点本地分配存储卷metrics-server 集群资源指标采集器kubectl top 命令的数据来源traefik Ingress ControllerHTTP/HTTPS 反向代理负责将外部流量路由到集群内的服务svclb-traefik K3s 内置的 Service Load BalancerKlipper-lb为 Traefik 提供 LoadBalancer 类型的 Service2.6 可以禁用一些不重要的组件编辑 K3s 配置禁用 traefik 和 metrics-serversudo 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) 19h2.7 k3s 、containerd装在哪里$ ls -lh /usr/local/bintotal 76Mlrwxrwxrwx 1 root root 3 Sep 6 23:58 crictl - k3slrwxrwxrwx 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.shlrwxrwxrwx 1 root root 3 Sep 6 23:58 kubectl - k3s可以看到这些软件都安装到/usr/local/bin目录了$ ls -l /var/lib/rancher/k3s/data/current/bin/containerdlrwxrwxrwx 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 BuildID6aycnyA_71ISj3_HJg7o/GpHAbw4ulNCCLvqe0SzK/2d5drffqdmr2MyNyq333/9XA--GyeOCo6NXKtBBnD, BuildID[sha1]4182bc65bce33c39f1b377bf54d95fc2fcda29ee, stripped2.8 启动一个pod并验证dns功能kubectl run dns-test --imagebusybox:1.36 --restartNever – sleep 3600kubectl exec -it dns-test – sh/bin # nslookup www.zzz.com.cnServer: 10.43.0.10Address: 10.43.0.10:53www.zzz.com.cn canonical name www.dtc.zzz.com.cnwww.zzz.com.cn canonical name www.dtc.zzz.com.cnName: www.dtc.zzz.com.cnAddress: 10.40.13.26/bin # nslookup kubernetesServer: 10.43.0.10Address: 10.43.0.10:53** server can’t find kubernetes.svc.cluster.local: NXDOMAINName: kubernetes.default.svc.cluster.localAddress: 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: NXDOMAIN2.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.268s3、离线安装k3s“笨办法”部署 K3s通常指的就是在目标节点没有网络连接或你希望完全掌控部署过程的离线部署Airgap Installation。这种方法“笨”在每一步都需要手动操作但能让你对集群的组成有最清晰的理解。核心思路很简单在有网的地方准备好所有“零件”然后搬到没网的服务器上“组装”起来。整个过程可以分为三步 第一步在有网的环境下准备“零件”你需要在一台能访问互联网的机器上准备好所有安装文件。获取核心文件从 K3s 的 GitHub Release 页面https://github.com/k3s-io/k3s/releases下载与你想安装版本对应的两个文件 K3s 二进制文件(k3s)这是 K3s 本身的可执行程序。离线镜像压缩包(k3s-airgap-images-amd64.tar.gz)这个文件包含了运行 K3s 所需的所有容器镜像。注意根据你服务器的 CPU 架构如amd64,arm64选择正确的版本 。获取安装脚本下载官方的安装脚本install.sh。你可以通过以下命令在本地保存一份 curl-sfLhttps://get.k3s.io-oinstall.sh如果你在中国大陆可以使用国内镜像源以获得更快的下载速度 curl-sfLhttps://rancher-mirror.rancher.cn/k3s/k3s-install.sh-oinstall.sh打包传输将下载好的k3s二进制文件、k3s-airgap-images-amd64.tar.gz和install.sh脚本通过 U 盘、SCP 命令或其他任何方式一并复制到你的离线目标服务器上。 第二步在离线服务器上“组装”安装登录到你的离线服务器开始进行手动配置。安置二进制文件将k3s二进制文件移动到系统的程序目录并赋予执行权限 sudocpk3s /usr/local/bin/sudochmodx /usr/local/bin/k3s导入容器镜像创建 K3s 专用的镜像目录然后将下载好的离线镜像包放进去 sudomkdir-p/var/lib/rancher/k3s/agent/images/sudocp./k3s-airgap-images-*.tar /var/lib/rancher/k3s/agent/images/运行安装脚本执行安装脚本但需要使用INSTALL_K3S_SKIP_DOWNLOADtrue这个关键参数告诉脚本“不要从网上下载任何东西就用当前目录下我准备好的文件” 。安装 Server 节点控制平面sudoINSTALL_K3S_SKIP_DOWNLOADtrue ./install.sh安装成功后你可以看到节点的状态信息。节点的 Token 位于/var/lib/rancher/k3s/server/node-token这个稍后添加 Agent 节点时会用到 。安装 Agent 节点工作节点在其他的工作节点上同样执行前两步放置二进制和镜像然后使用 Server 节点的地址和 Token 进行注册 # 将 SERVER_IP 替换为你的Server节点IPYOUR_TOKEN 替换为实际的Token值sudoINSTALL_K3S_SKIP_DOWNLOADtrueK3S_URLhttps://SERVER_IP:6443K3S_TOKENYOUR_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/dataimages下面是离线镜像。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 686kB2026-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 defaultlink/ether 56:9f:e8:6f:ba:23 brd ff:ff:ff:ff:ff:ffinet 10.42.0.0/32 scope global flannel.1valid_lft forever preferred_lft foreverinet6 fe80::549f:e8ff:fe6f:ba23/64 scope linkvalid_lft forever preferred_lft forever5: cni0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1450 qdisc noqueue state UP group default qlen 1000link/ether 2a:aa:cc:e4:d7:47 brd ff:ff:ff:ff:ff:ffinet 10.42.0.1/24 brd 10.42.0.255 scope global cni0valid_lft forever preferred_lft foreverinet6 fe80::28aa:ccff:fee4:d747/64 scope linkvalid_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)在另一台节点Pod A发送数据包 -cni0本节点网桥发现目标不在本子网。cni0根据路由表将数据包转发给flannel.1隧道接口。flannel.1将数据包封装成 VXLAN 包通过物理网卡发送到另一台节点。另一台节点的flannel.1收到并解封装。另一台节点的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 集群的全网互通。
返回列表