K3S 是 Rancher 为物联网(IoT)和边缘计算环境开发的轻量级 Kubernetes 发行版本。相比原生的 Kubernetes,其移除了很多非必要的组件,例如云控制管理器(CCM)、内置的(In-Tree)的存储插件等,以及为 ARM 架构的基础设施做了优化。
K3s 的轻量级同时也体现在其打包成一个二进制可执行文件进行分发,状态存储除了支持 etcd 外,还支持 Sqlite3、MySQl 和 Postgres。其跟多特性可参考官方文档。
K3s 支持单节集群部署(可用于开发测试环境),也支持高可用的多节点集群。同时还可以通过 k3d 项目快速在本地开发环境使用 Docker 容器部署 k3s 集群作为开发环境。
这里我将演示通过虚拟机部署一个高可用的多节点集群(3 个 Servers 节点 + 3 个 Agent 节点)。
k3S 架构
上图是来自 k3s 官网的架构图,其架构与 Kubernetes 的架构是相似的,k3s 的 server 节点也就是控制面节点,agent 节点是工作负载节点。k3s 默认使用 containerd 作为容器运行时。
更信息的部署架构可参考官方文档。
准备虚拟机节点
这里我们将部署 3 + 3 的集群,需要 6 台虚拟机,基本配置如下
部署的最小需求,可参考官方文档。
K3s 支持大部分主流的 Linux 操作系统,这里我使用的是 openSUSE Leap Micro 15.2,其是一个基于 openSUSE,为容器负载而设计的操作系统。
为了部署简单,这里我们禁用了系统的防火墙,如果开启防火墙,需要为 Server 节点开放如下端口
6443/TCP - Kubernetes API 服务
8472/UDP - Flannel VXLAN 模式需要
51820/UDP - Flannel Wireguard 后端需要
10250/TCP - Kubelet metrics 需要
2379-2380/TCP - 基于内嵌 etcd 高可用部署模式需要
启动 Server 节点
首先登陆到第一个 Server 节点 homek3s-server1,然后下载最新版本(v1.24.3+k3s1)的 k3s 二进制文件
# curl -sfL https://github.com/k3s-io/k3s/releases/download/v1.24.3%2Bk3s1/k3s -o /usr/local/bin/k3s
# chmod +x k3s
# k3s --version
k3s version v1.24.3+k3s1 (990ba0e8)
go version go1.18.1
复制代码
k3s 支持一下几个子命令
k3s server - 用于运行管理服务节点
k3s agent - 用于运行 agent 工作节点
k3s kubectl - 运行 kubectl 命令
k3s crictl - 运行 crictl 容器管理命令
其他的命令帮助,请通过 k3s --help
查看。
这里我们将要创建一个使用内置 etcd 数据库的高可用集群,执行如下命令
# k3s server --cluster-init --advertise-address=192.168.0.150 --tls-san=homek3s.mengz.lan --write-kubeconfig-mode=644
复制代码
参数 --cluster-init 是使用内置的 etcd 初始户一个新的集群;
参数 --advertise-address 是指定 API 服务器的监听 IP 地址,如果不指定,默认为节点的 IP 地址;
参数 --tls-san 是指定额外的域名或者 IP 地址作为 TLS 证书的 SAN,使得我们从客户端可通过域名访问而 API 服务器。
运行成功后,在 homek3s-server1 打开另一个终端执行
# k3s kubectl get no
NAME STATUS ROLES AGE VERSION
homek3s-server1 Ready control-plane,etcd,master 27h v1.24.3+k3s1
复制代码
可以看到,集群中以及运行了一个节点,不过这时 k3s 服务是启动在前台的,我们需要配置一个 systemd 服务,让其以服务形式运行。
创建文件 /etc/systemd/system/k3s.service,内如如下
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=-/etc/default/%N
EnvironmentFile=-/etc/sysconfig/%N
EnvironmentFile=-/etc/systemd/system/k3s.service.env
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStart=/usr/local/bin/k3s server
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
复制代码
终止刚才运行的 k3s 进程,然后执行
# systemctl enable --now k3s.server
# systemctl status k3s
● k3s.service - Lightweight Kubernetes
Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2022-07-22 03:31:21 CST; 18h ago
Docs: https://k3s.io
Process: 1121 ExecStartPre=/bin/sh -xc ! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service (code=exited, status=0/SUCCESS)
Main PID: 1129 (k3s-server)
Tasks: 120
CGroup: /system.slice/k3s.service
...
复制代码
这是后 k3s 进程将以服务的形式运行在后台了。
执行完上述步骤后,k3s 将会生产集群的管理员 kubeconfig 文件 - /etc/rancher/k3s/k3s.yaml,可将该文件拷贝的本地环境,修改 server 内容
server: https://127.0.0.1:6443server: https://192.168.0.150:6443
这样就可以在本地主机上使用 kubectl 访问集群了。
接下来,我们将在其他 Server 节点上启动 k3s,并作为管理节点加入集群,首先在第一个节点 homek3s-server1 上获取到集群的 Token
# cat /var/lib/rancher/k3s/server/node-token
K1087c3ff53c94a3c3b20475e84602f1e6d46f1b3903f2979f144800990897b06ac::server:fb8e7aa7ba23d7652942b09cb440ba24
复制代码
SSH 登陆其他 Server 节点(homek3s-server2
和 homek3s-server3
),执行如下步骤
下载相同版本的 k3s 二进制文件到 /usr/local/bin/k3s
执行如下命令加入集群
# k3s server --server=https://192.168.0.150:6443 --token=${NODE_TOKEN}
复制代码
其中 ${NODE_TOKEN} 是上面从第一个节点获取的 Token 内容。
如第一个节点一样,配置 etc/systemd/system/k3s.service,将 k3s 进程启动以服务方式启动。
完成上述步骤后,通过 kubectl 查看节点
❯ k get no
NAME STATUS ROLES AGE VERSION
homek3s-server1 Ready control-plane,etcd,master 28h v1.24.3+k3s1
homek3s-server2 Ready control-plane,etcd,master 27h v1.24.3+k3s1
homek3s-server3 Ready control-plane,etcd,master 27h v1.24.3+k3s1
复制代码
启动 Agent 节点
在启动完 3 个管理节点(Server)的集群之后,我接下来继续添加工作节点(Agent)到集群中,登陆到 3 个 Agent 节点之下如下步骤(3 个节点上的操作相同)
下载相同版本的 k3s 二进制文件到 /usr/local/bin/k3s (方法与 Server 节点上一样)
执行如下命令,以工作节点加入集群
# k3s agent --server=https://192.168.0.150:6443 --token=${NODE_TOKEN}
复制代码
${NODE_TOKEN} 是上面获取的节点 Token 值。
执行成功之后,也需要将 k3s 的 agent 进程以服务方式启动,这里与 Server 节点有些不同,创建文件 /etc/systemd/system/k3s-agent.service,内容如下
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=-/etc/default/%N
EnvironmentFile=-/etc/sysconfig/%N
EnvironmentFile=-/etc/systemd/system/k3s-agent.service.env
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStart=/usr/local/bin/k3s agent --server=${K3S_URL} --token=${K3S_TOKEN}
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
复制代码
然后再创建文件 /etc/systemd/system/k3s-agent.service.env,内容如下
K3S_URL="https://192.168.0.150:6443"
K3S_TOKEN="K1087c3ff58c94a3c3b20475e84602f8e6d46f1b3903f2979f144800990897b06ac::server:fb8e7aa7ba23d7652942b09cb440ba24"
复制代码
注意,将以上的 K3S_TOKEN 替换成你的值。
然后执行
# sysetmctl enable --now k3s-agent.service
复制代码
3 个 Agent 节点都启动完成之后,使用 kubectl 查看节点
❯ k get no
NAME STATUS ROLES AGE VERSION
homek3s-agent1 Ready <none> 27h v1.24.3+k3s1
homek3s-agent2 Ready <none> 26h v1.24.3+k3s1
homek3s-agent3 Ready <none> 26h v1.24.3+k3s1
homek3s-server1 Ready control-plane,etcd,master 28h v1.24.3+k3s1
homek3s-server2 Ready control-plane,etcd,master 27h v1.24.3+k3s1
homek3s-server3 Ready control-plane,etcd,master 27h v1.24.3+k3s1
复制代码
可以看到,我们以及通过 K3S 部署了一个 3+3 的高可用 Kubernetes 集群。
部署应用
成功启动一个 K3S 集群,除了 Kubernetes 必要的组件之外,还自动为集群部署以下组件
Traefik 的 Load Balancer 类型的服务就直接通过每个节点的 80 和 443 端口暴露了
❯ k get svc -n kube-system
traefik LoadBalancer 10.43.66.163 192.168.0.150,192.168.0.151,192.168.0.152,192.168.0.154,192.168.0.155,192.168.0.156 80:30833/TCP,443:32747/TCP 28h
复制代码
因此,我们可以直接创建应用,并通过 Ingress 向外暴露服务,这里我们创建一个简单的 Web 服务,也就是 Docker的教程,创建如下资源文件 docker-tour.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
com.docker.project: tutorial
name: tutorial
spec:
replicas: 1
selector:
matchLabels:
com.docker.project: tutorial
strategy:
type: Recreate
template:
metadata:
labels:
com.docker.project: tutorial
spec:
containers:
- image: docker/getting-started
name: tutorial
ports:
- containerPort: 80
protocol: TCP
resources: {}
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: tutorial
spec:
ports:
- name: 80-tcp
port: 80
protocol: TCP
targetPort: 80
selector:
com.docker.project: tutorial
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tutorial
labels:
com.docker.project: tutorial
spec:
# ingressClassName: contour
rules:
- host: "tour.homek3s.lan"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: tutorial
port:
number: 80
复制代码
然后执行
❯ kubectl apply -f docker-tour.yaml
复制代码
在你的内部 DNS 服务器,或者 /etc/hosts
中配置域名解析,将 tour.homek3s.lan
解析到任何一个节点的 IP 地址,如
192.168.0.150 tour.homek3s.lan
复制代码
通过浏览器访问 https://tour.homek3s.lan/ ,将打开部署的应用。
总结
这里演示了如果通过 K3S 部署一个高可用的 Kubernetes 集群,使用 k3s 内置 etcd 的方式作为入门,k3s 还支持使用外部的数据存储以及其他更多的部署选项,可参考官方文档。K3s 作为一个轻量级的 kubernetes 版本,以了单一的二进制文件 - k3s 进行分发,可以快速部署开发测试,以及边缘生产级别的集群。
后期将会继续探索另一款开源的轻量级 Kubeernets 版本 - K0S。
同时发布在 我的博客
评论