K3s轻量Kubernetes集群部署:香港VPS搭建生产级容器编排平台完整教程

Kubernetes(K8s)是容器编排的事实标准,但标准K8s对资源要求极高。K3s是Rancher Labs推出的轻量级Kubernetes发行版,内存占用仅512MB,非常适合在香港VPS上搭建生产级容器编排平台。

一、K3s vs K8s vs K0s 对比

特性K3s标准K8sK0s
最低内存512MB2GB+512MB
安装复杂度一条命令复杂简单
默认CNIFlannel无(需选择)kube-router
默认存储SQLite(单节点)/ etcd(多节点)etcdetcd / SQLite
ARM支持完整完整完整
生产就绪度高最高高

二、架构规划

<code">最小生产集群(3节点):
  master-1(控制平面):2核4G,香港VPS
  worker-1(工作节点):2核4G,香港VPS
  worker-2(工作节点):2核4G,香港VPS

  所有节点通过内网互通(IDC.Net同账号内网)
  对外通过Nginx Ingress暴露服务

三、安装Master节点

<code"># 在master-1上执行
# 开放K3s所需端口
ufw allow 6443/tcp    # Kubernetes API
ufw allow 10250/tcp   # Kubelet
ufw allow 8472/udp    # Flannel VXLAN
ufw allow 51820/udp   # Wireguard(K3s内置网络加密)

# 安装K3s(单命令,约30秒完成)
curl -sfL https://get.k3s.io | sh -s - server \
  --cluster-init \
  --tls-san 公网IP \
  --tls-san 内网IP \
  --disable traefik \          # 禁用默认Traefik,改用Nginx Ingress
  --node-name master-1 \
  --write-kubeconfig-mode 644

# 验证安装
kubectl get nodes
kubectl get pods -A

# 获取加入集群的Token(worker节点需要)
cat /var/lib/rancher/k3s/server/node-token

四、添加Worker节点

<code"># 在每台worker节点上执行
K3S_URL="https://master内网IP:6443"
K3S_TOKEN="master节点输出的Token"

curl -sfL https://get.k3s.io | K3S_URL=$K3S_URL K3S_TOKEN=$K3S_TOKEN sh -s - agent \
  --node-name worker-1

# 在master上验证节点已加入
kubectl get nodes -o wide
# NAME       STATUS   ROLES                  AGE
# master-1   Ready    control-plane,master   5m
# worker-1   Ready                     2m
# worker-2   Ready                     2m

五、安装Nginx Ingress Controller

<code"># 安装Helm(K8s包管理器)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# 添加ingress-nginx仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# 安装ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.service.type=NodePort \
  --set controller.service.nodePorts.http=30080 \
  --set controller.service.nodePorts.https=30443

# 验证安装
kubectl get pods -n ingress-nginx
<code"># Nginx(宿主机)将80/443流量转发到NodePort
server {
    listen 80;
    server_name *.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name *.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:30443;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

六、部署示例应用

<code"># myapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: your-registry/myapp:v1.2.3
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: production
spec:
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
spec:
  ingressClassName: nginx
  rules:
  - host: app.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              number: 80
<code"># 创建命名空间和密钥
kubectl create namespace production
kubectl create secret generic db-secret \
  --from-literal=password='数据库密码' \
  -n production

# 部署应用
kubectl apply -f myapp-deployment.yaml

# 查看部署状态
kubectl get all -n production
kubectl rollout status deployment/myapp -n production

七、零停机滚动更新

<code"># 更新镜像版本(滚动更新)
kubectl set image deployment/myapp \
  myapp=your-registry/myapp:v1.2.4 \
  -n production

# 观察滚动更新过程
kubectl rollout status deployment/myapp -n production

# 如果新版本有问题,立即回滚
kubectl rollout undo deployment/myapp -n production

# 查看历史版本
kubectl rollout history deployment/myapp -n production

八、持久化存储(Local Path Provisioner)

<code"># K3s默认内置Local Path Provisioner
# 创建使用本地存储的PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path    # K3s默认存储类
  resources:
    requests:
      storage: 20Gi

九、集群监控

<code"># 安装metrics-server(支持kubectl top命令)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 查看节点资源使用
kubectl top nodes

# 查看Pod资源使用
kubectl top pods -n production --sort-by=memory

# 安装Kubernetes Dashboard
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard \
  --create-namespace --namespace kubernetes-dashboard

十、总结

K3s将Kubernetes的复杂度大幅降低,三台2核4G的香港VPS即可搭建生产级容器编排平台,支持自动故障转移、滚动更新和水平扩缩容。IDC.Net的香港VPS同账号内网互通,节点间通信延迟低至0.1ms,是搭建K3s集群的理想基础设施,无需额外的内网互通费用。

THE END