k3s笔记-01-部署
文章目录
1. 前言
k3s的部署很简单,选择一个Linux系统,执行命令下载脚本进行安装:
1curl -sfL https://get.k3s.io | sh -
安装过程的主要消耗在下载托管在GitHub上的k3s可执行程序。由于最近工作需要在边缘机房部署集群,使用容器化的方式运行服务组件,经过几番考虑选择了k3s,理由如下:
- 边缘机房资源有限,一部分机房甚至只有2台宿主机,部署k3s对资源要求远低于标准k8s
- 边缘机房数量较多,每个机房维护一套高可用etcd和k8s代价很高,而k3s在v1.19.5+k3s1版本开始内嵌etcd
- 容器化服务组件最初的目的就是为了解决服务本身高可用问题,服务组件数量不多,不需要CNI也不需要Service,简化后的k3s已经够用
- k3s本身集成了api-server、scheduler、controller-manager、etcd、containerd...等等,一个可执行文件中包含了所有必须的组件,无需再拉取镜像
因为需要针对边缘机房环境进行定制化并输出部署脚本,这里就先研究了下k3s的安装。
2. 安装脚本分析
这里保存一个安装脚本的备份:get-k3s-io.sh
安装脚本很长,但是写的非常工整漂亮,可以看到主要安装步骤如下:
1# --- run the install process --
2{
3 verify_system
4 setup_env "$@"
5 download_and_verify
6 setup_selinux
7 create_symlinks
8 create_killall
9 create_uninstall
10 systemd_disable
11 create_env_file
12 create_service_file
13 service_enable_and_start
14}
- 检查系统:查看系统是否支持使用openrc或systemd运行程序
- 环境变量解析: K3S_ 开头的环境变量会传递给k3s可执行程序使用,INSTALL_ 开头的环境变量由安装脚本使用,可控制安装操作,如版本、安装目录、是否下载二进制文件等等
- 下载与验证k3s:从github或google下载当前环境所需的k3s可执行文件,若配置 INSTALL_K3S_SKIP_DOWNLOAD=true,可跳过下载
- 配置selinux:若启用了selinux,需要额外安装一些软件
- 创建软链接:创建kubectl、crictl、ctr等软链接,指向k3s可执行程序,执行命令时会启用对应功能
- 创建k3s-killall.sh脚本:执行 k3s-uninstall.sh 时会被调用,该脚本会停止k3s相关systemd服务,杀死所有k3s管理的容器组,解除k3s相关目录挂载并删除,移除CNI、移除k3s创建的iptables规则
- 创建k3s-uninstall.sh脚本:k3s卸载脚本,首先执行k3s-killall.sh,然后从系统中彻底卸载k3s
- 停止已加载的k3s服务
- 创建环境变量文件:将 K3s_ 开头的环境变量写入文件
- 创建service文件:根据系统支持,创建对应的systemd或openrc的service文件
- 启动k3s:启动k3s并设置为开机自动启动
示例:
1curl -sfL https://get.k3s.io | INSTALL_K3S_SKIP_DOWNLOAD=true INSTALL_K3S_EXEC="server" sh -s - --disable coredns,servicelb,traefik,local-storage,metrics-server --disable-kube-proxy --disable-network-policy --no-flannel --cluster-init --cluster-cidr 10.253.0.0/16 --service-cidr 10.254.0.0/16 --container-runtime-endpoint unix:///run/containerd/containerd.sock --node-name 10-0-0-1 --node-ip 10-0-0-1
环境变量需要设置在 sh -s - 之前,其中 INSTALL_ 开头的环境变量控制了安装脚本的操作,因为k3s启动参数繁杂,这里不使用 K3S_ 开头的环境变量进行自定义配置,统一改为在 sh -s - 后传入参数,这些参数在debian 10下会持久化到文件 /etc/systemd/system/k3s.service 中,在ExecStart启动k3s时,作为参数传入,如下:
1➜ ~ cat /etc/systemd/system/k3s.service
2...
3ExecStart=/usr/local/bin/k3s \
4 server \
5 '--cluster-init' \
6 '--cluster-cidr' \
7 '10.253.0.0/16' \
8 '--service-cidr' \
9 '10.254.0.0/16' \
10...
在安装后如果有需要增加其他启动参数,可修改service文件,重新加载后重启k3s即可。在生产环节中,为了简化部署,笔者主要做了以下调整:
- 预安装k3s二进制文件,跳过下载:规避了github和谷歌在国内的访问问题
- 移除所有附加组件、kube-proxy、CNI插件:我们的生产环节无法部署依赖service的服务,统一使用hostNetwork与自研的DNS服务
- 使用外置CRI:k3s提供了模板功能来自定义内嵌的containerd参数,但是生产环节中宿主机环境复杂,笔者使用了独立部署的containerd和预启动脚本来处理这些差异
3. k3s内嵌组件分析
首先看一下k3s的帮助命令,如下:
1➜ ~ k3s --help
2NAME:
3 k3s - Kubernetes, but small and simple
4
5USAGE:
6 k3s [global options] command [command options] [arguments...]
7
8VERSION:
9 v1.21.5+k3s2 (724ef700)
10
11COMMANDS:
12 server Run management server
13 agent Run node agent
14 kubectl Run kubectl
15 crictl Run crictl
16 ctr Run ctr
17 check-config Run config check
18 etcd-snapshot Trigger an immediate etcd snapshot
19 help, h Shows a list of commands or help for one command
20
21GLOBAL OPTIONS:
22 --debug (logging) Turn on debug logs [$K3S_DEBUG]
23 --data-dir value, -d value (data) Folder to hold state default /var/lib/rancher/k3s or ${HOME}/.rancher/k3s if not root
24 --help, -h show help
25 --version, -v print the version
- server:运行控制节点的子命令,有大量参数可定义控制平面组件,使用HA模式时需要注意所有master除宿主机相关参数外必须一致,由于参数繁多,笔者不推荐使用环境变量的方式传参
- agent:运行工作节点的子命令
- kubectl:kubectl子命令,可调用api-server与集群交互
- crictl:容器组管理子命令,可调用k3s使用CRI接口
- ctr:容器管理子命令,可调用k3s使用的containerd
- check-config:配置检查子命令
- etcd-snapshot:etcd快照管理子命令,可触发etcd生成快照,备份至本地或远端s3服务
从宏观上讲,k3s的集群中只有server与agent两种角色,agent的功能是server的子集,其他的子命令都属于辅助工具,下面分别展开agent和server的功能。
k3s agent
- kubelet:kubelet功能,实现k8s工作节点的所有功能
- flannel:k3s内嵌flannel作为默认集群通信方案
- kube-proxy:k3s内嵌kube-proxy,而非使用独立的kube-proxy组件
- containerd:k3s内嵌containerd作为默认CRI,也可以使用外部CRI
- lb:访问apiserver的本地lb,注意不是service中定义的load balancer
- 宿主机工具:包含修改宿主机环境所需的工具如iptables、ethtool等等
k3s server
- agent:server包含所有agent功能
- 控制平面组件:
- kube-apiserver:提供Kubernetes API
- kube-scheduler:提供Pod调度功能
- kube-controller-manager:管理标准控制器,如Node Controller、Job Controller...
- cloud-controller-manager:管理对接云厂商的控制器
- 数据库组件:
- sqlite:k3s封装了sqlite作为默认KV数据库
- etcd:k3s在v1.19.5+k3s1版本后内嵌了etcd,并可在初始化时启用
- k3s组件:
- helm-controller:helm控制器
- servicelb:服务lb组件,支持通过宿主机端口暴露service
以上是仅使用k3s二进制文件部署集群能得到的所有功能。
4. k3s附加组件分析
附加组件使用yaml部署以Pod形式运行,如下:
- coredns:提供DNS和服务发现
- servicelb:提供服务负载均衡功能,在k3s中利用宿主机端口暴露service
- traefik:实现k8s ingress controller,提供服务暴露功能
- local-storage:使用hostPath提供本地持久化存储卷
- metrics-server:k8s资源指标健康服务
这些都属于可选可替换的组件,对应的yaml存放在 /var/lib/rancher/k3s/server/manifests 中。
5. HA
k3s提供了两种高可用的部署方式,核心还是如何保障DB的高可用,如下:
1. 使用外部DB
High Availability with an External DB
要求:
- 部署2个或以上server
- 部署N个agent
- 部署一个高可用的外部数据库,如etcd、MySQL、PostgreSQL等
- 部署一个固定注册地址对agent暴露server,如:四层TCP负载均衡器、DNS、VIP或EIP
这种比较适合云主机环境,边缘机房的缺乏相关的基础设施。
2. 使用内嵌ETCD
High Availability with Embedded DB
要求:
- k3s版本v1.19.5+k3s1及以上
- 部署奇数个server,推荐3个及以上
- 保持这些参数在所有server上一致
- 网络相关参数:--cluster-dns, --cluster-domain, --cluster-cidr, --service-cidr
- 控制特定组件部署的参数:--disable-helm-controller, --disable-kube-proxy, --disable-network-policy,--disable
- 特性相关参数:--secrets-encryptio
这种方式是笔者目前采用的,etcd跟随server部署,无需分开维护DB与apiserver,一定程度上简化了部署和运维,但实现DB高可用所需的工作并不会减少,笔者将会在下一篇中记录实践情况。