第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 架构
K3s 支持在单节点上运行,即将整个 Kubernetes 集群部署在单个节点上。这种架构适用于一些简单的开发、测试或学习场景,以及某些边缘计算环境。下面是单节点 K3s 架构的一般配置:
-
主节点(Master Node):单节点架构下,该节点兼具主节点和工作节点的角色。主节点负责 管理整个集群的状态和控制平面操作,包括调度容器、监控资源、维护集群状态等。它运行 K3s 的服务端组件,如 kube-apiserver、kube-controller-manager、kube-scheduler 等。
-
容器运行时(Container Runtime):K3s 可以使用多种容器运行时,如 containerd、tiny Container Runtime Interface(CRI)等。容器运行时负责在主节点上运行和管理容器,提供容 器的隔离和资源管理功能。
-
代理节点(Agent Node):在单节点架构下,主节点兼具代理节点的功能。代理节点运行 K3s 的客户端组件,如 kubelet 和 kube-proxy,它们与主节点上的服务端组件进行通信,并负责在 主节点上启动和管理容器。
在单节点架构中,K3s 的主节点和代理节点运行在同一台机器上,共享系统资源。这种架构可以简化部署过程,并节省硬件资源。然而,需要注意的是,由于整个 Kubernetes 集群运行在单个节点上,它没有高可用性和容错能力。如果主节点发生故障,整个集群将不可用。
12.2.2 高可用的 k3s 架构
要实现高可用性的 K3s 架构,可以将 K3s 集群配置为多节点集群,这样可以在主节点故障时保持集 群的可用性。以下是一个高可用的 K3s 架构示例:
- 主节点(Master Node):主节点是 K3s 集群的控制平面,负责管理整个集群的状态和操作。 为了实现高可用性,可以将多个主节点配置为主-主模式或主-备模式。每个主节点运行 K3s 的服 务端组件,如 kube-apiserver、kube-controller-manager、kube-scheduler 等。主节点之 间通过内部通信协议进行状态同步和数据复制。
- 工作节点(Worker Node):工作节点负责运行容器和处理应用程序的工作负载。它们接收主 节点的指令并运行相应的容器。可以有多个工作节点加入到 K3s 集群中,提供扩展性和负载均 衡。
- 负载均衡器(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 源
12.3.2 配置防火墙
关闭 firewalld 防火墙, centos7 系统默认使用的是 firewalld 防火墙,停止 firewalld 防火墙, 并禁用这个服务。
12.3.3 时间同步
ntpdate cn.pool.ntp.org
编辑计划任务,每小时做一次同步
1)crontab -e
2)重启 crond 服务:
12.3.4 关闭 selinux
关闭 selinux,设置永久关闭,这样重启机器 selinux 也处于关闭状态
可用下面方式修改:
上面文件修改之后,需要重启虚拟机,如果测试环境可以用如下命令强制重启:
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 文件增加如下几行:
配置所有节点免密
$ 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
2、生成 containerd 的配置文件:
3、修改配置文件:
SystemdCgroup = false 修改成
SystemdCgroup = true
sandbox_image = "k8s.gcr.io/pause:3.6"修改成
sandbox_image="registry.aliyuncs.com/google_containers/pause:3.7"
4、配置 containerd 开机启动,并启动
5、安装 crictl 命令
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 服务,使配置生效
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 留言板
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
$ 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
$ 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
$ 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
$ 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
$ 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 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/
12.6 卸载 k3s 集群
在 k3s server 节点执行如下:
在 k3s agent 节点执行如下:
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




