Skip to content

第12章-轻量k8s平台-边缘计算-k3s

本章所讲内容:

12.1 k3s 核心技术解读?

12.2 k3s 架构分析

12.3 安装 k3s 集群:初始化配置

12.4 安装 k3s server 和 agent

12.5 k3s 中部署 Guestbook 留言板

12.6 卸载 k3s 集群

12.7 k3s 高可用集群安装

实验环境:新创建三台虚拟机

K3s server 机器配置:

​ IP:192.168.2.207

​ 主机名:k3s-master01

​ IP:192.168.2.208

​ 主机名:k3s-master02

K3s agent 机器配置:

​ IP:192.168.2.209

​ 主机名:k3s-node01

12.1 k3s 核心技术解读?

12.1.1 什么是 k3s?

​ 官网:https://docs.rancher.cn/docs/k3s/_index/

​ github 地址:https://github.com/k3s-io/k3s

​ K3s 是一个轻量级的 Kubernetes 发行版,专为资源受限的环境和边缘计算场景而设计。Kubernetes 是一个用于容器编排和管理的开源平台,但它在某些场景下可能过于复杂和资源消耗大。K3s 旨在提供一个Kubernetes 解决方案,具有更小的二进制文件大小和更低的系统资源需求。

​ K3s 保留了 Kubernetes 的核心功能,但去除了一些不常用的组件和依赖项,以减小系统的占用空间和内存消耗。它还采用了更轻量级的容器运行时,如 containerd 或者 tiny Container Runtime Interface (CRI)实现,而不是传统的 Docker 引擎。

​ K3s 的设计目标是简化安装和部署过程,使得在边缘设备、嵌入式系统或资源受限的环境中更容易运行 Kubernetes 集群。它可以在单节点或多节点集群中运行,并提供与标准 Kubernetes 相似的 API 和命令行工具,使得现有的 Kubernetes 应用程序可以无缝迁移到 K3s 上。

12.1.2 适用场景

K3s 适用于多种场景,特别是那些资源受限、边缘计算或需要快速部署和管理的环境。以下是一些适合使用 K3s 的场景:

1、边缘计算:K3s 适用于在边缘设备、物联网设备或边缘节点上运行 Kubernetes 集群。由于 K3s

的轻量级设计和低资源需求,它可以在资源有限的设备上高效运行,并提供容器编排和管理的能力。

2、嵌入式系统:K3s 可以在嵌入式系统中使用,这些系统通常具有受限的硬件资源和操作系统约束。它可以在这些设备上部署和管理容器化应用程序,同时保持较低的内存和磁盘占用。

3、开发和测试环境:K3s 可以用作开发和测试环境中的轻量级 Kubernetes 解决方案。由于它的快速安装和部署过程,开发人员可以更快地创建本地或虚拟机上的 Kubernetes 集群,以进行应用程序的开发、测试和调试。

4、小型和中小型企业:对于资源有限的小型和中小型企业,K3s 提供了一个简化的 Kubernetes 解决方案。它降低了对硬件和系统资源的要求,同时提供了容器编排和管理的能力,使得企业可以在自己的环境中运行和管理应用程序。

12.2 k3s 架构分析

12.2.1 单节点的 k3s 架构

image-20230917114522170

​ K3s 支持在单节点上运行,即将整个 Kubernetes 集群部署在单个节点上。这种架构适用于一些简单的开发、测试或学习场景,以及某些边缘计算环境。下面是单节点 K3s 架构的一般配置:

  1. 主节点(Master Node):单节点架构下,该节点兼具主节点和工作节点的角色。主节点负责 管理整个集群的状态和控制平面操作,包括调度容器、监控资源、维护集群状态等。它运行 K3s 的服务端组件,如 kube-apiserver、kube-controller-manager、kube-scheduler 等。

  2. 容器运行时(Container Runtime):K3s 可以使用多种容器运行时,如 containerd、tiny Container Runtime Interface(CRI)等。容器运行时负责在主节点上运行和管理容器,提供容 器的隔离和资源管理功能。

  3. 代理节点(Agent Node):在单节点架构下,主节点兼具代理节点的功能。代理节点运行 K3s 的客户端组件,如 kubelet 和 kube-proxy,它们与主节点上的服务端组件进行通信,并负责在 主节点上启动和管理容器。

