K3s集群以及KubePi安装、配置与使用

Debian-K3s集群的安装、配置与使用

K3s 是一个轻量级的 Kubernetes 发行版,旨在简化和优化 Kubernetes 的安装和运行。K3s 使用了简化的架构,使其更适合在资源受限的环境中运行,如边缘设备、物联网(IoT)设备和低功耗硬件。K3s 的架构基于标准的 Kubernetes 组件,但对其进行了精简和优化。

官方文档:https://docs.k3s.io/zh/

https://docs.rancher.cn/docs/k3s/_index

K3s 集群的典型拓扑

  • Server 节点指的是运行 k3s server 命令的主机,control plane 和数据存储组件由 K3s 管理。
  • Agent 节点指的是运行 k3s agent 命令的主机,不具有任何数据存储或 control plane 组件。
  • Server 和 Agent 都运行 kubelet、容器运行时和 CNI。

1. 单节点模式

在单节点模式下,k3s serverk3s agent 运行在同一台机器上。适用于测试环境或资源非常有限的环境。

1
2
3
4
5
6
[Master Node] (K3s server + agent)
└── K3s API Server
└── K3s Controller Manager
└── K3s Scheduler
└── etcd (默认使用 SQLite)
└── K3s agent (用于运行容器和 Pod)

2. 多节点模式

在多节点模式下,k3s server 可以部署多个实例以提供高可用性,而 k3s agent 部署在多个工作节点上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Master Node 1] (K3s server)
└── K3s API Server
└── K3s Controller Manager
└── K3s Scheduler
└── etcd (或外部 etcd)

[Master Node 2] (K3s server) <- 高可用配置
└── K3s API Server
└── K3s Controller Manager
└── K3s Scheduler

[Worker Node 1] (K3s agent)
└── K3s agent
└── 容器运行时

[Worker Node 2] (K3s agent)
└── K3s agent
└── 容器运行时

部署 K3s 单节点模式是非常简单的。以下是安装步骤,涵盖了从安装 K3s 到验证集群是否正常运行的完整过程。

步骤 1:准备环境

确保你的机器有互联网连接,并且已经更新了系统。

  1. 更新系统
    在安装 K3s 之前,先确保系统是最新的:
1
2
sudo apt update
sudo apt upgrade -y

2.安装Docker

由于 K3s 默认运行环境为 containerd,所以为了使用 Docker 作为运行时,需要先在各节点正常安装 Docker

https://getdocker.quickso.cn/

步骤 2:安装 K3s

默认:

1
curl -sfL https://get.k3s.io | sh -

国内:

1
2
3
4
curl –sfL \
https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn sh -s - \
--system-default-registry "registry.cn-hangzhou.aliyuncs.com"

要使用 Docker 而不是 containerd

默认:

1
curl -sfL https://get.k3s.io | sh -s - --docker

国内:

1
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - --docker

常用命令

