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.k3s.io/zh/

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
2
3
4
5
6
7
ufw disable

或者

ufw allow 6443/tcp #apiserver
ufw allow from 10.42.0.0/16 to any #pods
ufw allow from 10.43.0.0/16 to any #services
  • 确认主机名: 建议分别设置主机名为 masternode0 方便识别。

    1
    2
    sudo hostnamectl set-hostname master  # 在102上执行
    sudo hostnamectl set-hostname node0 # 在103上执行

2. 部署 Master 节点 (192.168.10.102)

在 Master 节点上,我们将运行安装脚本并将其配置为集群的主控节点。

  1. 执行安装命令:

    1
    2
    3
    4
    5
    curl -sfL https://get.k3s.io | sh -

    # 中国用户,可以使用以下方法加速安装:

    curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
  2. 获取 Node Token: 安装完成后,你需要获取一个“令牌”,用于将 Node0 加入集群。

    1
    sudo cat /var/lib/rancher/k3s/server/node-token

    复制保存这个字符串,稍后在 Node0 上会用到。

  3. 检查状态:

    1
    sudo kubectl get nodes

    此时你应该能看到 master 节点处于 Ready 状态。


3. 部署 Node 节点 (192.168.10.103)

现在切换到 Node0 主机,将其作为工作节点连接到 Master。

  1. 执行安装命令: 请将下方命令中的 <MASTER_TOKEN> 替换为你刚才在 Master 上获取的字符串。

    1
    2
    3
    4
    5
    6
    7
    curl -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
sudo kubectl get nodes

预期输出:

1
2
3
4
sudo kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 32m v1.33.6+k3s1
node0 Ready <none> 30m v1.33.6+k3s1

配置国内镜像

Master节点

创建或编辑配置文件:

1
sudo nano /etc/rancher/k3s/registries.yaml

填入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mirrors:
docker.io:
endpoint:
- "https://docker.m.daocloud.io"
- "https://docker.1panel.live"

registry.k8s.io:
endpoint:
- "https://k8s.m.daocloud.io"

quay.io:
endpoint:
- "https://quay.m.daocloud.io"

ghcr.io:
endpoint:
- "https://ghcr.m.daocloud.io"

重启K3s

1
sudo systemctl restart k3s

Node节点

1
2
sudo mkdir -p /etc/rancher/k3s
sudo nano /etc/rancher/k3s/registries.yaml

配置完成

1
sudo systemctl restart k3s-agent

如何卸载K3s

如果需要重新开始:

  • Master: sudo /usr/local/bin/k3s-uninstall.sh
  • Node: sudo /usr/local/bin/k3s-agent-uninstall.sh

部署 Nginx 验证集群

我们创建一个简单的 Nginx 服务

  1. 在 Master 节点上创建配置文件:

    1
    nano nginx-demo.yaml
  2. 粘贴以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP

注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 定义一个 Deployment 资源,用于管理应用的滚动更新和副本数
apiVersion: apps/v1 # 使用 apps/v1 API 版本(Kubernetes 稳定版)
kind: Deployment # 资源类型为 Deployment
metadata:
name: nginx # Deployment 的名称,用于标识该资源
spec:
replicas: 2 # 指定运行 2 个 Pod 副本,保证高可用
selector: # 选择器,用于匹配该 Deployment 管理的 Pod
matchLabels: # 通过标签匹配
app: nginx # 标签键值对,要求 Pod 带有 app=nginx
template: # Pod 模板,定义新 Pod 的规格
metadata:
labels: # Pod 标签,必须与 selector 匹配
app: nginx
spec:
containers: # 容器列表
- name: nginx # 容器名称
image: nginx:latest # 使用的镜像及版本(latest 表示最新版,生产环境建议固定版本)
ports: # 声明容器监听的端口
- containerPort: 80 # 容器内 Nginx 服务监听 80 端口
---
# 定义一个 Service 资源,为 Deployment 中的 Pod 提供稳定的网络访问入口
apiVersion: v1 # 使用 v1 API 版本(Service 核心资源)
kind: Service # 资源类型为 Service
metadata:
name: nginx # Service 名称,集群内可通过该名称访问
spec:
selector: # 标签选择器,关联到带有 app=nginx 标签的 Pod
app: nginx
ports: # 端口映射配置
- port: 80 # Service 暴露的端口(集群内其他服务访问的端口)
targetPort: 80 # 目标 Pod 的容器端口(与 containerPort 对应)
protocol: TCP # 使用的协议(TCP)
type: ClusterIP # Service 类型为 ClusterIP(默认),仅在集群内部可访问,不对外暴露

  1. 应用配置:

    1
    sudo kubectl apply -f nginx-demo.yaml
  2. 验证:

