完整版 Kubernetes 对单个 VPS 来说可能显得过于复杂和资源密集。k3s 是 CNCF 认证的轻量级 Kubernetes 发行版,30 秒内安装完毕,仅占用约 512 MB 内存,完全兼容 kubectl 和 Helm。k3s 特别适合在预算有限的 VPS 上运行生产级工作负载。与 Docker Compose 不同,k3s 提供了企业级特性如自动故障恢复、零停机滚动更新、精细的资源限制和声明式基础设施管理。此外,k3s 内置了 Traefik 作为 Ingress 控制器,并集成了本地路径存储驱动,使得在单节点环境中管理持久化数据变得简单直观。
为何选择 k3s 而非 Docker Compose?
Docker Compose 对于运行少量容器足有效率,但当应用规模增长时,Kubernetes 提供了 Docker Compose 无法实现的高级功能:
- 自动修复(Auto-healing) — 崩溃的 Pod 会自动重启,无需手动干预
- 滚动更新(Rolling Updates) — 应用升级时零停机,逐个替换实例
- 资源限制 — 为每个 Pod 设置 CPU 和内存限制,防止单个应用消耗过多资源
- 声明式配置 — 将所有基础设施定义存储在 Git 中的 YAML 文件,实现版本控制和审计
- Helm 包管理 — 使用 Helm Chart 一条命令安装复杂的多组件软件栈
- 自动扩展和调度 — 根据资源可用性自动调度 Pod,支持水平扩展
从 Docker Compose 迁移到 k3s 是自然的进化路径。当您的应用需要更精细的资源控制、健康检查和跨多个容器的服务编排时,k3s 是理想选择。更关键的是,您在 k3s 上编写的 YAML 配置文件和积累的知识,未来可以无缝迁移到更大规模的生产集群。
系统要求与规划
- 操作系统:Ubuntu 20.04 或更高版本(CentOS/RHEL 也支持)
- 最低 RAM:2 GB(推荐 4 GB 或更多)
- CPU:2 个核心(推荐 4+ 核心处理生产工作负载)
- 存储:SSD 20 GB 以上(k3s 本身~1GB,容器镜像和数据需要剩余空间)
- 网络:开放端口 6443(Kubernetes API)用于 kubectl 远程访问
- 出站连接:需要访问互联网以拉取容器镜像和 Helm Chart
对于生产环境,建议使用 4GB 内存的 VPS。如果计划运行数据库(如 PostgreSQL)或更复杂的应用,8GB 以上内存更为理想。检查 VPS 提供商是否允许修改内核参数和加载内核模块,这些对 Kubernetes 正常运行是必要的。
第一步 — 安装 k3s
k3s 的安装极其简单。官方安装脚本会自动检测系统环境并配置所有必要的组件:
curl -sfL https://get.k3s.io | sh -
# 等待 1-2 分钟自动完成
sudo k3s kubectl get nodes
如果看到节点状态为 Ready,说明 k3s 已成功启动。若节点长时间处于 NotReady 状态,请检查以下项目:
- VPS 的物理内存是否至少 2GB(运行
free -h查看) - 防火墙是否允许 6443 端口的入站流量
- 系统日志是否有错误信息(查看
sudo journalctl -u k3s) - 确保有足够的磁盘空间(
df -h)
第二步 — 本地配置 kubectl
为了从本地机器(而非 VPS 上)管理集群,需要配置本地 kubectl 连接到 VPS 上的 k3s API:
# 在 VPS 上打印 kubeconfig
sudo cat /etc/rancher/k3s/k3s.yaml
将输出内容复制下来,在本地机器上创建配置文件:
# 在本地机器上
mkdir -p ~/.kube
# 粘贴上面的内容,将 127.0.0.1 替换为 VPS 的公网 IP(例如 1.2.3.4)
nano ~/.kube/config-k3s
# 例如将这一行
# server: https://127.0.0.1:6443
# 改为
# server: https://1.2.3.4:6443
# 设置环境变量指向该配置
export KUBECONFIG=~/.kube/config-k3s
# 验证连接
kubectl get nodes
kubectl get pods --all-namespaces
如果连接失败,确保 VPS 防火墙已开放 6443 端口,并且 IP 地址替换正确。可使用 telnet VPS_IP 6443 测试端口连通性。
第三步 — 部署第一个应用
创建 Deployment
Deployment 定义应用应该如何在集群中运行(镜像、副本数、资源限制等):
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 2 # 运行 2 个副本实现负载均衡
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine # 使用轻量级 Alpine 镜像
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "500m" # 限制不超过 0.5 CPU 核心
kubectl apply -f nginx-deployment.yaml
kubectl get pods -w # -w 参数持续监视 Pod 状态变化
运行命令后,kubectl 会逐个启动 2 个 nginx Pod。观察状态从 Pending → ContainerCreating → Running 的变化。
创建 Service
Service 为 Pod 群组提供稳定的网络访问端点。即使 Pod 重启 IP 变化,Service IP 保持不变:
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
type: ClusterIP # ClusterIP 仅在集群内可访问
ports:
- protocol: TCP
port: 80 # Service 监听的端口
targetPort: 80 # 转发到 Pod 的端口
kubectl apply -f nginx-service.yaml
kubectl get svc # 查看 Service 的 ClusterIP
通过 Ingress 暴露到互联网(使用内置 Traefik)
Ingress 使应用可以通过 HTTP(S) 从互联网访问。k3s 默认部署 Traefik Ingress 控制器,支持自动 HTTPS 和路由规则:
# nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt
spec:
rules:
- host: nginx.example.com # 用你的域名替换
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
kubectl apply -f nginx-ingress.yaml
# 查看 Ingress 的 IP/域名
kubectl get ingress -w
创建 Ingress 后,将你的域名 A 记录指向 VPS 的 IP。Traefik 会自动申请 Let's Encrypt SSL 证书(需要域名指向正确)。等待几秒钟,访问 https://nginx.example.com 应该返回 nginx 欢迎页面。
第四步 — 安装和使用 Helm
Helm 是 Kubernetes 的包管理器,可一条命令部署整个应用栈(例如数据库、缓存、应用服务):
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version
示例:用 Helm 安装 cert-manager
cert-manager 自动化 Kubernetes 中的 TLS 证书管理和续期,与 Traefik 协同工作:
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true
# 验证安装
kubectl get pods -n cert-manager
Helm Chart 封装了所有必要的 YAML 配置、依赖关系和最佳实践。安装后,cert-manager 会自动为标记了特定注解的 Ingress 颁发和续期 Let's Encrypt 证书。
第五步 — 配置 ConfigMap 和 Secret
ConfigMap 存储应用配置(非敏感数据),Secret 存储敏感信息(密码、API 密钥)。都是 Kubernetes 原生资源,支持热更新:
# 创建 ConfigMap
kubectl create configmap app-config \
--from-literal=DB_HOST=postgres \
--from-literal=DB_PORT=5432 \
--from-literal=LOG_LEVEL=info
# 创建 Secret(自动 Base64 编码)
kubectl create secret generic app-secret \
--from-literal=DB_PASSWORD=my_secure_password \
--from-literal=API_KEY=secret_api_key
在 Deployment 中引用这些配置:
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DB_HOST
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: DB_PASSWORD
修改 ConfigMap/Secret 后,Pod 需要重启才能加载新值。可通过 kubectl rollout restart deployment/app-name 重启 Deployment 中的所有 Pod。
存储和持久卷
对于需要数据持久化的应用(如数据库),需要配置 PersistentVolumeClaim(PVC):
# postgres-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce # 一次仅一个 Pod 可读写
resources:
requests:
storage: 50Gi # 请求 50GB 存储
storageClassName: local-path # k3s 内置的本地存储驱动
k3s 内置的 local-path 驱动将数据存储在 VPS 的 /var/lib/rancher/k3s/storage 目录。对于生产数据库,建议将这个目录挂载到高性能 SSD 上,或配置定期备份策略。
常用 kubectl 命令速查
kubectl get all -A # 查看所有资源
kubectl get nodes # 查看集群节点
kubectl get pods -n [namespace] # 查看指定 namespace 的 Pod
kubectl describe pod [pod-name] # 查看 Pod 详细信息
kubectl logs [pod-name] -f # 流式查看 Pod 日志
kubectl exec -it [pod-name] -- /bin/sh # 进入 Pod 容器 Shell
kubectl scale deployment [name] --replicas=3 # 扩展副本数
kubectl set image deployment/[name] [container]=[image:tag] # 更新镜像版本
kubectl rollout undo deployment/[name] # 回滚部署到上一个版本
kubectl port-forward svc/[service] 8080:80 # 本地端口转发测试服务
kubectl delete pod [pod-name] # 删除 Pod(Deployment 会自动重建)
启用资源指标监控:默认 k3s 不部署 metrics-server。执行 kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml 启用后,即可使用 kubectl top nodes 和 kubectl top pods 查看实时 CPU 和内存使用。
网络和 DNS 配置
k3s 使用 CoreDNS 作为集群内 DNS 服务,所有 Pod 默认可通过服务名称 (dns.default) 相互通信。Service DNS 名称格式为 [service-name].[namespace].svc.cluster.local。例如:
# Pod 访问另一个 namespace 的服务
curl http://my-service.other-namespace.svc.cluster.local:8080
对于跨 VPS 或跨区域的 Kubernetes 集群,可使用 CNI 插件(如 Flannel、Weave)实现高级网络拓扑。k3s 默认使用 Flannel,已配置完毕无需额外设置。
安全加固和最佳实践
RBAC(基于角色的访问控制):k3s 默认启用 RBAC。生产环境中,为不同团队和服务创建独立的 ServiceAccount,并分配最小必要权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: read-pods
rules:
- apiGroups: [""]
resources: ["pods", "pods/logs"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-pods-users
subjects:
- kind: User
name: "app-user"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: read-pods
apiGroup: rbac.authorization.k8s.io
网络策略:使用 NetworkPolicy 限制 Pod 间通信,实现零信任网络:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
资源配额:为每个 namespace 设置资源上限,防止单个应用消耗整个集群的资源:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: production
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
pods: "50"
故障排查和监控
集群运行过程中遇到问题时,按以下步骤诊断:
# 1. 检查 k3s 服务状态
sudo systemctl status k3s
# 2. 查看系统日志
sudo journalctl -u k3s -n 100 -f
# 3. 诊断 Pod 问题
kubectl describe pod [problem-pod] # 查看事件和状态
# 4. 查看容器日志
kubectl logs [pod-name] --previous # 上一次的容器日志(如果 Pod 重启过)
# 5. 检查集群健康
kubectl get componentstatuses
kubectl cluster-info
常见问题排查:Pod 卡在 Pending(通常是资源不足或 image 镜像无法拉取)、CrashLoopBackOff(应用启动错误)、ImagePullBackOff(镜像仓库无法访问)。逐一查看事件信息可快速定位问题。
备份和恢复
k3s 默认将集群状态保存在 SQLite 数据库(/var/lib/rancher/k3s/server/db)。定期备份该目录以防数据丢失:
# 在 VPS 上执行定期备份
sudo tar -czf /backup/k3s-backup-$(date +%Y%m%d).tar.gz \
/var/lib/rancher/k3s/server/db \
/etc/rancher/k3s/k3s.yaml
# 恢复时停止 k3s,替换数据库,重启
sudo systemctl stop k3s
sudo rm -rf /var/lib/rancher/k3s/server/db
sudo tar -xzf /backup/k3s-backup-20260101.tar.gz -C /
sudo systemctl start k3s
k3s 与 Docker Compose 功能对比
| 功能 | k3s | Docker Compose |
|---|---|---|
| 自动重启 | ✅ 存活探针 | 重启策略 |
| 零停机部署 | ✅ 滚动更新 | ❌ 需停机 |
| 资源限制 | ✅ CPU/内存 | 有限 |
| 学习难度 | 中等(学习曲线) | ✅ 低 |
| 内存开销 | ~512MB | ~50MB |
| Helm 支持 | ✅ 完全支持 | ❌ 无 |
| 自动扩展 | ✅ 水平扩展 | ❌ 手动扩展 |
| 适用场景 | 生产工作负载、多微服务、需要高可靠性 | 开发测试、简单应用、单机部署 |
需要运行 k3s 的 VPS?
AsiaGB VPS 配备 4–8 GB 内存和完全 root 权限,完美适配 k3s 生产工作负载。SSD 存储、99% 正常运行时间保证。起价仅需 500 泰铢/月。
查看 VPS 方案