类型 命令 使用方法及示例
集群信息 kubectl cluster-info 显示集群基本信息 kubectl cluster-info
kubectl version 查看客户端和服务器版本 kubectl version --short
节点管理 kubectl get nodes 查看所有节点状态 kubectl get nodes -o wide
kubectl describe node <节点名> 查看节点详细信息 kubectl describe node node01
命名空间 kubectl get ns 查看所有命名空间 kubectl get ns
kubectl create ns <命名空间> 创建命名空间 kubectl create ns test
Pod 管理 kubectl get pods 查看默认命名空间的 Pod kubectl get pods -n <命名空间>
kubectl describe pod <Pod名> 查看 Pod 详细信息 kubectl describe pod nginx-pod
kubectl logs <Pod名> 查看 Pod 日志 kubectl logs nginx-pod -c <容器名> (多容器场景)
kubectl exec -it <Pod名> -- <命令> 进入 Pod 容器 kubectl exec -it nginx-pod -- /bin/sh
kubectl delete pod <Pod名> 删除 Pod kubectl delete pod nginx-pod --force (强制删除)
部署管理 kubectl get deployments 查看 Deployment kubectl get deploy -A (全命名空间)
kubectl scale deploy <Deployment名> --replicas=<数量> 扩缩容 kubectl scale deploy nginx-deploy --replicas=3
kubectl rollout status deploy/<Deployment名> 查看滚动更新状态 kubectl rollout status deploy/nginx-deploy
kubectl rollout undo deploy/<Deployment名> 回滚到上一版本 kubectl rollout undo deploy/nginx-deploy
服务管理 kubectl get services 查看 Service kubectl get svc
kubectl expose deploy <Deployment名> --port=<端口> 创建 Service kubectl expose deploy nginx-deploy --port=80 --type=NodePort
配置管理 kubectl get configmaps 查看 ConfigMap kubectl get cm
kubectl create configmap <名称> --from-file=<文件路径> 从文件创建 ConfigMap kubectl create configmap app-config --from-file=config.properties
存储管理 kubectl get pv 查看持久卷(PV) kubectl get pv
kubectl get pvc 查看持久卷声明(PVC) kubectl get pvc -n default
调试诊断 kubectl top pod 查看 Pod 资源使用 kubectl top pod --sort-by=cpu
kubectl get events --sort-by=.metadata.creationTimestamp 查看事件(按时间排序) kubectl get events -n kube-system
应用部署 kubectl apply -f <YAML文件> 通过 YAML 文件部署资源 kubectl apply -f nginx.yaml
kubectl delete -f <YAML文件> 删除 YAML 定义的资源 kubectl delete -f nginx.yaml
标签筛选 kubectl get pods -l <键>=<值> 按标签筛选资源 kubectl get pods -l app=nginx
端口转发 kubectl port-forward <Pod名> <本地端口>:<Pod端口> 端口转发到本地 kubectl port-forward nginx-pod 8080:80
补丁更新 kubectl patch deploy <名称> -p '{"spec": {"template": {"metadata": {"annotations": {"update": "v2"}}}}}' 热更新 Deployment kubectl patch deploy nginx-deploy -p '{"spec":{"replicas":5}}'

配置镜像

Docker
1
2
3
echo '{"registry-mirrors": ["https://docker.1ms.run"]}' | sudo tee /etc/docker/daemon.json > /dev/null
systemctl daemon-reload
systemctl restart docker
K3s
1
2
3
4
5
6
7
cat >> /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"docker.io":
endpoint:
- "https://docker.1ms.run"
EOF
systemctl restart k3s

安装完成后,K3s 会自动启动, 检查K3s服务的状态:

1
sudo systemctl status k3s

工作节点的安装(可选)

查看 K3S_TOKEN

1
sudo cat /var/lib/rancher/k3s/server/node-token
Agent安装
1
root@k3s-agent-1:~# curl -sfL https://get.k3s.io | K3S_URL=https://MASTER_URL:6443 K3S_TOKEN=NODE_TOKEN sh -

要使用 Docker 而不是 containerd

1
2
3
curl -sfL https://get.k3s.io | K3S_URL=https://MASTER_URL:6443 K3S_TOKEN=NODE_TOKEN INSTALL_K3S_EXEC="--docker" sh -
# 或使用国内镜像
curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://MASTER_URL:6443 K3S_TOKEN=NODE_TOKEN INSTALL_K3S_EXEC="--docker" sh -

根据需求把上面的 https://MASTER_URL:6443NODE_TOKEN更换成你的即可

K3s worker 节点的角色默认为none,如何修改?

可以通过kubectl label node 节点名称 node-role.kubernetes.io/worker=worker为节点增加 worker 角色。

配套工具

helm

Helm 是一个 Kubernetes 包管理工具,类似于 Linux 下的 aptyum,它帮助用户管理 Kubernetes 应用的安装、升级和配置。

helm官网地址:https://helm.sh/docs/intro/install/

在上面的文档中找到你的服务器对应系统的安装流程,下面是Ubuntu的安装流程

1
2
3
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

也可以Apt安装

1
2
3
4
5
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

然后复制k3s.yml到~/.kube/文件夹下即可

1
cp /etc/rancher/k3s/k3s.yaml ~/.kube/

测试helm命令:
image.png

kubepi

  • KubePi 是一个现代化的 K8s 面板。
  • KubePi 允许管理员导入多个 Kubernetes 集群,并且通过权限控制,将不同 cluster、namespace 的权限分配给指定用户。它允许开发人员管理 Kubernetes 集群中运行的应用程序并对其进行故障排查,供开发人员更好地处理 Kubernetes 集群中的复杂性。

