基于OpenEuler部署K3S

介绍

什么是K3s

K3s 是一个轻量级的 Kubernetes 发行版,它针对边缘计算、物联网等场景进行了高度优化。K3s 有以下增强功能:

  • 打包为单个二进制文件。
  • 使用基于 sqlite3 的轻量级存储后端作为默认存储机制。同时支持使用 etcd3、MySQL 和 PostgreSQL 作为存储机制。
  • 封装在简单的启动程序中,通过该启动程序处理很多复杂的 TLS 和选项。
  • 默认情况下是安全的,对轻量级环境有合理的默认值。
  • 添加了简单但功能强大的batteries-included功能,例如:本地存储提供程序,服务负载均衡器,Helm controller 和 Traefik Ingress controller。
  • 所有 Kubernetes control-plane 组件的操作都封装在单个二进制文件和进程中,使 K3s 具有自动化和管理包括证书分发在内的复杂集群操作的能力。
  • 最大程度减轻了外部依赖性,K3s 仅需要 kernel 和 cgroup 挂载。

openeuler社区教程:K3s部署指南 | openEuler社区 | v24.03_LTS

K3s的更多用法可以参考K3s官网

https://rancher.com/docs/k3s/latest/en/

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

K3s官网采用下载对应架构二进制可执行文件的格式,通过install.sh脚本进行离线安装,openEuler社区将该二进制文件的编译过程移植到社区中,并编译出RPM包。此处可通过yum命令直接进行下载安装。

如果你想直接走高可用,请直接跳转到7.高可用K3S(内部etcd),前提是你要所有的机子都部署到了5.1部署K3s才可以开始7.高可用K3S(内部etcd)

主机拓扑

主机名 ip CPU 内存
Server1 192.168.48.101 ≧2 2G
Agent1 192.168.49.102 ≧1 512MB

前期准备

确保server节点及agent节点主机名不一致