​ 在单节点架构中,K3s 的主节点和代理节点运行在同一台机器上,共享系统资源。这种架构可以简化部署过程,并节省硬件资源。然而,需要注意的是,由于整个 Kubernetes 集群运行在单个节点上,它没有高可用性和容错能力。如果主节点发生故障,整个集群将不可用。

12.2.2 高可用的 k3s 架构

image-20230917114802079

要实现高可用性的 K3s 架构,可以将 K3s 集群配置为多节点集群,这样可以在主节点故障时保持集 群的可用性。以下是一个高可用的 K3s 架构示例:

  1. 主节点(Master Node):主节点是 K3s 集群的控制平面,负责管理整个集群的状态和操作。 为了实现高可用性,可以将多个主节点配置为主-主模式或主-备模式。每个主节点运行 K3s 的服 务端组件,如 kube-apiserver、kube-controller-manager、kube-scheduler 等。主节点之 间通过内部通信协议进行状态同步和数据复制。
  2. 工作节点(Worker Node):工作节点负责运行容器和处理应用程序的工作负载。它们接收主 节点的指令并运行相应的容器。可以有多个工作节点加入到 K3s 集群中,提供扩展性和负载均 衡。
  3. 负载均衡器(Load Balancer):为了实现高可用性和负载均衡,可以在主节点之前引入负载均 衡器。负载均衡器将入口流量分发到多个主节点上,实现请求的负载均衡和故障转移。常用的负 载均衡器有 Nginx、HAProxy 等。 4. 存储系统(Storage System):K3s 需要一个共享存储系统,用于存储持久化数据和共享卷。 可以使用网络存储解决方案,如 NFS、Ceph 等,来提供共享存储服务。

​ 通过将 K3s 集群配置为高可用架构,可以确保在主节点故障时仍然保持集群的可用性和稳定性。当一 个主节点发生故障时,其他主节点可以接管集群的管理职责,并确保应用程序的正常运行。

需要注意的是,高可用的 K3s 架构会增加一些复杂性和资源需求,包括更多的节点和网络负载。因 此,在设计和部署高可用 K3s 架构之前,需要评估系统需求和可用资源,并根据实际情况进行规划和配 置。

12.3 安装 k3s 集群:初始化配置

192.168.2.207 :主机名设置成 k3s-master01

192.168.2.208 :主机名设置成 k3s-master02

192.168.2.209 : 主机名设置成 k3s-node01

下面 12.3.* 的步骤都在 所有节点 上操作

12.3.0 修改主机名

$ hostnamectl set-hostname k3s-master01 && bash
$ hostnamectl set-hostname k3s-master02 && bash
$ hostnamectl set-hostname k3s-node01 && bash

12.3.1 修改 yum 源

配置安装 k3s 需要的 yum 源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF

添加安装 docker 和 containerd 需要的 yum 源

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

12.3.2 配置防火墙

关闭 firewalld 防火墙, centos7 系统默认使用的是 firewalld 防火墙,停止 firewalld 防火墙, 并禁用这个服务。

systemctl stop firewalld && systemctl disable firewalld

12.3.3 时间同步

ntpdate cn.pool.ntp.org

编辑计划任务,每小时做一次同步

1)crontab -e

* * * * * /usr/sbin/ntpdate cn.pool.ntp.org 

2)重启 crond 服务:

systemctl restart crond

12.3.4 关闭 selinux

关闭 selinux,设置永久关闭,这样重启机器 selinux 也处于关闭状态

可用下面方式修改:

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

上面文件修改之后,需要重启虚拟机,如果测试环境可以用如下命令强制重启:

reboot -f

12.3.5 修改内核参数

$ modprobe br_netfilter

$ cat > /etc/sysctl.d/k8s.conf <<EOF 
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

$ sysctl -p /etc/sysctl.d/k8s.conf

12.3.6 配置 hosts 文件

所有的 hosts 文件保持一致,可按如下方法修改:

在/etc/hosts 文件增加如下几行:

192.168.2.207 k3s-master01 k3-m1
192.168.2.208 k3s-master02 k3-m2
192.168.2.209 k3s-node01   k3-n1

配置所有节点免密

$ ssh-keygen -t rsa -b 2048
$ ssh-copy-id 192.168.2.207
$ ssh-copy-id 192.168.2.208
$ ssh-copy-id 192.168.2.209

12.3.7 安装 containerd 容器运行时

1、安装 containerd

yum install containerd.io-1.6.6 -y

2、生成 containerd 的配置文件:

mkdir -p /etc/containerd

containerd config default > /etc/containerd/config.toml