https://github.com/1Panel-dev/KubePi

文档:https://github.com/1Panel-dev/KubePi/wiki/

安装(持久化部署)

1
wget https://raw.githubusercontent.com/1Panel-dev/KubePi/master/docs/deploy/kubectl/kubepi-pvc.yaml

获取StorageClass

1
kubectl get sc

修改

1
vim kubepi-pvc.yaml
1
storageClassName: local-path 修改这个配置为你的StorageClass

应用

1
kubectl apply -f kubepi-pvc.yaml

获取访问地址

1
2
3
4
5
6
7
# 获取 NodeIp
export NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}")
# 获取 NodePort
export NODE_PORT=$(kubectl -n kube-system get services kubepi -o jsonpath="{.spec.ports[0].nodePort}")
# 获取 Address
echo http://$NODE_IP:$NODE_PORT

登录系统
地址: http://$NODE_IP:$NODE_PORT
用户名: admin
密码: kubepi

集群导入

选择集群列表-导入-认证模式选择kubeconfig 文件

在终端执行

1
cat /etc/rancher/k3s/k3s.yaml

将输出的内容复制粘贴到输入框

如果 server IP 为 127.0.0.1,需要将 IP 替换为集群 master 节点 IP

cluster-import-kubeconfig

然后修改默认密码,就可以开始使用了,更多内容请看官方文档

image-20250810101553554

卸载 K3s

如果您使用安装脚本安装了 K3s,那么在安装过程中会生成一个卸载 K3s 的脚本。

卸载 K3s 会删除集群数据和所有脚本。要使用不同的安装选项重新启动集群,请使用不同的标志重新运行安装脚本。

要从 server 节点卸载 K3s,请运行:

1
/usr/local/bin/k3s-uninstall.sh

要从 agent 节点卸载 K3s,请运行:

1
/usr/local/bin/k3s-agent-uninstall.sh

部署服务

以NGINX为例

创建 Pod

将以下代码写入 nginx-pod.yaml

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80

使用如下命令应用:

1
2
root@k3s-server:~/k3s# kubectl apply -f nginx-pod.yaml
pod/nginx created

查看运行状态:

1
2
3
root@k3s-server:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 11h

与 Docker 不同,这里进入容器的需要在命令前加上 --

进入 Pod 并测试访问:

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
root@k3s-server:~/k3s# kubectl exec -it nginx -- /bin/bash
root@nginx:/# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

到此为止,我们创建了一个功能正常的 Pod。

创建 Deployment

将以下代码写入 nginx-deployment.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80

使用如下命令应用:

1
2
root@k3s-server:~/k3s# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx created

查看运行状态:

1
2
3
root@k3s-server:~/k3s# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 2/2 2 2 29s

此时再查看 Pod,如下:

1
2
3
4
root@k3s-server:~/k3s# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-544dc8b7c4-lzvz9 1/1 Running 0 3m4s
nginx-544dc8b7c4-5nbcw 1/1 Running 0 3m4s

可以看到,由 Deployment 产生的 Pod 命名规则如下:

1
${DeploymentName}-${DeploymentUid}-${Hash}

在查看 Pod 的时候,如果加上 -o wide 参数,就可以查看更多信息:

1
2
3
4
root@k3s-server:~/k3s# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-544dc8b7c4-lzvz9 1/1 Running 0 9m30s 10.42.1.4 k3s-agent-1 <none> <none>
nginx-544dc8b7c4-5nbcw 1/1 Running 0 9m30s 10.42.3.3 k3s-agent-2 <none> <none>

可以看到,该 nginx 被创建了两个 Pod 副本,分别部署在了 k3s-agent-1k3s-agent-2 上面。

创建 Service

Service,将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。

举个例子,考虑一个图片处理后端,它运行了 3 个副本。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端副本。 然而组成这一组后端程序的 Pod 实际上可能会发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态。

Service 定义的抽象能够解耦这种关联。

