单机部署K3s服务并接入Kuboard

在Kubernetes上做实验或者写一些自己的小工具时,通常要搭建一个环境用来学习,采用K3s的方式在单机服务器上搭建一套环境是占用资源较少的方式,并且配置上Kuboard进行管理后会更容易操作。本文就记录下环境搭建的步骤。

环境准备

这里采用一台2C、2G配置的腾讯云 22.04.5 LTS (Jammy Jellyfish) 云主机进行,环境为初始化系统,未安装任何服务。

1、先进行系统更新,保证系统内版本是最新的。

1
apt update && apt upgrade -y && apt autoremove -y && reboot

2、安装Docker 25.0.5
这里我选择安装Docker 25.0.5版本作为K3s安装的runtime。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ apt install apt-transport-https ca-certificates curl gnupg lsb-release -y
$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/ \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

$ apt update

#查找可用的docker版本
$ apt-cache madison docker-ce

# 安装Docker
$ apt install docker-ce=5:25.0.5-1~ubuntu.22.04~jammy docker-ce-cli=5:25.0.5-1~ubuntu.22.04~jammy containerd.io -y

3、确认Dokcer安装完成

1
2
3
$ systemctl status docker

$ docker info

4、配置成稳定的Dokcer镜像源

1
2
3
4
5
6
7
8
9
$ sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io"
]
}
EOF
$ systemctl daemon-reload
$ systemctl restart docker

K3S部署

K3s社区已经将所需的K3s资源都同步到了国内的服务器上,可以使用这些国内资源在国内环境上安装K3s,提升了安装速度的同时也提升了安装的稳定性。K3s默认使用containerd作为容器runtime,这里进行修改,选择Docker作为容器runtime。

1、执行安装脚本,使用Docker作为runtime,并设置默认registry地址为registry.cn-hangzhou.aliyuncs.com。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 使用Docker作为runtime,使用该命令
$ curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - --docker --system-default-registry "registry.cn-hangzhou.aliyuncs.com"

# 默认使用containerd作为runtime,使用该命令
$ 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"

[INFO] Finding release for channel stable
[INFO] Using v1.31.6+k3s1 as release
[INFO] Downloading hash rancher-mirror.rancher.cn/k3s/v1.31.6-k3s1/sha256sum-amd64.txt
[INFO] Downloading binary rancher-mirror.rancher.cn/k3s/v1.31.6-k3s1/k3s
[INFO] Verifying binary download
[INFO] Installing k3s to /usr/local/bin/k3s
[INFO] Skipping installation of SELinux RPM
[INFO] Creating /usr/local/bin/kubectl symlink to k3s
[INFO] Creating /usr/local/bin/crictl symlink to k3s
[INFO] Skipping /usr/local/bin/ctr symlink to k3s, command exists in PATH at /usr/bin/ctr
[INFO] Creating killall script /usr/local/bin/k3s-killall.sh
[INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO] env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO] systemd: Creating service file /etc/systemd/system/k3s.service
[INFO] systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO] systemd: Starting k3s

2、可以等待几分钟后,再查看K3s工作状态:

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
$ systemctl status k3s
● k3s.service - Lightweight Kubernetes
Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2025-03-27 00:21:18 CST; 3min ago
Docs: https://k3s.io
Process: 26559 ExecStartPre=/bin/sh -xc ! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service 2>/dev/null (code=exited, status=0/SUCCESS)
Process: 26561 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
Process: 26562 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 26563 (k3s-server)
Tasks: 16
Memory: 483.3M
CPU: 21.133s
CGroup: /system.slice/k3s.service
├─26563 "/usr/local/bin/k3s server" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">
└─28640 "/usr/local/bin/k3s server" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">

$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-7f9dc8d998-jl8q8 1/1 Running 0 93s
kube-system helm-install-traefik-crd-4v5w2 0/1 Completed 0 93s
kube-system helm-install-traefik-tjs4j 0/1 Completed 2 93s
kube-system local-path-provisioner-864d7dff5d-5rph4 1/1 Running 0 93s
kube-system metrics-server-69969b57cb-k7g2q 1/1 Running 0 93s
kube-system svclb-traefik-98e2a50a-h5n6s 2/2 Running 0 34s
kube-system traefik-57d9d494d7-x52jb 1/1 Running 0 34s

3、同时可以在Docker中查看image和container变化:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-hangzhou.aliyuncs.com/rancher/mirrored-library-traefik 2.11.20 d7d7095a482f 7 weeks ago 178MB
registry.cn-hangzhou.aliyuncs.com/rancher/local-path-provisioner v0.0.31 8309ed19e06b 2 months ago 60.4MB
registry.cn-hangzhou.aliyuncs.com/rancher/klipper-helm v0.9.4-build20250113 cf1d4e2d0dbd 2 months ago 190MB
....

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
624e32c551a8 registry.cn-hangzhou.aliyuncs.com/rancher/mirrored-library-traefik "/entrypoint.sh --gl…" 5 minutes ago Up 5 minutes k8s_traefik_traefik-57d9d494d7-x52jb_kube-system_1562282c-dbdb-490b-bf7e-85a6e4ebc251_0
f1a36596c826 b82360cf0b97 "entry" 5 minutes ago Up 5 minutes k8s_lb-tcp-443_svclb-traefik-98e2a50a-h5n6s_kube-system_2e314526-1424-4989-9dea-09023c830c05_0
ecdd527845ce registry.cn-hangzhou.aliyuncs.com/rancher/klipper-lb "entry" 5 minutes ago Up 5 minutes k8s_lb-tcp-80_svclb-traefik-98e2a50a-h5n6s_kube-system_2e314526-1424-4989-9dea-09023c830c05_0
......

