前因
之前在观看有关docker的视频时,总有人提到k8s。我见到很多这种评论之后,便去查了查什么叫k8s。按照我的理解,这应该是一个继承了高可用性的集群化容器平台。在实习的这段无聊的日子里阅读了大量有关kuberneters的资料后,我决定在本地搭建一个小型kuberneters集群。
0、minikuber
我首先尝试在办公室的电脑(i5-10500+8G RAM+1T HDD)上使用minikuber搭建一个单节点集群。结果无论是基于WSL2还是hyper-v均失败了,最后我只能回家,在我的那台服务器上尝试搭建完整的kuberneters。至于失败的原因,之后有时间再说吧。
1、初期准备
咱准备了三台虚拟机,配置均为8核心CPU+8GB RAM+50GB 硬盘。系统是debian11.每台虚拟机均配备两块网卡,一块以桥接的形式连接到家庭网络(192.168.31.110-112),另一块则用于内部网络通信(仅主机,172.16.31.110-112).
在安装系统阶段,就给了我当头一棒。或许是最近网络条件又恶化了吧。在安装debian时不能选择配置网络镜像,不然我就会在漫长等待后被告知安装失败。而其它的东西,无非就是在分区时不推荐开启Swap交换分区,和设置好hostname。apt软件包源可以在安装后参考这里进行配置。
接下来,为几台机器分别设置IP,并且将IP与hostname的对应关系写入/etc/hosts。
在Debian11上,我使用
hostnamectl set-hostname k8s-master
修改hostname为k8s-master。
这儿提一下咱踩过的一个小坑,运行特权命令,请不要直接运行
su
最好使用
sudo + 命令(前提是你的用户账户允许使用sudo)
以及
su - root
否则会出现很多离谱的问题,比如说shutdown和reboot找不到呀,明明安装了应用却打不开,dpkg安装报错等。
在安装完系统、配置好源之后,文档上还提示我应该转发 IPv4 并让 iptables 看到桥接流量。不过debian11似乎没有iptables,所以我直接忽略了iptables这一步。而开启转发,就是运行:
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
具体参考这里。
接下来文档还提到了cgroup 驱动,因为我确定debian11使用的是systemd,同时文档也没有指出需要什么强制性操作,所以我就没有做进一步处理了。
这一步所有节点都必须执行。
2、安装docker
kuberneters需要一个容器引擎来完成一些基本操作。我看了看参考文档上的那些东西,觉得还是选择我最熟悉的docker吧。docker可以按照这份官方文档来进行安装。
在安装完了docker之后,还得要安装cri-dockerd
,这是为了能够让docker使用容器运行时接口(CRI)来与kuberneters通信,并且让docker被kuberneters管理。
在安装好了之后,需要记录下CRI 套接字是 /run/cri-dockerd.sock
,这个后面会用到。
这一步所有节点都必须执行。
3、安装 kubeadm
kubeadm是一个用来管理kuberneters的工具箱,我使用它创建kuberneters集群。
在安装这个工具之前,首先更新 apt
包索引并安装使用 Kubernetes apt
仓库所需要的一些依赖包:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
接下来,最好不要按照官网走,中国大陆地区很难连接上Google的软件仓库,转到这里进行接下来的步骤。
不过,gpg key还是得自己下载放到指定位置的,这一点得自己动手。我采取的方法是:先在Windows系统上下载好——在终端里使用scp命令将文件传输到普通用户目录——切换root用户将文件拷贝到指定位置。
接下来就是照着文档安装并锁定版本了:
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
这里安装的三个软件中,kubeadm用来创建集群和让节点加入集群。kubelet是用来保证容器都运行在 Pod 中的。具体的解释参考官方文档。简单的说,pod是容器的集合,一个pod里可以包含多个容器,每个pod有自己的IP地址,而kuberneters的调度也是以pod为单位。
kubectl,是一个用来管理kuberneters的命令行工具,后面会经常使用它。
这一步所有节点都必须执行。
4、初始化主节点
看上去很简单,只需要一条命令,如下:
kubeadm init \
--cri-socket unix:///var/run/cri-dockerd.sock
--apiserver-advertise-address=172.16.31.110 \
--control-plane-endpoint=k8s-master \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16
实则里面有坑。
首先,因为无法访问gcr.io,所以我们得为docker服务配置代理(只配置终端代理没有用,kuberneters也得通过docker拉取镜像)或者使用镜像站(类似于再加一条--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \不过网传的这个registry.cn-hangzhou.aliyuncs.com似乎已经挂了)。
部分参数的解释:
cri-socket:之前的CRI套接字
apiserver-advertise-address:kuberneters api服务器的地址,一般是你的主控节点内部IP
control-plane-endpoint:将单个控制平面 kubeadm 集群升级成高可用,即为所有控制平面节点设置共享端点, 端点可以是负载均衡器的 DNS 名称或 IP 地址
service-cidr:service网络的IP地址范围,当你给一个pod暴露了端口的时候,pod的端口也会运行在这个内部IP上
pod-network-cidr:pod分配到的内部网络地址范围
image-repository:可以指定镜像仓库地址
kubernetes-version:可以指定需要部署的k8s的版本
文档里的说明
之后就是等待了。如果你的网络连接Google正常,那么大约只需要半个小时左右就可以安装好,安装好后,会显示类似于这样的话:
kubeadm join 192.168.31.110:6443 --token e6itty.nahyjrbe9uu4jc3z \
--discovery-token-ca-cert-hash sha256:b8f7a6720e6ae23c6657a0e283c844ea908836f40e628b521cb2bcc4daaf2a84
需要记下这一段命令,用于后面加入节点使用。
这一步只需要主控节点执行。
5、设置配置文件
使用kubecli需要有admin.conf配置文件,复制一份到用户目录下的.kube文件夹里就行了。
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
接下来,得把这个文件复制到各个节点上的相同位置,但是因为它们没有/etc/kubernetes/admin.conf,不能使用cp命令,只能一个个手动复制过去了。
然后,执行:
systemctl status systemd-resolved
systemctl start systemd-resolved
来避免拉取镜像时出现
Failed to create pod sandbox: open /run/systemd/resolve/resolv.conf: no such file or directory
这样的报错。
这一步所有节点都必须执行。
6、安装网络插件
必须要安装网络插件才能够让核心DNS启动,可以先尝试在主节点上运行
cubectl get nodes
来查看现有master节点的运行情况。不出意料应该是notready的。所以需要安装网络插件来让功能完整。
网络插件类型众多,而且它们和kuberneters之间还有版本的对应关系。我参考了这篇文章,使用了Calico网络插件,不过因为我的kuberneters版本过新,使用了最新的3.25版Calico。
下载资源清单文件(官方文档就是这个叫法):
wget https://docs.projectcalico.org/archive/v3.25/manifests/calico.yaml
然后部署插件:
kubectl apply -f calico.yaml
然后还是等待。这里还是得注意网络问题。如果在半个小时之后发现master还没有ready,而运行
kubectl get pods -n kube-system
发现报错 init:ImagePullBackOff,那么说明拉取镜像失败了。我这里采用的方法是打开calico.yaml文件,找到里面标有image的镜像,一个个手动用docker pull拉取....
在拉取镜像后再次等待一下,master节点应该已经Ready了。
而如果使用
journalctl -u kubelet
这个命令查看kubelet运行情况时,发现出现network: stat /var/lib/calico/nodename: no such file or directory: check that the calico/n这样的报错,那么需要删除calico的配置文件并重启kubelet:
rm -rf /etc/cni/net.d/*
rm -rf /var/lib/cni/calico
rm -rf /var/lib/calico
systemctl restart kubelet
这一步只需要主控节点执行。
7、worker节点加入集群
千辛万苦终于来到了这一步。使用之前记下来的加入命令,再加上--cri-socket unix:///var/run/cri-dockerd.sock \,也就是:
kubeadm join 192.168.31.110:6443 --token e6itty.nahyjrbe9uu4jc3z \
--cri-socket unix:///var/run/cri-dockerd.sock \
--discovery-token-ca-cert-hash sha256:b8f7a6720e6ae23c6657a0e283c844ea908836f40e628b521cb2bcc4daaf2a84
在worker节点上运行,把worker节点加入集群。接下来就是等待它们Ready了。
这里同样需要注意网络问题,如果有必要就挂代理拉镜像。
在主节点使用
kubectl get nodes
来查看加入情况。
8、部署管理面板
像我这种命令行苦手,那肯定是不用GUI就不舒服,所以管理面板也得安排上。
kuberneters有官方的管理面板,参考这里的说明,首先用这条部署它:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
然后便是修改配置,让端口暴露出来。这里需要运行
KUBE_EDITOR="nano" kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
这里前面的“KUBE_EDITOR="nano"”代表使用nano取代默认的编辑器vi来修改配置文件。我用nano只是因为个人确实不习惯vi。
在出现的窗口中,将type: ClusterIP 改为 type: NodePort即可让dashboard的端口暴露。这里还得留心一下上面的端口号。
然后便是认证,创建一个yaml文件:
nano dashuser.yaml
写入以下内容:
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
这里的文件的大概解释是创建角色并手动授予所需的权限,使用命名空间中的名称创建服务帐户。我也不是很理解,这里参考的是这篇文章,虽然我后面在使用过程中出错了,不过还是正常获取到了tocken。
接着执行资源清单并获取tocken:
kubectl apply -f dash.yaml
kubectl -n kubernetes-dashboard create token admin-user
记下这段tocken,然后在浏览器里访问集群里任意主机的https://外部IP:刚刚记下的端口号,记不住可以用端口扫描工具把集群IP的所有扫一遍。
如果无法访问,就运行
kubectl get pods -A
来确认dashboard运行正常。
浏览器里忽略证书错误,复制tocken并将其粘贴到登录屏幕上的字段中,即可进入dashboard。
9、后记
其实我有点后悔去踩这个坑,k8s比docker难多了,特别是大陆特殊的网络问题,折磨得我十分无语。家庭服务器弄这个感觉也没什么必要。可能只是咱自己想要折腾吧。以后有时间和硬件或许会研究研究k8s的家庭应用?后面的事,又有谁能确定呢?
写到这里已经快晚上11点了,由于咱自己本身就是小白而且还是盲从网上的大神们搭建起来的,所以请大家务必不要抄我这个才60分的作业,如果有错误,欢迎指正,我会修改的。
Comments NOTHING