Service 有两种类型,一种是 NodePort,选择该种类型的可直接通过 ${serverIP}:${nodePort} 访问内部的服务;另一种是 ClusterIP 类型,它只会在集群内部可以访问到该 Pod,不会把 Pod 的内容映射在某一个外网可以访问的端口上,但这并不意味着不能对外提供服务,而是需要 Ingress 的帮助,来将外网的流量转发到 Service 上来。

NodePort

将以下代码写入 nginx-service-nodeport.yaml

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

这里 nodePort 的范围是 30000-32767

使用如下命令应用:

1
2
root@k3s-server:~/k3s# kubectl apply -f nginx-service-nodeport.yaml 
service/nginx-service created

现在访问 http://10.0.0.39:30080http://10.0.0.31:30080http://10.0.0.32:30080,都可以正常访问到内容:

访问测试

查看 Service:

1
2
3
4
root@k3s-server:~/k3s# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 12h
nginx-service NodePort 10.43.74.219 <none> 80:30080/TCP 7m21s

ClusterIP

Service

将以下代码写入 nginx-service-clusterip.yaml

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80

使用如下命令应用:

1
2
root@k3s-server:~/k3s# kubectl apply -f nginx-service-clusterip.yaml 
service/nginx-service created

这样就创建了 Service,但外部还不能访问,所以需要 Ingress。

Ingress

先做个 DNS 解析:

类型 名称 内容
A *.k3s.abc.com 10.0.0.39
A *.k3s.abc.com 10.0.0.31
A *.k3s.abc.com 10.0.0.32

将以下代码写入 nginx-ingress.yaml

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

使用如下命令应用:

1
2
root@k3s-server:~/k3s# kubectl apply -f nginx-ingress.yaml 
ingress.networking.k8s.io/nginx-ingress created

现在访问 http://nginx.k3s.abc.com 即可访问到部署的服务:

访问测试

尝试关掉 k3s-agent-1

1
root@k3s-agent-1:/home/jiji# shutdown -h now

证实 k3s-agent-1 确实下线了:

1
2
3
4
5
root@k3s-server:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k3s-server Ready control-plane,master 13h v1.24.4+k3s1
k3s-agent-2 Ready <none> 12h v1.24.4+k3s1
k3s-agent-1 NotReady <none> 12h v1.24.4+k3s1

再访问 http://nginx.k3s.abc.com,服务出现不可用,但刷新后也可访问正常。经过两次连续的 ping,我们发现 DNS 解析由原本失效的 10.0.0.31,变为了 10.0.0.39。这也就保证了在 Agent 宕机的情况下服务高可用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ ping nginx.k3s.abc.com

正在 Ping nginx.k3s.abc.com[10.0.0.31] 具有 32 字节的数据:
来自 10.0.0.1 的回复: 无法访问目标主机。
来自 10.0.0.1 的回复: 无法访问目标主机。
来自 10.0.0.1 的回复: 无法访问目标主机。
来自 10.0.0.1 的回复: 无法访问目标主机。

10.0.0.31 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),

$ ping nginx.k3s.abc.com

正在 Ping nginx.k3s.abc.com [10.0.0.39] 具有 32 字节的数据:
来自 10.0.0.39 的回复: 字节=32 时间=3ms TTL=63
来自 10.0.0.39 的回复: 字节=32 时间=5ms TTL=63
来自 10.0.0.39 的回复: 字节=32 时间=5ms TTL=63
来自 10.0.0.39 的回复: 字节=32 时间=12ms TTL=63

10.0.0.39 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 3ms,最长 = 12ms,平均 = 6ms

但当我关闭 k3s-server 的时候,服务出现了不可用,且无自动切换。或许对于高可用 K3s 集群来说,需要至少两台 Server 节点。

HTTPS
1
2
3
root@k3s-server:~# kubectl create secret tls my-tls-secret \
--cert=path/to/cert/file \
--key=path/to/key/file

nginx-ingress.yaml 中追加:

1
2
3
4
5
spec:
tls:
- hosts:
- nginx.k3s.abc.com
secretName: my-tls-secret

K3s集群以及KubePi安装、配置与使用
https://blog.quickso.cn/2025/08/10/K3s集群以及KubePi安装、配置与使用/
作者
木子欢儿
发布于
2025年8月10日
许可协议