查看 Pod 和 Service:

1
kubectl get pods,svc

输出示例:

1
2
3
4
5
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-xxxxxxxxxx-xxxxx 1/1 Running 0 1m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx ClusterIP 10.43.123.456 <none> 80/TCP 1m

此时 Nginx 已经在集群内部可用

服务访问

ClusterIP 只能在 Kubernetes 集群内部访问,局域网电脑和互联网都无法直接访问。

如果想在局域网或者绑定域名访问,有几种方案。


方案一:NodePort(最简单,适合局域网)

把 Service 改成:

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080

部署

1
kubectl apply -f nginx.yaml

查看

1
kubectl get svc

例如输出

1
2
NAME    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)
nginx NodePort 10.96.182.111 <none> 80:30080/TCP

然后局域网即可访问

1
http://192.168.10.102:30080

这里

1
192.168.10.102

就是 Kubernetes Node 的 IP。


方案二:LoadBalancer(云服务器推荐)

如果你是:

  • 阿里云 ACK
  • 腾讯云 TKE
  • 华为云 CCE
  • AWS EKS
  • Azure AKS

改成

1
type: LoadBalancer

例如

1
2
spec:
type: LoadBalancer

然后

1
kubectl get svc

会看到

1
2
EXTERNAL-IP
47.xx.xx.xx

直接访问

1
http://47.xx.xx.xx

即可。


方案三:Ingress(推荐绑定域名)

生产环境几乎都用 Ingress。

安装 Ingress Controller,例如:

  • NGINX Ingress Controller
  • Traefik
  • HAProxy
  • Kong

例如安装 NGINX Ingress。

创建 Ingress:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
spec:
ingressClassName: nginx
rules:
- host: www.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80

部署:

1
kubectl apply -f ingress.yaml

配置 DNS

1
www.test.com

解析到

1
Ingress Controller IP

例如

1
2
3
www.test.com

192.168.1.100

或者公网

1
2
3
www.test.com

47.xx.xx.xx

即可访问

1
http://www.test.com

方案四:MetalLB(裸机 Kubernetes 推荐)

如果你的 Kubernetes 是:

  • VMware
  • Proxmox
  • ESXi
  • 裸机服务器
  • 家庭服务器

没有云厂商 LoadBalancer。

安装 MetalLB。

然后 Service 写:

1
type: LoadBalancer

MetalLB 会自动分配一个局域网 IP,例如

1
192.168.1.210

访问:

1
http://192.168.1.210

甚至可以把域名解析到:

1
2
3
www.test.com

192.168.1.210

方案五:hostNetwork(不推荐)

容器直接使用宿主机网络:

1
2
spec:
hostNetwork: true

这样 Nginx 就监听宿主机的 80 端口。

直接访问:

1
http://192.168.1.100

但这种方式容易与宿主机端口冲突,通常不推荐。


域名绑定流程

无论采用哪种方式,流程基本一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
浏览器


www.test.com


DNS


Node IP / LoadBalancer IP


Ingress


Service


Pod

如果只是局域网访问

推荐:

1
2
3
4
5
Deployment

Service(NodePort)

192.168.1.100:30080

优点:配置简单,无需额外组件。


如果要绑定域名(推荐用于生产)

推荐架构:

1
2
3
4
5
6
7
8
9
Deployment

ClusterIP Service

Ingress

