Debian12上使用K3s部署Kubernetes集群
本文最后更新于 2026年7月10日 上午
什么是 K3s?
K3s 是一个完全兼容的 Kubernetes 发行版,具有以下增强功能:
打包为单个二进制文件。
使用基于 sqlite3 作为默认存储机制的轻量级存储后端。同时支持使用 etcd3、MySQL 和 Postgres。
封装在简单的启动程序中,可以处理很多复杂的 TLS 和选项。
默认情况下是安全的,对轻量级环境有合理的默认值。
添加了简单但强大的
1
batteries-included功能,例如:
- 本地存储提供程序
- service load balancer
- Helm controller
- Traefik ingress controller
所有 Kubernetes control plane 组件的操作都封装在单个二进制文件和进程中。因此,K3s 支持自动化和管理复杂的集群操作(例如证书分发等)。
最大程度减轻了外部依赖性,K3s 仅需要现代内核和 cgroup 挂载。K3s 打包了所需的依赖,包括:
- containerd
- Flannel (CNI)
- CoreDNS
- Traefik (Ingress)
- Klipper-lb (Service LB)
- 嵌入式网络策略控制器
- 嵌入式 local-path-provisioner
- 主机实用程序(iptables、socat 等)
官方网站 :https://k3s.io/
官方文档:
https://docs.rancher.cn/docs/k3s/
环境说明
本文使用 Debian 部署一个 K3s 双节点 Kubernetes 集群。
节点规划
| 主机名 | IP | 角色 |
|---|---|---|
| master | 192.168.10.102 | K3s Server(Master) |
| node0 | 192.168.10.103 | K3s Agent |
请根据自己的实际 IP 修改。
系统要求:
- Debian 12 x64
- CPU:1 Core+
- 内存:最低 512MB(建议 1GB+)
- 两台服务器网络互通,开放 6443 端口
- root 用户或 sudo 权限
1. 准备工作(两台主机均需执行)
在开始之前,确保两台机器可以互相通信,并且防火墙允许必要的流量。
更新系统:
1
sudo apt update && sudo apt upgrade -y安装基础工具
1
apt install -y curl wget vim git net-tools iproute2 ca-certificates停止并禁用防火墙
1 | |
确认主机名: 建议分别设置主机名为
master和node0方便识别。1
2sudo hostnamectl set-hostname master # 在102上执行
sudo hostnamectl set-hostname node0 # 在103上执行
2. 部署 Master 节点 (192.168.10.102)
在 Master 节点上,我们将运行安装脚本并将其配置为集群的主控节点。
执行安装命令:
1
2
3
4
5curl -sfL https://get.k3s.io | sh -
# 中国用户,可以使用以下方法加速安装:
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -获取 Node Token: 安装完成后,你需要获取一个“令牌”,用于将 Node0 加入集群。
1
sudo cat /var/lib/rancher/k3s/server/node-token复制保存这个字符串,稍后在 Node0 上会用到。
检查状态:
1
sudo kubectl get nodes此时你应该能看到
master节点处于Ready状态。
3. 部署 Node 节点 (192.168.10.103)
现在切换到 Node0 主机,将其作为工作节点连接到 Master。
执行安装命令: 请将下方命令中的
<MASTER_TOKEN>替换为你刚才在 Master 上获取的字符串。1
2
3
4
5
6
7curl -sfL https://get.k3s.io | K3S_URL=https://192.168.10.102:6443 \
K3S_TOKEN=<MASTER_TOKEN> sh -
# 中国用户,可以使用以下方法加速安装:
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | K3S_URL=https://192.168.10.102:6443 \
K3S_TOKEN=<MASTER_TOKEN> sh -
4. 验证集群状态
回到 Master 节点,运行以下命令验证 Node0 是否已成功加入:
1 | |
预期输出:
1 | |
配置国内镜像
Master节点
创建或编辑配置文件:
1 | |
填入
1 | |
重启K3s
1 | |
Node节点
1 | |
配置完成
1 | |
如何卸载K3s
如果需要重新开始:
- Master:
sudo /usr/local/bin/k3s-uninstall.sh - Node:
sudo /usr/local/bin/k3s-agent-uninstall.sh
部署 Nginx 验证集群
我们创建一个简单的 Nginx 服务
在 Master 节点上创建配置文件:
1
nano nginx-demo.yaml粘贴以下内容:
1 | |
注释
1 | |
应用配置:
1
sudo kubectl apply -f nginx-demo.yaml验证:
查看 Pod 和 Service:
1 | |
输出示例:
1 | |
此时 Nginx 已经在集群内部可用
服务访问
ClusterIP 只能在 Kubernetes 集群内部访问,局域网电脑和互联网都无法直接访问。
如果想在局域网或者绑定域名访问,有几种方案。
方案一:NodePort(最简单,适合局域网)
把 Service 改成:
1 | |
部署
1 | |
查看
1 | |
例如输出
1 | |
然后局域网即可访问
1 | |
这里
1 | |
就是 Kubernetes Node 的 IP。
方案二:LoadBalancer(云服务器推荐)
如果你是:
- 阿里云 ACK
- 腾讯云 TKE
- 华为云 CCE
- AWS EKS
- Azure AKS
改成
1 | |
例如
1 | |
然后
1 | |
会看到
1 | |
直接访问
1 | |
即可。
方案三:Ingress(推荐绑定域名)
生产环境几乎都用 Ingress。
安装 Ingress Controller,例如:
- NGINX Ingress Controller
- Traefik
- HAProxy
- Kong
例如安装 NGINX Ingress。
创建 Ingress:
1 | |
部署:
1 | |
配置 DNS
把
1 | |
解析到
1 | |
例如
1 | |
或者公网
1 | |
即可访问
1 | |
方案四:MetalLB(裸机 Kubernetes 推荐)
如果你的 Kubernetes 是:
- VMware
- Proxmox
- ESXi
- 裸机服务器
- 家庭服务器
没有云厂商 LoadBalancer。
安装 MetalLB。
然后 Service 写:
1 | |
MetalLB 会自动分配一个局域网 IP,例如
1 | |
访问:
1 | |
甚至可以把域名解析到:
1 | |
方案五:hostNetwork(不推荐)
容器直接使用宿主机网络:
1 | |
这样 Nginx 就监听宿主机的 80 端口。
直接访问:
1 | |
但这种方式容易与宿主机端口冲突,通常不推荐。
域名绑定流程
无论采用哪种方式,流程基本一致:
1 | |
如果只是局域网访问
推荐:
1 | |
优点:配置简单,无需额外组件。
如果要绑定域名(推荐用于生产)
推荐架构:
1 | |
例如:
1 | |
这是 Kubernetes 中最常见、最灵活的访问方式,支持多个域名、HTTPS(TLS)以及路径路由等高级功能。
配置SSL证书
方式一:Let’s Encrypt(推荐,免费自动续期)
这是目前最常见的方案。
1. 安装 NGINX Ingress Controller
例如:
1 | |
安装完成后查看:
1 | |
如果是云服务器,会看到:
1 | |
如果是裸机,可以配合 MetalLB。
2. 域名解析
例如:
1 | |
添加 DNS A 记录:
1 | |
等待解析生效:
1 | |
应该能解析到你的公网 IP。
3. 安装 cert-manager
cert-manager 用于自动申请和续期 Let’s Encrypt 证书。
例如:
1 | |
等待所有 Pod 正常运行:
1 | |
4. 创建 ClusterIssuer
例如:
1 | |
部署:
1 | |
5. 配置 Ingress
例如:
1 | |
部署:
1 | |
6. 查看证书
1 | |
正常会显示:
1 | |
查看 Secret:
1 | |
浏览器访问:
1 | |
即可使用 HTTPS,并且证书会自动续期。
方式二:使用自己购买的 SSL 证书
如果你已经购买了证书(如阿里云、腾讯云、DigiCert 等),通常会拿到:
fullchain.pem(或server.crt)privkey.pem(或server.key)
先创建 Kubernetes Secret:
1 | |
然后在 Ingress 中引用:
1 | |
部署后即可启用 HTTPS。
如果证书更新,需要重新创建或更新 Secret。
5.安装管理面板 (Portainer)
对于 K3s 这种轻量级集群,Portainer 是最推荐的面板。它比官方 Dashboard 更美观,比 Rancher 更省资源。
创建 Portainer 命名空间:
1
sudo kubectl create namespace portainer使用 Helm 或直接使用 Manifest 安装: 这里我们使用最简单的官方远程脚本安装:
1
kubectl apply -n portainer -f https://downloads.portainer.io/ce2-19/portainer.yaml验证与访问
检查 Pod 运行状态:
1
kubectl get pods -n portainer等待状态变为
Running。获取访问端口: Portainer 默认映射了两个端口:
- HTTP:
30777 - HTTPS:
30779(推荐使用)
- HTTP:
浏览器访问: 打开浏览器,输入 Master 或 Node 的 IP 地址:
https://192.168.10.102:30779https://192.168.10.103:30779
注意: 初次登录需要你在 12 分钟内设置管理员密码,否则出于安全考虑,Portainer 服务会自动停止,届时需要重启 Pod。
6.拓展
kubernetes 常用命令
1. 基础信息查询 (Get & Describe)
这些命令用于查看集群资源的运行状态。
- 查看资源列表:
kubectl get nodes(查看节点状态)kubectl get pods -A(查看所有命名空间的 Pod)kubectl get svc(查看服务)kubectl get ns(查看命名空间)
- 查看详细描述:
kubectl describe pod <pod-name>(当 Pod 状态异常时,常用此命令查看错误事件)
- 查看日志:
kubectl logs <pod-name>(查看容器标准输出日志)kubectl logs -f <pod-name>(持续跟踪日志)
2. 资源创建与修改 (Apply & Edit)
K8s 推荐使用“声明式”管理资源。
通过文件创建/更新:
kubectl apply -f <filename.yaml>(最常用的部署命令)
直接编辑运行中的资源:
kubectl edit deployment <deployment-name>
临时修改镜像:
kubectl set image deployment/<name> <container-name>=<new-image>:<tag>
删除资源
kubectl delete (-f FILENAME | TYPE [NAME | /NAME | -l label | --all]) [flags]
3. 故障排除与调试 (Debug)
当应用出现问题时,这些工具能帮你进入内部查看。
- 进入 Pod 内部:
kubectl exec -it <pod-name> -- /bin/bash
- 端口转发: (将本地端口映射到集群内部)
kubectl port-forward <pod-name> 8080:80
- 查看资源占用 (需安装 Metrics Server):
kubectl top nodekubectl top pod
4. 扩缩容与滚动更新 (Scale & Rollout)
管理应用的副本数量和发布版本。
- 手动扩缩容:
kubectl scale deployment <name> --replicas=5
- 查看更新状态:
kubectl rollout status deployment/<name>
- 版本回滚:
kubectl rollout undo deployment/<name>(回滚到上一个版本)
5. 常用技巧与别名
为了提高效率,建议在你的终端配置文件(如 .bashrc 或 .zshrc)中添加别名:
1alias k='kubectl'
常用缩写对照表:
| 全称 | 缩写 |
|---|---|
pods |
po |
nodes |
no |
deployments |
deploy |
services |
svc |
namespaces |
ns |
configmaps |
cm |
💡 一个典型的排错流程示例:
kubectl get pods(查看状态是否为 Running)- 如果是 Pending/Error,执行
kubectl describe pod <name>(查看 Events 报错) - 如果是 CrashLoopBackOff,执行
kubectl logs <name>(查看程序崩溃原因)
更多命令
https://kubernetes.io/zh-cn/docs/reference/kubectl/
7.Helm
1. Helm 是什么?
在没有 Helm 之前,部署一个复杂的应用(如 WordPress)需要手动编写和维护大量的 YAML 文件(Deployment, Service, Ingress, ConfigMap 等)。
Helm 的核心价值:
- 打包管理: 将多个 YAML 文件封装成一个名为 Chart 的包。
- 模板化: 支持变量(Values),同一个 Chart 可以通过不同的配置部署到开发、测试和生产环境。
- 版本控制: 像 Git 一样,你可以一键升级应用,或者在出问题时一键回滚(Rollback)。
2. 如何安装 Helm
Helm 只是一个二进制客户端工具,安装非常简单。
通过脚本快速安装:
1 | |
注意: 安装完成后,运行
helm version确认是否安装成功。
3. Helm 怎么用? (常用命令)
使用 Helm 通常遵循:添加仓库 -> 搜索 -> 安装 -> 管理 的流程。
第一步:添加常用的 Chart 仓库
就像给手机加源一样,最常用的是 Bitnami 仓库。
1 | |
第二步:查找并安装应用
假设我们要安装一个 Redis:
1 | |
第三步:管理已安装的应用
1 | |
Q&A
1 | |
8.安装 kube-prometheus-stack 监控栈
1.添加 Helm 仓库
首先,需要将 Prometheus 社区的 Helm 仓库添加到你的本地 Helm 客户端中。
1 | |
2.创建命名空间
为了保持集群整洁,建议为监控组件创建一个独立的 monitoring 命名空间。
1 | |
3.安装 Helm Chart
使用 Helm 安装监控栈。这里我们将该发布(Release)命名为 kps。
1 | |
4.验证 Pod 运行状态
确认所有组件(Prometheus, Grafana, Alertmanager 等)是否已成功启动。
1 | |
预期输出: 你会看到类似下方的列表,确保所有 Pod 的状态均为 Running 且 READY 列显示正常(如 2/2 或 3/3)。
1 | |
5.访问 Grafana 面板
1. 获取 Grafana 管理员密码 默认用户名是 admin。运行以下命令获取自动生成的解码密码(提示:默认通常是 prom-operator):
1 | |
2. 端口转发(Port-forward) 为了从外部访问集群内部的服务,我们需要映射端口。(临时访问)
注意:
--address 0.0.0.0允许你通过服务器的 IP 访问,而不仅仅是 localhost。
1 | |
3. 浏览器登录 访问你的服务器 IP 和端口(例如:http://192.168.122.42:3000):
- 用户名 (Username):
admin - 密码 (Password): 使用上方命令获取到的字符串。
6.持久化运行
将 Grafana 服务的类型从 ClusterIP 改为 NodePort,这样你可以通过集群中任何节点的 IP + 指定端口直接访问,无需运行任何命令。
修改服务:
1
kubectl patch svc kps-grafana -n monitoring -p '{"spec": {"type": "NodePort"}}'获取暴露的端口:
1
kubectl get svc -n monitoring kps-grafana在输出的
PORT(S)列中,你会看到类似80:31234/TCP的内容。此时,你可以通过http://<服务器IP>:31234永久访问。
9.实战:部署WordPress
部署WordPress,核心步骤是配置镜像加速、部署MySQL数据库、部署WordPress应用,最后通过NodePort服务实现在局域网内的访问。
下面是一个逐步的操作指南。
1. 配置镜像加速(国内环境必需)
2. 创建数据库密码(Secret)
数据库密码等敏感信息不应直接写在配置文件中,应使用Kubernetes的 Secret 对象来存储。
在 master 节点执行以下命令,创建一个名为 wordpress-db-secret 的 Secret:
bash
1 | |
注意:请务必将
your-strong-root-password和your-strong-wordpress-password替换为你自己的强密码。
3. 创建持久化存储(PersistentVolumeClaim)
WordPress的网站文件(主题、插件、上传的图片等)和MySQL的数据库文件都需要持久化存储,防止Pod重启后数据丢失。
创建一个名为 storage.yaml 的文件,并写入以下内容:
1 | |
应用此配置:
1 | |
K3s自带的 local-path-provisioner 会自动为这些PVC在节点上创建相应的存储目录。
4. 部署MySQL
创建一个名为 mysql-deployment.yaml 的文件,内容如下:
1 | |
应用配置:
1 | |
5. 部署WordPress
创建一个名为 wordpress-deployment.yaml 的文件,内容如下:
1 | |
应用配置:
1 | |
6. 获取访问地址并验证
查看Service分配的NodePort:
1
kubectl get svc wordpress你会看到类似下面的输出,
PORT(S)列会显示80:3XXXX/TCP,其中3XXXX就是Kubernetes为你自动分配的端口号。1
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress NodePort 10.43.xxx.xxx <none> 80:3XXXX/TCP 10s在局域网内访问:
现在,你可以通过局域网内任意一台电脑的浏览器,访问http://<任意节点IP>:<分配的NodePort>来访问你的WordPress站点。- 例如,如果分配的端口是
30080,则访问地址为http://192.168.10.102:30080或http://192.168.10.103:30080。
- 例如,如果分配的端口是
7. (可选)配置Ingress实现域名访问
如果你拥有一个域名,并且希望将其指向WordPress服务,可以使用K3s自带的Traefik Ingress Controller来配置更优雅的访问方式。
创建一个 wordpress-ingress.yaml 文件:
1 | |
应用配置:
1 | |
配置完成后,你需要将你的域名DNS解析到K3s集群任意节点的IP地址,然后就可以通过域名访问了。
总结与注意事项
- 数据持久化:本方案已通过PVC保障了数据持久性,即使Pod重启或迁移,你的网站数据也不会丢失。
- 密码安全:所有密码都存储在Kubernetes Secret中,比明文写在YAML文件里更安全。
- 镜像拉取:在国内环境下,第一步的镜像加速配置至关重要。如果后续部署时Pod状态为
ImagePullBackOff,请检查镜像加速配置是否正确。