3、修改配置文件:

vim /etc/containerd/config.toml
SystemdCgroup = false 修改成
            SystemdCgroup = true

sandbox_image = "k8s.gcr.io/pause:3.6"修改成
    sandbox_image="registry.aliyuncs.com/google_containers/pause:3.7"

4、配置 containerd 开机启动,并启动

systemctl enable containerd --now

5、安装 crictl 命令

tar zxvf crictl-v1.24.2-linux-amd64.tar.gz -C /usr/local/bin/

6、修改 crictl 配置文件

cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false 
EOF

7、重启 containerd 服务,使配置生效

systemctl restart containerd

12.4 安装k3s server 和agent

1、安装k3s server

在 k3s-master01 上操作:

curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

验证安装是否成功

$ kubectl get node
NAME           STATUS   ROLES                  AGE   VERSION
k3s-master01   Ready    control-plane,master   14m   v1.27.5+k3s1


$ kubectl get pod -n kube-system
NAME                                     READY   STATUS      RESTARTS       AGE
helm-install-traefik-crd-b5xzd           0/1     Completed   1              15m
coredns-77ccd57875-4fcdt                 1/1     Running     4 (114s ago)   15m
helm-install-traefik-6trhd               0/1     Completed   6              15m
local-path-provisioner-957fdf8bc-gc665   1/1     Running     2 (76s ago)    15m
svclb-traefik-8d9a45b5-bjbxk             2/2     Running     0              74s
traefik-64f55bb67d-ncp5k                 1/1     Running     0              74s
metrics-server-648b5df564-6rd6t          1/1     Running     6 (75s ago)    15m

显示如上:

2、把 k3s-node01 添加到 k3s 集群

k3s-master01 提取 join token

$ cat /var/lib/rancher/k3s/server/node-token
K10305d115f63008004fd568760c347e0c0bffaba275fcd36d5de6ea971fb37cf35::server:3eb41696cfa4ca97bda06528f35b0b64

k3s-node01 加入k3s:

curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.2.207:6443 K3S_TOKEN=K10305d115f63008004fd568760c347e0c0bffaba275fcd36d5de6ea971fb37cf35::server:3eb41696cfa4ca97bda06528f35b0b64 sh -

验证 work 节点是否加入集群:

$ kubectl get nodes
NAME           STATUS   ROLES                  AGE   VERSION
k3s-master01   Ready    control-plane,master   20m   v1.27.5+k3s1
k3s-node01     Ready    <none>                 45s   v1.27.5+k3s1

显示如上,说明工作节点成功加入 k3s 集群:

12.5 在k3s 搭建的 k8s 中部署Guestbook 留言板

img

1、导入镜像

上传镜像到所有节点

各个通过 ctr 解压镜像:

$ ctr -n=k8s.io images import frontend.tar.gz 
$ ctr -n=k8s.io images import redis-master.tar.gz 
$ ctr  -n=k8s.io  images import redis-slave.tar.gz 

2、部署Guestbook

控制节点上操作,基于yaml文件创建资源对象

$ vim redis-master-deployment.yaml 

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: redis-master
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: master
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: docker.io/kubeguide/redis-master:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
$ kubectl apply -f redis-master-deployment.yaml
$ vim redis-master-service.yaml 

apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    app: redis
    role: master
    tier: backend
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: master
    tier: backend
$ kubectl apply -f redis-master-service.yaml 
$ vim redis-slave-deployment.yaml

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: redis-slave
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: slave
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: slave
        tier: backend
    spec:
      containers:
      - name: slave
        image: docker.io/kubeguide/guestbook-redis-slave:latest
        imagePullPolicy: IfNotPresent
        env:
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 6379
$ kubectl apply -f redis-slave-deployment.yaml
$ vim redis-slave-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: redis-slave
  labels:
    app: redis
    role: slave
    tier: backend
spec:
  ports:
  - port: 6379
  selector:
    app: redis
    role: slave
    tier: backend
$ kubectl apply -f redis-slave-service.yaml
$ vim frontend-deployment.yaml

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: frontend
  labels:
    app: guestbook
spec:
  selector:
    matchLabels:
      app: guestbook
      tier: frontend
  replicas: 1
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: docker.io/kubeguide/guestbook-php-frontend:latest
        imagePullPolicy: IfNotPresent
        env:
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 80
$ kubectl apply -f frontend-deployment.yaml 
$ vim frontend-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  type: NodePort 
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30001
  selector:
    app: guestbook
    tier: frontend
