前言
不知不觉,已工作三年,回顾这三年,发现自身技术上的成长并没有想象中的那么大, 在这个充满焦虑的社会自己难得静下心来系统的学习和缺少实践。
最近在学习kubernetes, 决定写一个系列,来记录这个过程。同时为了不让过程那么枯燥,决定用我的树莓派集群来实践,定一个小目标:花一个月的时间将树莓派集群上运行的大部分应用(nginx、postgresql、gitea、homeassistant、prometheus、grafana等)部署在kubernetes上!
硬件
我用到的硬件如下:
树莓派4 4GB * 4
tf卡 * 4
256G SSD(通过USB3.0连接到树莓派) * 4
type-c电源线 * 4
63W 五口USB电源
八口千兆交换机
网线若干
树莓派集群支架(带风扇)
虽然准备搭建的是一个用于测试的k8s环境,但存储介质一定要选好,tf卡鱼龙混杂,建议选购不低于1元/1GB的大牌产品(推荐闪迪、三星)。
我打算用三个SSD固态硬盘作为ceph的OSD节点,一个SSD用作Master节点的系统盘,提升系统速度和可靠性。
软件
系统: RPi OS 64Bit Lite, 更换为testing源,直接升级到debian 11
软件: kubernetes v1.21, docker v20.10.7(1.20之后的k8s不再依赖docker,习惯上使用docker作为默认的容器运行时)
kubernetes的安装(kubeadm、kubelet 和 kubectl):install-kubeadm
docker的安装: install-docker
- 其他: 搭建k8s时需要大量访问境外网站,所以需要有一个FQ代理,我在其中一个树莓派上已经运行了一个v2ray和一个对外的http代理,这样其他的树莓派就能通过这个http代理访问外网了
准备
安装好系统后配置时区、local、扩展系统空间等初始化工作就不详述了,下面说说安装k8s必须要配置的内容。
主要有配置静态IP、ssh互信、关闭Swap、配置docker的cgroup驱动、配置iptables、预先拉取镜像等。
设置静态IP
为每个树莓派设置静态IP, 编辑/etc/dhcpcd.conf, 在文件末尾添加以下几行:
1 | interface eth0 |
表示给eth0网卡设置了一个静态IP 192.168.10.100, 子网掩码是24(255.255.255.0),网关地址为192.168.10.1, DNS设置了一个192.168.10.1和114.114.114.114。
依次给其他三个树莓派设置IP为192.168.10.101、192.168.10.102、192.168.10.103
hostname和hosts设置
使用hostnamectl命令为每台树莓派设置hostname:
1 | sudo hostnamectl set-hostname RPi-0 |
另外三个树莓派hostname依次设置为RPi-1, RPi-2, RPi-3
编辑hosts文件, 添加以下内容:
1 | 127.0.0.1 RPi-0 |
注意:设置每个树莓派的hosts中自身的hostname指向127.0.0.1
ssh互相免密
在每个树莓派上生成ssh秘钥:
1 | ssh-keygen |
一直回车就好。
然后在RPi-0上使用ssh-keyscan收集四个树莓派的公钥指纹:
1 | ssh-keyscan RPi-0 RPi-1 RPi-2 RPi-3 >> ~/.ssh/known_hosts 2>/dev/null |
将RPi-0上的~/.ssh/known_hosts 文件copy到其他三个树莓派上同样的位置。
在每个树莓派上查看公钥:
1 | cat .ssh/id_rsa.pub |
将所有树莓派的公钥一行一个进行汇总, 添加到每个树莓派的.ssh/authorized_keys文件。这样, 所有树莓派之间都可以通过ssh免密登录了,可在任一树莓派上执行 ssh RPi-1、 ssh RPi-2、 ssh RPi-3
进行验证。
(以上操作如果使用ansible将会很便捷。)
关闭Swap
执行free -m
查看:
1 | pi@RPi-0:~ $ free -m |
会发现RPi OS启用了Swap,使用以下命令来关闭:
1 | sudo dphys-swapfile swapoff |
再次执行free -m
:
1 | pi@RPi-0:~ $ free -m |
已经成功关闭Swap。
启用cgroup限制
如果没有启用cgroup限制,执行docker info
命令后在末尾会输出以下警告:
在/boot/cmdline.txt
末尾(空格隔开,不换行)添加以下内容:
1 | cgroup_enable=cpuset |
可使用sed命令来完成快速修改:
1 | sudo sed -i '$ s/$/ cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 swapaccount=1/' /boot/cmdline.txt |
重启后再次执行docker info
,会发现上图的警告已经没了。
配置docker的cgroup驱动
执行docker info | grep "Cgroup Driver"
查看docker的cgroup驱动是否为systemd:
1 | pi@RPi-0:~ $ docker info | grep "Cgroup Driver" |
docker最新版默认systemd,无需更改, 如果不是请按以下方法更改。
创建或替换 /etc/docker/daemon.json 以启用 cgroup 的 systemd 驱动,内容如下:
1 | { |
重启树莓派,再次执行docker info | grep "Cgroup Driver"
查看Cgroup Driver项是否已变成systemd。
允许 iptables 检查桥接流量
为了让你的 Linux 节点上的 iptables 能够正确地查看桥接流量,你需要确保在你的 sysctl 配置中将 net.bridge.bridge-nf-call-iptables 设置为 1。
1 | cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf |
加载ipvs内核模块
kube-proxy支持 iptables 和 ipvs 两种模式, 如果要使用ipvs模式,需要加载相应的内核模块。
安装ipvsadm和ipset:
1
sudo apt install ipvsadm ipset
列出ipvs相应的模块并写入/etc/modules:
1
sudo ls /lib/modules/$(uname -r)/kernel/net/netfilter/ipvs | grep -o "^[^.]*" >> /etc/modules
重启之后检查是否加载ipvs模块(没有输出则未加载):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17pi@RPi-0:~ $ lsmod | grep ip_vs
ip_vs_wrr 16384 0
ip_vs_wlc 16384 0
ip_vs_sh 20480 0
ip_vs_sed 16384 0
ip_vs_rr 16384 9
ip_vs_pe_sip 16384 0
nf_conntrack_sip 36864 1 ip_vs_pe_sip
ip_vs_nq 16384 0
ip_vs_lc 16384 0
ip_vs_lblcr 20480 0
ip_vs_lblc 20480 0
ip_vs_ftp 20480 0
nf_nat 49152 3 nft_chain_nat,xt_MASQUERADE,ip_vs_ftp
ip_vs_dh 20480 0
ip_vs 143360 35 ip_vs_wlc,ip_vs_rr,ip_vs_dh,ip_vs_lblcr,ip_vs_sh,ip_vs_nq,ip_vs_lblc,ip_vs_pe_sip,ip_vs_wrr,ip_vs_lc,ip_vs_sed,ip_vs_ftp
nf_conntrack 139264 6 xt_conntrack,nf_nat,nf_conntrack_sip,nf_conntrack_netlink,xt_MASQUERADE,ip_vs
镜像拉取
在RPi-0上查看需要的镜像:
1 | kubeadm config images list |
在每个树莓派上使用docker pull
命令来拉取以上列表的镜像
以上,便完成了k8s搭建前的准备工作,可以重启全部树莓派以确保环境生效。接下来就是集群的搭建了。