containerd

1、如果是选择containerd作为容器runtime,则还要配置k3s containerd的镜像源并重启K3s,K3s启动时会检查/etc/rancher/k3s/中是否存在registries.yaml文件,并指示containerd使用文件中定义的镜像仓库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ cat >> /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"docker.io":
endpoint:
- "https://docker.m.daocloud.io"
EOF

$ systemctl restart k3s

# 确认镜像配置
$ cat /var/lib/rancher/k3s/agent/etc/containerd/certs.d/docker.io/hosts.toml
mirrors:
"docker.io":
endpoint:
- "https://docker.m.daocloud.io"

# 查看k3s containerd 的 socket
$ ls -lrt /run/k3s/containerd/containerd.sock
srw-rw---- 1 root root 0 Mar 27 01:29 /run/k3s/containerd/containerd.sock

2、containerd提供ctr和crictl工具,查看k3s containerd拉取的镜像:

1
2
3
4
5
6
7
8
9
10
11
$ k3s ctr image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
registry.cn-hangzhou.aliyuncs.com/rancher/klipper-helm:v0.9.4-build20250113 application/vnd.oci.image.index.v1+json sha256:6b33b9efa5b89c2606e777b137e9959fbcd4364501d19c0c746d0cc8f32026d9 67.2 MiB linux/amd64,linux/arm,linux/arm64/v8 io.cri-containerd.image=managed
......


$ crictl image ls
root@VM-8-16-ubuntu:/home/ubuntu# crictl image ls
IMAGE TAG IMAGE ID SIZE
registry.cn-hangzhou.aliyuncs.com/rancher/klipper-helm v0.9.4-build20250113 cf1d4e2d0dbd1 70.4MB
......

3、对于习惯使用Docker的小伙伴来说,ctr和crictl的操作和Docker还是有所区别,这里可以使用nerdctl与K3s集成,nerdctl是一个与Docker cli风格兼容的containerd客户端工具,而且直接兼容docker compose的语法。
1)下载nerdctl并解压

1
2
3
$ wget https://github.com/containerd/nerdctl/releases/download/v2.0.4/nerdctl-full-2.0.4-linux-amd64.tar.gz

$ tar -xvf nerdctl-full-2.0.4-linux-amd64.tar.gz

2)nerdctl操作K3s自带的containerd,注意此处必须额外指定--namespace=k8s.io

1
2
3
4
5
6
7
8
9
$ ./bin/nerdctl -H /run/k3s/containerd/containerd.sock --namespace=k8s.io images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
registry.cn-hangzhou.aliyuncs.com/rancher/mirrored-library-traefik <none> 21f5c16b2215 22 hours ago linux/amd64 180.4MB 49.45MB
<none> <none> 21f5c16b2215 22 hours ago linux/amd64 180.4MB 49.45MB
........

$ ./bin/nerdctl -H /run/k3s/containerd/containerd.sock --namespace=k8s.io ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7db864ef1a2c registry.cn-hangzhou.aliyuncs.com/rancher/mirrored-library-traefik:2.11.20 "/entrypoint.sh --gl…" 22 hours ago Up k8s://kube-system/traefik-57d9d494d7-wn6nx/traefik

Pod测试

服务部署好以后,这里通过启动一个nginx pod来验证是否可以正常使用
1、编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ cat nginx-deployment.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.26.3

2、创建deployment并查看pod

1
2
3
4
5
6
$ kubectl apply -f nginx-deployment.yml 
deployment.apps/nginx-deployment created

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-74bd454fc9-kqjnj 1/1 Running 0 41s

到这里就说明服务OK,可以正常使用,但通过命令操作起来仍然是相对繁琐的,接下来安装Kuboard来管理刚部署的K3s服务。

Kuboard接入

1、创建一个脚本,并执行Kuboard的部署:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$cat kuboard-install.sh 
docker run -itd \
--restart=unless-stopped \
--name=kuboard \
-p 18080:80/tcp \
-p 10081:10081/tcp \
-e KUBOARD_ENDPOINT="http://{内网IP}:80" \
-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
-v /root/kuboard-data:/data \
eipwork/kuboard:v3

$ sh kuboard-install.sh

$ docker ps -a | grep kuboard
ae14cf2e2ae5 eipwork/kuboard:v3 "/entrypoint.sh" 13 seconds ago Up 12 seconds 443/tcp, 0.0.0.0:10081->10081/tcp, :::10081->10081/tcp, 0.0.0.0:18080->80/tcp, :::18080->80/tcp kuboard

# 通过logs确认kuboard启动正常
$ docker logs kuboard

Kuboard安装完成后的默认口令是:admin/Kuboard123

该口令目前是弱口令,建议安装完成后,立即在个人设置中进行修改。

2、在腾讯云主机防火墙上新建一条放行策略,允许访问云主机的18080端口,并通过默认口令登录。

3、点击添加集群,可以看到支持通过Token、KuboConfig、Kuboard Agent三种方式添加Kubernetes 集群。这里我选择Token方式,按照操作说明添加即可。

4、添加完成后,即可在Kuboard中进行各种操作了。

参考

1、https://docs.rancher.cn/docs/k3s/quick-start/_index
2、https://forums.rancher.cn/t/k3s/1416
3、https://kuboard.cn/install/v3/install-built-in.html
4、https://docs.rancher.cn/docs/k3s/installation/private-registry/_index/
5、https://docs.k3s.io/installation/private-registry
6、https://github.com/containerd/nerdctl/issues/128#issuecomment-803544231