1
vi system_init.sh
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
#!/bin/bash
if [ $# -eq 2 ];then
echo "设置主机名为:$1"
echo "ens33设置IP地址为:192.168.48.$2"
else
echo "使用方法:sh $0 主机名 主机位"
exit 2
fi

echo "--------------------------------------"
echo "1.正在设置主机名:$1"
hostnamectl set-hostname $1

echo "2.正在关闭firewalld、selinux"
systemctl disable firewalld &> /dev/null
systemctl stop firewalld
sed -i "s#SELINUX=enforcing#SELINUX=disabled#g" /etc/selinux/config
setenforce 0

echo "3.正在设置ens33:192.168.48.$2"
cat > /etc/sysconfig/network-scripts/ifcfg-ens33 <<EOF
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
NAME=ens33
UUID=53b402ff-5865-47dd-a853-7afcd6521738
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.48.$2
GATEWAY=192.168.48.2
PREFIX=24
DNS1=192.168.48.2
DNS2=114.114.114.114
EOF
nmcli c reload
nmcli c up ens33

echo "4.更新yum源软件包缓存"
yum clean all && yum makecache

echo "5.添加hosts解析"
cat > /etc/hosts <<EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.48.101 Server1
192.168.48.102 Agent1
EOF

echo "6.必备工具安装"
yum install wget psmisc vim net-tools telnet socat device-mapper-persistent-data lvm2 git gcc -y

echo "7.重启系统"
reboot
1
2
3
4
sh system_init.sh 主机名  主机位

[Server1] sh system_init.sh Server1 101
[Agent1] sh system_init.sh Agent1 102

安装containerd

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
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo sed -i 's/\$releasever/8/g' /etc/yum.repos.d/docker-ce.repo
yum clean all && yum makecache
yum install -y containerd

mkdir -p /etc/containerd/certs.d/docker.io
mkdir -p /etc/containerd/certs.d/registry.k8s.io

cat>/etc/containerd/certs.d/docker.io/hosts.toml<<EOF
server = "https://docker.io"

[host."https://docker.m.daocloud.io"]
capabilities = ["pull", "resolve"]
[host."https://docker.xuanyuan.me/"]
capabilities = ["pull", "resolve"]
[host."hhttps://docker.qianyios.top/"]
capabilities = ["pull", "resolve"]
[host."https://reg-mirror.giniu.com"]
capabilities = ["pull", "resolve"]
EOF

cat>/etc/containerd/certs.d/registry.k8s.io/hosts.toml<<EOF
server = "registry.k8s.io"

[host."k8s.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF

containerd config default > /etc/containerd/config.toml
sed -i 's#sandbox_image = "registry.k8s.io/pause:.*"#sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.10"#' /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 重启 containerd 服务
systemctl daemon-reload
systemctl restart containerd.service

安装K3S

部署K3s

由于OpenEuler已经编译好RPM的包了,可以直接安装

操作节点:[所有节点]

1
yum install -y 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
26
27
28
29
mkdir -p /etc/rancher/k3s
cat > /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
docker.io:
endpoint:
- "https://registry.cn-hangzhou.aliyuncs.com/"
- "https://docker.xuanyuan.me"
- "https://docker.m.daocloud.io"
- "https://docker.1ms.run"
- "https://docker.1panel.live"
- "https://hub.rat.dev"
- "https://docker-mirror.aigc2d.com"
- "https://docker.qianyios.top/"
quay.io:
endpoint:
- "https://quay.tencentcloudcr.com/"
registry.k8s.io:
endpoint:
- "https://registry.aliyuncs.com/v2/google_containers"
gcr.io:
endpoint:
- "https://gcr.m.daocloud.io/"
k8s.gcr.io:
endpoint:
- "https://registry.aliyuncs.com/google_containers"
ghcr.io:
endpoint:
- "https://ghcr.m.daocloud.io/"
EOF

安装好后在这里打个快照,后面讲高可用会用到

部署server节点

操作节点:[Server1]

如需在单个服务器上安装 K3s,可以在 server 节点上执行如下操作:

1
2
3
4
INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_REGISTRIES="https://registry.cn-hangzhou.aliyuncs.com,https://registry.aliyuncs.com/google_containers" \
k3s-install.sh \
--system-default-registry "registry.cn-hangzhou.aliyuncs.com"

image-20250604204942034

查看镜像列表和pod情况

1
2
crictl images
kubectl get pod -A

image-20250606143307535

部署Agent节点

操作节点:[Server1]

查看token

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

K10ed18fcd528981577fe508d419bd28fefeef1c372ccc246a79fff1fa4b371e5e1::server:a02d22a5169cdc2465bd989360029283

操作节点:[Agent1]

1
2
3
4
5
INSTALL_K3S_SKIP_DOWNLOAD=true \
K3S_URL=https://192.168.48.101:6443 \
K3S_TOKEN=a02d22a5169cdc2465bd989360029283 \
INSTALL_K3S_REGISTRIES="https://registry.cn-hangzhou.aliyuncs.com,https://registry.aliyuncs.com/google_containers" \
k3s-install.sh

· a02d22a5169cdc2465bd989360029283 是前面server1获取的token

· 192.168.48.101server1的ip

image-20250607175545654

安装dashboard

操作节点:[Server1]

1
2
3
4
5
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
sed -i 's/kubernetesui\/dashboard:v2.7.0/registry.cn-hangzhou.aliyuncs.com\/qianyios\/dashboard:v2.7.0/g' recommended.yaml
sed -i 's/kubernetesui\/metrics-scraper:v1.0.8/registry.cn-hangzhou.aliyuncs.com\/qianyios\/metrics-scraper:v1.0.8/g' recommended.yaml
sed -i '/targetPort: 8443/a\ nodePort: 30001' recommended.yaml
sed -i '/nodePort: 30001/a\ type: NodePort' recommended.yaml

运行pod

1
kubectl apply -f recommended.yaml

创建token

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
#创建service account并绑定默认cluster-admin管理员群角色
#创建用户
kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard
#用户授权
kubectl create clusterrolebinding dashboard-admin \
--clusterrole=cluster-admin \
--serviceaccount=kubernetes-dashboard:dashboard-admin
#临时获取用户Token(默认只有 30 分钟 )
kubectl create token dashboard-admin -n kubernetes-dashboard
#永久获取用户Token
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: dashboard-admin-token
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: dashboard-admin
type: kubernetes.io/service-account-token
EOF

KUBECONFIG_FILE="dashboard-kubeconfig.yaml"

# 自动获取 API Server 地址
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')

# 自动获取 CA 证书
CA_CERT=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')

# 自动从 Secret 获取 Token(你提到的正确方式)
TOKEN=$(kubectl get secret dashboard-admin-token -n kubernetes-dashboard -o jsonpath='{.data.token}' | base64 --decode)

# 生成 kubeconfig 文件
cat <<EOF > ${KUBECONFIG_FILE}
apiVersion: v1
kind: Config
clusters:
- name: kubernetes
cluster:
server: ${APISERVER}
certificate-authority-data: ${CA_CERT}
users:
- name: dashboard-admin
user:
token: ${TOKEN}
contexts:
- name: dashboard-context
context:
cluster: kubernetes
user: dashboard-admin
current-context: dashboard-context
EOF

echo "✅ kubeconfig 文件已生成:${KUBECONFIG_FILE}"

这时候就会提示你

✅ kubeconfig 文件已生成:dashboard-kubeconfig.yaml

你就把这个文件上传到dashboard的kubeconfig就可以免密登入了

image-20250607185120057

高可用K3S(内部etcd)

官方教程:高可用嵌入式 etcd

具有嵌入式 etcd 的 HA K3s 集群由以下部分组成:

  • 三个或多个 Server 节点为 Kubernetes API 提供服务并运行其他 control plane 服务,以及托管嵌入式 etcd 数据存储。
  • 可选:零个或多个 Agent 节点,用于运行你的应用和服务
  • 可选:固定注册地址,供 Agent 节点注册到集群

主机拓扑

主机名 ip CPU 内存
Server1 192.168.48.101 ≧2 2G
Server2 192.168.48.102 ≧2 2G
Server3 192.168.48.103 ≧2 2G
Agent1 192.168.49.104 ≧1 512MB

现在所有的机子都从5.1部署K3s克隆这个部署好K3s的快照,也就是说现在所有机子的起点都在5.1部署K3s

记得给agent改ip哈

初始化第一个Server1

操作节点:[Server1]

1
2
3
4
5
6
K3S_TOKEN=qianyiosQianyios12345 \
INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_REGISTRIES="https://registry.cn-hangzhou.aliyuncs.com,https://registry.aliyuncs.com/google_containers" \
k3s-install.sh --cluster-init - server \
--system-default-registry "registry.cn-hangzhou.aliyuncs.com" \
--tls-san= 192.168.48.200

qianyiosQianyios12345是作为集群间的共享密钥,可自定义

其他server加入集群

1
2
3
4
5
6
7
K3S_TOKEN=qianyiosQianyios12345 \
INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_REGISTRIES="https://registry.cn-hangzhou.aliyuncs.com,https://registry.aliyuncs.com/google_containers" \
k3s-install.sh - server \
--system-default-registry "registry.cn-hangzhou.aliyuncs.com" \
--server https://192.168.48.101:6443 \
--tls-san= 192.168.48.200

qianyiosQianyios12345是作为第一个server1共享出来的密钥

–server https://192.168.48.101:6443 改成serve1的ip地址计科

其他Agent加入集群

1
2
3
4
5
INSTALL_K3S_SKIP_DOWNLOAD=true \
K3S_TOKEN=qianyiosQianyios12345 \
K3S_URL=https://192.168.48.101:6443 \
INSTALL_K3S_REGISTRIES="https://registry.cn-hangzhou.aliyuncs.com,https://registry.aliyuncs.com/google_containers" \
k3s-install.sh - agent

这时候在Server可以查看node情况

1
kubectl get nodes

image-20250607215850489

配置集群负载均衡器

官方教程:集群负载均衡器

按理来说我们需要两台额外的节点来做负载均衡和高可用vip节点,但是为了测试方便,我们直接部署在

server节点,也就是图中的第二种方法

image-20250607223109712

操作节点:[所有的server]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
yum install -y haproxy keepalived
cat > /etc/haproxy/haproxy.cfg <<"EOF"
frontend k3s-frontend
bind *:16443
mode tcp
option tcplog
default_backend k3s-backend

backend k3s-backend
mode tcp
option tcp-check
balance roundrobin
timeout connect 5s
timeout server 30s
timeout client 30s
default-server inter 10s downinter 5s
server server-1 192.168.48.101:6443 check
server server-2 192.168.48.102:6443 check
server server-3 192.168.48.103:6443 check
EOF

操作节点:[Server1]

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
cat > /etc/keepalived/keepalived.conf <<"EOF"
global_defs {
enable_script_security
script_user root
}

vrrp_script chk_haproxy {
script 'killall -0 haproxy'
interval 2
}

vrrp_instance haproxy-vip {
interface ens33 #这里要改,是你的网卡
state MASTER #这里要改 server1是Master 其他都是Backup
priority 200

virtual_router_id 51

virtual_ipaddress {
192.168.48.200/24 #高可用ip
}

track_script {
chk_haproxy
}
}
EOF

操作节点:[Server2]

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
cat > /etc/keepalived/keepalived.conf <<"EOF"
global_defs {
enable_script_security
script_user root
}

vrrp_script chk_haproxy {
script 'killall -0 haproxy'
interval 2
}

vrrp_instance haproxy-vip {
interface ens33 #这里要改,是你的网卡
state BACKUP #这里要改 server1是Master 其他都是Backup
priority 150

virtual_router_id 51

virtual_ipaddress {
192.168.48.200/24 #高可用ip
}

track_script {
chk_haproxy
}
}
EOF

操作节点:[Server3]

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
cat > /etc/keepalived/keepalived.conf <<"EOF"
global_defs {
enable_script_security
script_user root
}

vrrp_script chk_haproxy {
script 'killall -0 haproxy'
interval 2
}

vrrp_instance haproxy-vip {
interface ens33 #这里要改,是你的网卡
state BACKUP #这里要改 server1是Master 其他都是Backup
priority 100

virtual_router_id 51

virtual_ipaddress {
192.168.48.200/24 #高可用ip
}

track_script {
chk_haproxy
}
}
EOF

操作节点:[所有的Server]

1
systemctl restart haproxy keepalived

现在来查看vip是否生成

操作节点:[Server1]

1
ip a

image-20250607224346215

自行部署dashboard之后,查看他在哪个节点上

1
https://192.168.48.200:30001/

现在不是有高可用的vip吗。那么正好可以用vip访问,端口不变

image-20250607224828394

高可用模拟宕机测试

查看dashboard部署在哪个节点

1
kubectl get pods -A -l k8s-app=kubernetes-dashboard -o wide

我这里显示的是dashboard部署在Server2

那么我们就对Server2进行powerof关机,来模拟宕机看看dashboard能否被k3s自动调度到其他节点

但是我发现pod还在running的状态

1
2
3
4
5
6
7
8
9
10
11
12
[root@Server3 ~]# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kubernetes-dashboard kubernetes-dashboard-668679b698-nlpqc 1/1 Running 0 15m

[root@Server3 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
agent1 Ready <none> 35m v1.24.2+k3s-
server1 Ready control-plane,etcd,master 36m v1.24.2+k3s-
server2 NotReady control-plane,etcd,master 36m v1.24.2+k3s-
server3 Ready control-plane,etcd,master 36m v1.24.2+k3s-
[root@Server3 ~]#

server2 已经被标记为 NotReady

说明 Kubernetes 已感知到它不可用(可能是关机、网络不通或 kubelet 崩溃等),但:

  • 如果 Pod 的副本数是 1,Kubernetes 不会自动创建新的 Pod
  • 默认的节点失联容忍时间较长(5分钟),所以即使节点 NotReady,也不会立刻触发 Pod 驱逐。

方案一 等待五分钟

经过漫长等待,dashboard的pod进行了重新分配

image-20250607230458318

1
kubectl get pods -A -l k8s-app=kubernetes-dashboard -o wide

经过查看已经被调度到了Server3节点

结论:高可用实验,实验成功,且页面可以正常访问

方案二 手动删除 Pod 强制重建(推荐测试)

由于刚刚经过方案一的测试,被调度到了server3,所以这次对server3进行模拟宕机,然后手动删除pod

1
kubectl delete pod -n kubernetes-dashboard pod名字

image-20250607231149105

经过手动删除,立马触发自动调度,已经被调度到了Server2节点

结论:高可用实验,实验成功,且页面可以正常访问

方案三 缩短节点失联容忍时间(适用于生产环境)

如果你希望 Kubernetes 更快地响应节点故障,可以在 K3s 启动参数中添加以下内容:

1
2
--node-monitor-grace-period=20s \
--pod-eviction-timeout=30s

⚠️ 注意:这会影响整个集群的行为,适用于生产环境或需要快速故障恢复的场景。

卸载K3S

官方教程:Uninstalling K3s | K3s

卸载Server

要从服务器节点卸载 K3s,请运行:

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

卸载Agent

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

1
/usr/local/bin/k3s-agent-uninstall.sh
特别声明
千屹博客旗下的所有文章,是通过本人课堂学习和课外自学所精心整理的知识巨著
难免会有出错的地方
如果细心的你发现了小失误,可以在下方评论区告诉我,或者私信我!
非常感谢大家的热烈支持!