安装k3s单节点并校验
使用官方安装脚本,单节点场景建议显式指定节点名、放开kubeconfig权限,并先禁用内置Traefik(后面我们会单独部署Ingress以讲清配置链路)。若你的马赛VPS内存偏紧,可追加--disable-dependency-metrics减少采集组件开销。
# 安装 k3s 单节点(server 模式,同时作为控制面与工作节点) curl -sfL https://get.k3s.io | sh -s - \ --write-kubeconfig-mode 644 \ --node-name marseille-1 \ --disable traefik \ --disable local-storage \ --kubelet-arg "eviction-hard=imagefs.available<10%,memory.available<100Mi" # 等待就绪后查看节点与已部署系统 Pod sudo k3s kubectl get nodes -o wide sudo k3s kubectl get pods -A # 复制 kubeconfig 到默认路径,便于用 kubectl 操作 mkdir -p ~/.kube sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config sudo chown $(id -u):$(id -g) ~/.kube/config sed -i “s/127.0.0.1/localhost/“ ~/.kube/config
校验阶段只要get nodes显示marseille-1为Ready、系统Pod全部Running,单节点控制面即就绪。此时k3s已内置Service网络(默认10.43.0.0/16)与Pod网络(默认10.42.0.0/16),后续应用无需再装CNI。如果未来要扩成多节点,只需在新增的马赛VPS上执行带--server与token的agent安装命令即可加入同一集群。
三、用Deployment与Service部署首个应用
编排的核心是把“跑一个容器”升级为“声明一个期望状态”。下面以一个面向欧洲用户的静态API服务为例,编写Deployment与ClusterIP Service。关键点在于资源请求(requests)与限制(limits)要写清楚:requests用于k3s调度时判断节点能否容纳,limits则防止单个Pod把整台马赛VPS的内存吃满,是单节点场景下的必要加固。
资源限制与探针配置
单台马赛VPS资源有限,必须为每个工作负载设置limits。下例中上限设为500Mi内存与500m CPU,并配置liveness/readiness探针,避免故障实例持续接收流量。探针用HTTP GET探活,与业务端口一致,便于k3s自动剔除异常Pod。
# app-deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: eu-api labels: app: eu-api spec: replicas: 2 selector: matchLabels: app: eu-api strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: eu-api spec: containers: - name: api image: registry.example.com/eu-api:1.8.2 ports: - containerPort: 8080 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "500Mi" livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: eu-api-svc spec: type: ClusterIP selector: app: eu-api ports: - protocol: TCP port: 80 targetPort: 8080
应用清单并观察滚动更新过程,可看到两个副本按maxSurge逐个替换,期间服务不中断。随后用kubectl get endpoints确认Service已把两个Pod IP纳入后端。对内网调用方而言,直接访问eu-api-svc.default.svc.cluster.local即可,无需关心Pod漂移后的IP变化——这正是编排层相对Docker单机的本质提升。
# 部署并查看状态 kubectl apply -f app-deploy.yaml kubectl rollout status deployment/eu-api kubectl get pods -o wide kubectl get endpoints eu-api-svc # 临时在集群内验证服务可达 kubectl run curl-test --rm -it --image=curlimages/curl -- sh -c \ "curl -s -o /dev/null -w “%{http_code}\n“ http://eu-api-svc/"
四、Ingress与对外暴露:从马赛节点到公网
ClusterIP只在内网可见,要让欧洲用户从公网访问,需经Ingress把域名流量路由到对应Service。k3s内置Traefik作为默认Ingress Controller,但我们安装时禁用了它,目的正是手动部署以看清配置链路。下面用Traefik的IngressRoute(或标准Ingress)把api.example.eu指向eu-api-svc,并配置TLS自动重定向,落实传输层加固。
标准Ingress暴露与TLS
在马赛VPS上,公网IP直接绑定到节点,Ingress Controller以hostNetwork或NodePort方式监听80/443。以下标准Ingress将域名按路径路由到后端Service,并设置annotations启用TLS与HTTP到HTTPS重定向。证书可对接cert-manager自动签发,避免明文传输。
# ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: eu-api-ingress annotations: traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.tls: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true" spec: ingressClassName: traefik tls: - hosts: - api.example.eu secretName: eu-api-tls rules: - host: api.example.eu http: paths: - path: / pathType: Prefix backend: service: name: eu-api-svc port: number: 80
部署Ingress后,把域名api.example.eu的A记录解析到马赛VPS的公网IP,流量即经由Traefik按host路由到对应Service。若单台节点需承载多个站点,可继续追加Ingress规则或在Traefik侧按Host头分流,这就是相比docker run单端口映射更好的多租户能力。验证时从欧洲本地或马赛机房内网curl域名,确认返回200且证书有效。
kubectl apply -f ingress.yaml kubectl get ingress eu-api-ingress # 从马赛节点本机验证(假设公网IP已绑定) curl -sI https://api.example.eu/healthz | head -n 3
单节点下的高可用取舍
- Ingress Controller本身也是Pod,单节点场景下它宕机即全站不可达,故建议为其设置resources.limits并单独预留CPU。
- 若业务对可用性敏感,可在马赛再加一台VPS组成双节点k3s,用--disable traefik后在两节点各跑一个Ingress副本,配合前置负载均衡消除单点。
- 证书与Secret务必通过kubectl describe secret核对,避免明文配置落入镜像或日志。
五、资源限制、监控与轻量替代方案
单台马赛VPS跑k3s,资源治理是长久稳定运行的关键。除了每个工作负载写limits,还应从命名空间层面设ResourceQuota与LimitRange,防止某个应用突发把节点压垮。下表给出不同编排形态在“同等2核4G马赛VPS”下的资源占用与可承载副本数参考,帮助量化选择。
| 编排形态 |
系统占用(内存) |
可给业务的余量 |
典型可承载Pod数 |
滚动更新 |
运维心智负担 |
| Docker单机 |
约80MB-120MB |
约3.8GB |
8-12个轻量容器 |
需脚本 |
低 |
| Docker Compose |
约100MB-150MB |
约3.7GB |
8-12个容器 |
需脚本 |
低 |
| k3s单节点 |
约400MB-600MB |
约3.2GB-3.4GB |
10-16个中等Pod |
原生支持 |
中 |
| k3s+外部etcd |
约500MB-700MB |
约3.0GB-3.2GB |
10-14个Pod |
原生支持 |
中高 |
| 完整k8s单控 |
约1.5GB-2GB |
约2GB |
6-8个Pod |
原生支持 |
高 |
| Docker Swarm |
约120MB-200MB |
约3.6GB |
8-12个服务 |
原生支持 |
低中 |
命名空间级资源治理
用LimitRange给未显式声明limits的Pod兜底,用ResourceQuota锁定命名空间总量,是单节点防雪崩的实用加固。下面片段把default命名空间的内存上限锁在2.5Gi、CPU锁在1500m,并强制每个容器至少有128Mi请求,避免“无限制Pod”吞掉整台马赛VPS。
# ns-quota.yaml apiVersion: v1 kind: LimitRange metadata: name: mem-cpu-limit-range namespace: default spec: limits: - default: cpu: "300m" memory: "256Mi" defaultRequest: cpu: "100m" memory: "128Mi" type: Container --- apiVersion: v1 kind: ResourceQuota metadata: name: ns-quota namespace: default spec: hard: requests.cpu: "1500m" requests.memory: "2Gi" limits.cpu: "1500m" limits.memory: "2.5Gi" pods: "20"
轻量替代与调优清单
- 若只是想获得自愈与调度、不需要Ingress丰富特性,可保留k3s内置Traefik,省去手动部署步骤。
- 内存极度紧张时,用--disable servicelb,metrics-server关闭非必需组件,并以embedded etcd替代外部DB降低依赖。
- 镜像分发走马赛本地或欧洲镜像缓存,减少跨区拉取;对固定基础镜像可用k3s内置的镜像导入,离线也能部署。
- 日志与指标用轻量方案(如node-exporter+Prometheus单实例或外部托管),避免再起一套重型监控吃光资源。
- 定期kubectl top nodes/pods巡检,结合ResourceQuota把异常增长挡在命名空间边界。
总结
在单台或少量马赛(法国)VPS上用k3s跑轻量Kubernetes,是一条介于“裸Docker单机”和“完整k8s集群”之间的务实路线:它保留了Deployment、Service、Ingress、资源限制等核心编排能力,又把控制面开销压到一台入门VPS能承受的范围。本文从节点初始化、声明式部署、Ingress对外暴露到命名空间级资源治理,给出了可执行的命令与清单;关键在于单节点下务必写好limits与ResourceQuota,并在扩节点时再补Ingress高可用。若你的欧洲业务正考虑用容器编排提升交付效率,欢迎通过idcbest.com官网在线客服咨询,获取针对马赛vps的配置与报价参考。