$ kubectl apply -f frontend-service.yaml 

验证

查看刚才创建的应用是否正常

$ kubectl get pod 
NAME                            READY   STATUS    RESTARTS   AGE
redis-master-776dd7b474-c6fd8   1/1     Running   0          4m22s
redis-slave-588bfbb76f-rgktw    1/1     Running   0          28s
frontend-777c74bdc6-9phj8       1/1     Running   0          29s

查看对应的 service

$ kubectl get svc
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP   10.43.0.1       <none>        443/TCP        63m
redis-master   ClusterIP   10.43.63.63     <none>        6379/TCP       4m8s
frontend       NodePort    10.43.126.81    <none>        80:30001/TCP   44s
redis-slave    ClusterIP   10.43.223.117   <none>        6379/TCP       43s

在浏览器访问 frontend 在宿主机暴露的 ip:端口即可访问到前端页面: http://192.168.2.207:30001/

image-20230917134519996

12.6 卸载 k3s 集群

在 k3s server 节点执行如下:

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

在 k3s agent 节点执行如下:

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

12.7 k3s 高可用集群安装

​ 将 k3s 进行高可用部署。官方提供了两种部署方式,一种是连接外部数据库如:mysql,然后部署多个 k3s server 端再进行负载均衡,还有一种是官方提供的高可用方式,参考: https://docs.rancher.cn/docs/k3s/installation/ha-embedded/_index/

创建三台虚拟机,两台控制节点,一台工作节点

1、部署控制节点

## k3s-master01执行
$ curl -sfL https://get.k3s.io | K3S_TOKEN=k3s_server_token INSTALL_K3S_MIRROR=cn sh -s - server --cluster-init


## k3s0master02执行
$ curl -sfL https://get.k3s.io | K3S_TOKEN=k3s_server_token INSTALL_K3S_MIRROR=cn sh -s - server --server https://192.168.2.207:6443

不安装traefix创建集群(实验未成功)

## k3s-master01执行
$ curl -sfL https://get.k3s.io | K3S_TOKEN=k3s_server_token INSTALL_K3S_MIRROR=cn sh -s - server --no-deploy traefik --cluster-init


## k3s0master02执行
$ curl -sfL https://get.k3s.io | K3S_TOKEN=k3s_server_token INSTALL_K3S_MIRROR=cn sh -s - server --no-deploy traefik --server https://192.168.2.207:6443

2、工作节点加入集群

控制节点查看token

$ cat /var/lib/rancher/k3s/server/node-token 
K10845ad74d0f40ae6ae9d9c1b2f1597605fe0c0fc4fabf629f9d89841a0b50700b::server:k3s_server_token

工作节点加入集群

curl -sfL https://get.k3s.io | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.2.207:6443 K3S_TOKEN=K10845ad74d0f40ae6ae9d9c1b2f1597605fe0c0fc4fabf629f9d89841a0b50700b::server:k3s_server_token sh -

3、验证

$ kubectl get node
NAME           STATUS   ROLES                       AGE     VERSION
k3s-master01   Ready    control-plane,etcd,master   9m39s   v1.27.5+k3s1
k3s-master02   Ready    control-plane,etcd,master   6m11s   v1.27.5+k3s1
k3s-node01     Ready    <none>                      111s    v1.27.5+k3s1

4、部署Guestbook留言板

$ ls
frontend-deployment.yaml  redis-master-deployment.yaml  redis-slave-deployment.yaml
frontend-service.yaml     redis-master-service.yaml     redis-slave-service.yaml

$ for i in $(ls);do kubectl apply -f $i;done

$ kubectl get pod 
NAME                            READY   STATUS    RESTARTS   AGE
frontend-777c74bdc6-hvm2d       1/1     Running   0          54s
redis-master-776dd7b474-6cv9x   1/1     Running   0          53s
redis-slave-588bfbb76f-xk4r8    1/1     Running   0          53s
$ kubectl get svc 
NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
frontend       NodePort    10.43.128.48   <none>        80:30001/TCP   2m26s
kubernetes     ClusterIP   10.43.0.1      <none>        443/TCP        13m
redis-master   ClusterIP   10.43.86.68    <none>        6379/TCP       2m25s
redis-slave    ClusterIP   10.43.50.98    <none>        6379/TCP       2m24s

5、浏览器访问测试

http://192.168.2.207:30001

image-20230917153500524