Ingress Controller(80/443

域名

例如:

1
2
3
4
5
6
7
8
9
10
api.example.com


Ingress


ClusterIP Service


Pod

这是 Kubernetes 中最常见、最灵活的访问方式,支持多个域名、HTTPS(TLS)以及路径路由等高级功能。

配置SSL证书

方式一:Let’s Encrypt(推荐,免费自动续期)

这是目前最常见的方案。

1. 安装 NGINX Ingress Controller

例如:

1
2
3
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace

安装完成后查看:

1
kubectl get svc -n ingress-nginx

如果是云服务器,会看到:

1
2
NAME                                 TYPE           EXTERNAL-IP
ingress-nginx-controller LoadBalancer 1.2.3.4

如果是裸机,可以配合 MetalLB。


2. 域名解析

例如:

1
www.example.com

添加 DNS A 记录:

1
2
3
www.example.com

1.2.3.4

等待解析生效:

1
ping www.example.com

应该能解析到你的公网 IP。


3. 安装 cert-manager

cert-manager 用于自动申请和续期 Let’s Encrypt 证书。

例如:

1
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

等待所有 Pod 正常运行:

1
kubectl get pods -n cert-manager

4. 创建 ClusterIssuer

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
email: admin@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-key

solvers:
- http01:
ingress:
class: nginx

部署:

1
kubectl apply -f issuer.yaml

5. 配置 Ingress

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt

spec:
ingressClassName: nginx

tls:
- hosts:
- www.example.com
secretName: nginx-tls

rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80

部署:

1
kubectl apply -f ingress.yaml

6. 查看证书
1
kubectl get certificate

正常会显示:

1
2
NAME        READY
nginx-tls True

查看 Secret:

1
kubectl get secret nginx-tls

浏览器访问:

1
https://www.example.com

即可使用 HTTPS,并且证书会自动续期。

方式二:使用自己购买的 SSL 证书

如果你已经购买了证书(如阿里云、腾讯云、DigiCert 等),通常会拿到:

  • fullchain.pem(或 server.crt
  • privkey.pem(或 server.key

先创建 Kubernetes Secret:

1
2
3
kubectl create secret tls nginx-tls \
--cert=fullchain.pem \
--key=privkey.pem

然后在 Ingress 中引用:

1
2
3
4
tls:
- hosts:
- www.example.com
secretName: nginx-tls

部署后即可启用 HTTPS。

如果证书更新,需要重新创建或更新 Secret。

5.安装管理面板 (Portainer)

对于 K3s 这种轻量级集群,Portainer 是最推荐的面板。它比官方 Dashboard 更美观,比 Rancher 更省资源。

  1. 创建 Portainer 命名空间:

    1
    sudo kubectl create namespace portainer
  2. 使用 Helm 或直接使用 Manifest 安装: 这里我们使用最简单的官方远程脚本安装:

    1
    kubectl apply -n portainer -f https://downloads.portainer.io/ce2-19/portainer.yaml

    验证与访问

    1. 检查 Pod 运行状态:

      1
      kubectl get pods -n portainer

      等待状态变为 Running

    2. 获取访问端口: Portainer 默认映射了两个端口:

      • HTTP: 30777
      • HTTPS: 30779 (推荐使用)
    3. 浏览器访问: 打开浏览器,输入 Master 或 Node 的 IP 地址:

      • https://192.168.10.102:30779
      • https://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 node
    • kubectl top pod

4. 扩缩容与滚动更新 (Scale & Rollout)

管理应用的副本数量和发布版本。

  • 手动扩缩容:
    • kubectl scale deployment <name> --replicas=5
  • 查看更新状态:
    • kubectl rollout status deployment/<name>
  • 版本回滚:
    • kubectl rollout undo deployment/<name> (回滚到上一个版本)

5. 常用技巧与别名

为了提高效率,建议在你的终端配置文件(如 .bashrc.zshrc)中添加别名:

1
alias k='kubectl'

常用缩写对照表:

全称 缩写
pods po
nodes no
deployments deploy
services svc
namespaces ns
configmaps cm

💡 一个典型的排错流程示例:

  1. kubectl get pods (查看状态是否为 Running)
  2. 如果是 Pending/Error,执行 kubectl describe pod <name> (查看 Events 报错)
  3. 如果是 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
2
3
4
5
6
7
8
9
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

#国内
curl -fsSL -o get_helm.sh https://ghfast.top/https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

注意: 安装完成后,运行 helm version 确认是否安装成功。


3. Helm 怎么用? (常用命令)

使用 Helm 通常遵循:添加仓库 -> 搜索 -> 安装 -> 管理 的流程。

第一步:添加常用的 Chart 仓库

就像给手机加源一样,最常用的是 Bitnami 仓库。

1
2
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

第二步:查找并安装应用

假设我们要安装一个 Redis:

1
2
3
4
5
# 搜索 Redis
helm search repo redis

# 安装 Redis (名称定为 my-redis)
helm install my-redis bitnami/redis

第三步:管理已安装的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看已安装的应用列表
helm list

# 查看应用的配置参数
helm get values my-redis

# 升级应用 (比如修改了配置文件后)
helm upgrade my-redis bitnami/redis -f values.yaml

# 一键回滚到上一个版本
helm rollback my-redis 1

# 卸载应用
helm uninstall my-redis

Q&A

1
2
3
4
5
6
7
8
9
10
出现了下面问题
root@master:~# helm install kps prometheus-community/kube-prometheus-stack \
-n monitoring
Error: INSTALLATION FAILED: Kubernetes cluster unreachable: stat /root/.kube/config: no such file or directory
解决办法
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
chmod 600 ~/.kube/config

8.安装 kube-prometheus-stack 监控栈

1.添加 Helm 仓库

首先,需要将 Prometheus 社区的 Helm 仓库添加到你的本地 Helm 客户端中。

1
2
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

2.创建命名空间

为了保持集群整洁,建议为监控组件创建一个独立的 monitoring 命名空间。

1
kubectl create namespace monitoring

3.安装 Helm Chart

使用 Helm 安装监控栈。这里我们将该发布(Release)命名为 kps

1
helm install kps prometheus-community/kube-prometheus-stack -n monitoring

4.验证 Pod 运行状态

确认所有组件(Prometheus, Grafana, Alertmanager 等)是否已成功启动。

1
kubectl get pods -n monitoring

预期输出: 你会看到类似下方的列表,确保所有 Pod 的状态均为 RunningREADY 列显示正常(如 2/2 或 3/3)。

1
2
3
4
5
6
7
8
NAME                                                    READY   STATUS    RESTARTS      AGE
alertmanager-kps-kube-prometheus-stack-alertmanager-0 2/2 Running 2 (12m ago) 30m
kps-grafana-7c695669f4-mwsbg 3/3 Running 0 30m
kps-kube-prometheus-stack-operator-7964756cb-mmfbr 1/1 Running 1 (12m ago) 30m
kps-kube-state-metrics-96dc6f854-vmwnn 1/1 Running 0 30m
kps-prometheus-node-exporter-tzqg4 1/1 Running 1 (12m ago) 30m
kps-prometheus-node-exporter-ztvnh 1/1 Running 0 30m
prometheus-kps-kube-prometheus-stack-prometheus-0 2/2 Running 0 30m

5.访问 Grafana 面板

1. 获取 Grafana 管理员密码 默认用户名是 admin。运行以下命令获取自动生成的解码密码(提示:默认通常是 prom-operator):

1
kubectl get secret --namespace monitoring -l app.kubernetes.io/component=admin-secret -o jsonpath="{.items[0].data.admin-password}" | base64 --decode ; echo

2. 端口转发(Port-forward) 为了从外部访问集群内部的服务,我们需要映射端口。(临时访问)

注意: --address 0.0.0.0 允许你通过服务器的 IP 访问,而不仅仅是 localhost。

1
kubectl port-forward --address 0.0.0.0 -n monitoring svc/kps-grafana 3000:80

3. 浏览器登录 访问你的服务器 IP 和端口(例如:http://192.168.122.42:3000):

  • 用户名 (Username): admin
  • 密码 (Password): 使用上方命令获取到的字符串。

6.持久化运行

将 Grafana 服务的类型从 ClusterIP 改为 NodePort,这样你可以通过集群中任何节点的 IP + 指定端口直接访问,无需运行任何命令。

  1. 修改服务:

    1
    kubectl patch svc kps-grafana -n monitoring -p '{"spec": {"type": "NodePort"}}'
  2. 获取暴露的端口:

    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
2
3
4
kubectl create secret generic wordpress-db-secret \
--from-literal=MYSQL_ROOT_PASSWORD='your-strong-root-password' \
--from-literal=MYSQL_PASSWORD='your-strong-wordpress-password' \
--from-literal=MYSQL_USER='wordpress'

注意:请务必将 your-strong-root-passwordyour-strong-wordpress-password 替换为你自己的强密码。

3. 创建持久化存储(PersistentVolumeClaim)

WordPress的网站文件(主题、插件、上传的图片等)和MySQL的数据库文件都需要持久化存储,防止Pod重启后数据丢失。

创建一个名为 storage.yaml 的文件,并写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# storage.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

应用此配置:

1
kubectl apply -f storage.yaml

K3s自带的 local-path-provisioner 会自动为这些PVC在节点上创建相应的存储目录。

4. 部署MySQL

创建一个名为 mysql-deployment.yaml 的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# mysql-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-db-secret
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: wordpress-db-secret
key: MYSQL_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-db-secret
key: MYSQL_PASSWORD
- name: MYSQL_DATABASE
value: wordpress
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim

应用配置:

1
kubectl apply -f mysql-deployment.yaml

5. 部署WordPress

创建一个名为 wordpress-deployment.yaml 的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# wordpress-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
# 关键:使用 NodePort 类型,以便在局域网内通过节点IP+端口访问
type: NodePort
ports:
- port: 80
targetPort: 80
# nodePort 可省略,系统会自动分配一个 30000-32767 之间的端口
# nodePort: 30080
selector:
app: wordpress
tier: frontend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:latest
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: wordpress-db-secret
key: MYSQL_USER
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-db-secret
key: MYSQL_PASSWORD
- name: WORDPRESS_DB_NAME
value: wordpress
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress-pv-claim

应用配置:

1
kubectl apply -f wordpress-deployment.yaml

6. 获取访问地址并验证

  1. 查看Service分配的NodePort

    1
    kubectl get svc wordpress

    你会看到类似下面的输出,PORT(S) 列会显示 80:3XXXX/TCP,其中 3XXXX 就是Kubernetes为你自动分配的端口号。

    1
    2
    NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    wordpress NodePort 10.43.xxx.xxx <none> 80:3XXXX/TCP 10s
  2. 在局域网内访问
    现在,你可以通过局域网内任意一台电脑的浏览器,访问 http://<任意节点IP>:<分配的NodePort> 来访问你的WordPress站点。

    • 例如,如果分配的端口是 30080,则访问地址为 http://192.168.10.102:30080http://192.168.10.103:30080

7. (可选)配置Ingress实现域名访问

如果你拥有一个域名,并且希望将其指向WordPress服务,可以使用K3s自带的Traefik Ingress Controller来配置更优雅的访问方式。

创建一个 wordpress-ingress.yaml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# wordpress-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress-ingress
spec:
rules:
- host: your-domain.com # 替换为你的域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wordpress
port:
number: 80

应用配置:

1
kubectl apply -f wordpress-ingress.yaml

配置完成后,你需要将你的域名DNS解析到K3s集群任意节点的IP地址,然后就可以通过域名访问了。


总结与注意事项

  1. 数据持久化:本方案已通过PVC保障了数据持久性,即使Pod重启或迁移,你的网站数据也不会丢失。
  2. 密码安全:所有密码都存储在Kubernetes Secret中,比明文写在YAML文件里更安全。
  3. 镜像拉取:在国内环境下,第一步的镜像加速配置至关重要。如果后续部署时Pod状态为 ImagePullBackOff,请检查镜像加速配置是否正确。

Debian12上使用K3s部署Kubernetes集群
https://blog.quickso.cn/2025/12/26/Debian12上使用K3s部署Kubernetes集群/
作者
木子欢儿
发布于
2025年12月26日
许可协议