前情提要
自己为什么要学K8s
在我自己前的学习Go语言系列的第一篇曾说过自己的经历,刚入行的时候,公司的服务都是一个单体架构,数据库和框架在一台云服务器上,没有对象存储和CDN,存放了很多资料在云服务器上面,遇到了硬盘容量不足的时候,需要定闹钟在半夜人少的时候去磁盘扩容挂载重启。后来还有遇到某些致命错误不得不回滚整个服务的系统镜像,导致数据库存放的订单信息丢失,然后去支付后台核对手动退款,搞活动突发流量来了不能平滑升级只能在那里卡死,很没有用户体验感。
容器技术是一个颠覆性的技术,容器的编排完美的解决了这些问题。使用k8s可以快速部署应用,自动扩缩容节约成本,容器化部署消除环境差异问题,自动化运维减轻运维成本,所以为什么不去用呢?
为什么要使用树莓派安装K8s
自己折腾很多云服务器,曾经的MJJ(VPS圈中的垃圾佬),花了好多钱买了很多便宜机器,啥事也没干,想要自己搭建一个K8s集群肯定需要一些稳定的机器了,国外的不稳定,国内的机器买时一时爽,续费火葬场~。
综合考虑使用树莓派再好不过了,功耗小,永久使用权,方便折腾,网上也有人实现了,所以毫不犹豫就下手了。缺点就是有些软件不支持树莓派,例如私有镜像仓库软件Harber没有支持Arm架构,基于PHP的Hyperf框架也不支持Arm架构,还有更多的的坑还我去踩~。
K8s集群介绍&科普
什么是k8s
全名Kubernetes,k和s中间有8个字母,简称K8s。一个容器编排管理工具,一个基于容器技术的集群系统,给容器化的应用提供部署运行,动态伸缩,服务发现等等编排与管理能力。最初由Google公司设计开发,前身是Google的Borg平台, 其实K8s是一个属于运维范畴的知识,自己是一名后端工程师,本篇文章只是稍微记录一下学习路程,纯新手,不会对K8s的细节进行深入讲解。(难的我也不会,哈哈~)
K8s基本概念
Pod
K8s最基本调度资源,一个Pod中可以有单个或者多个容器,K8s很多概念都非常抽象,比如这个Pod,它可以看作Pod其中容器的逻辑上的物理主机,一个Pod只能存在一个物理机器上,多个容器在一个Pod中共享一个网络和文件系统,在k8s集群中部署应用的时候就是写一些yaml配置文件来配置pod使用哪个容器镜像,指定部署到哪个Node节点,限定pod使用的资源,暴露哪个端口,挂载哪个数据卷,指定一些动态伸缩的指标,指定健康检查手段等等。
Master节点
节点,通常一个节点会部署在一台物理机器上,通常分成两种节点:Master节点和Node节点,从名字可以看出Master节点就是集群的大脑,起控制作用。
Master节点有几个重要的基本组件及其作用需要了解:
- Etcd:高可用分布式强一致性键值对数据库(一句话总结了,可以了解一下与其相关的raft算法),保存所有节点的网络配置和资源对象的状态。
- Api Server:负责对外提供Api服务,Master节点的其他组件都要通过调用Api Server实现自己的功能。
- Controller Manager:负责维护集群的各种状态,比如实现资源监控,动态伸缩,滚动更新,故障检测。每个资源类型都有一个控制器,例如Deployment和ReplicationController属于应用资源控制器(维护pod副本数量,应用升级,自动扩缩容),DaemonSet(用于部署一些日志收集,运行监控的资源应用),Jop(定时任务控制器),控制器类型可以在部署应用时yaml描述文件kind字段查看资源类型。
- scheduler:调度器,负责监听新建Pod以及Node信息,把新建的Pod调度到合适的Node节点。
Node节点
Node节点就是K8s的工作集群,是部署应用的载体,干活的角色。
- Kube-Proxy:部署服务的负载均衡组件,把服务的请求的负载合理转发到合适的Pod上。
- kubelet 负责K8s集群具体的任务,上报Pod和Node的状态,执行健康检查,监听调度器的任务分配,挂载数据卷等等功能。 因为网络和机器都是不稳定的,通常为了K8s集群的高可用,通常生产环境的Mater节点当然不能只能是一个,折腾环境一个Master节点就可以了。
其他组件
集群网络覆盖组件,英文简称CNI,也叫容器网络接口,它是一种标准设计规范,体现了K8s的开放宽容的特点,允许自定义开发很多东西,是由CoreOS提出的一个容器网络规范(CoreOS一个创业公司,Etcd就是这家公司研究出来的,现在已被著名的RedHat收购了),用于配置或销毁容器时动态配置适当的网络配置和资源。 集群网络覆盖组件主流的是Flannel和Calico这两个方案,自己安装的是Calico,想要了解其中原理细节还是非常复杂的,抽象理解就是大概就是使用Etcd保存网络状态,在Node所在的机器上新建一个虚拟的网卡,基于共同维护多级虚拟路由表,进行路由转发,Calico原理是基于BPG协议和Linux的路由转发机制,Flannel基于UDP协议ipv4地址路由转发。Flannel比较简单容易理解,Calico比较底层,自由,功能更多。
硬件说明
三树莓派4B 8G
树莓派64位系统:github.com/openfans-co…
系统安装教程可以参考我的个人公众号文章:mp.weixin.qq.com/s/nkppkqU7u…
电源是小米的5口充电器
积木DIY的机箱
前提任务
三个树莓派需要统一设置一下,提高集群稳定性,达到集群安装要求。
更改树莓派名字
sudo vim /etc/hosts
以Master节点机器为例:更改第一行,127.0.0.1 raspberrypi 改成 127.0.0.1 b41。
我的三个树莓派名字就分别改成了b41/b42/b43
还需要改一个地方
sudo vim /etc/hostname
三个树莓派依次改成自己想要的名字,便于后期分辨谁是谁。
设置静态IP
设置静态IP就是为了让他们重启时不会自动分配动态的IP,方便它们之间“沟通”。
sudo vim /etc/dhcpcd.conf
interface wlan0
static ip_address=自定义的树莓派内网ip地址/24
static routers=内网网关ip地址
static domain_name_servers=114.114.114.114 #自定义dns
内网网关就是路由器的管理地址,我的路由器管理地址就是192.168.2.181 我的自己设置b41的内网ip地址是192.168.2.181,其他两个树莓派也一样设置,内网IP的设置不能与其他设备相同。
这里的interface wlan0是指连接wifi的时候设置静态地址,前提是树莓派要用Wifi连接到路由器,而不是使用网线连接。如果是网线连接需要设置eth0,可以使用ipconfig查看树莓派有几个网卡。
为了保险起见我在路由器又设置了一遍静态IP(openwrt系统路由器,网络->IP/MAC绑定):
关闭Swap内存交换空间
什么是Swap
这个非常重要,这里让我学到了什么是OOM(Out Of Memory),Swap内存通俗的来说就是机器硬盘上的预留分配的内存分区,机器上的物理内存不够用了就会在硬盘上申请一块区域给运行的程序使用,所以说在硬盘上的Swap内存分区的性能肯定是比不上物理内存的,Swap内存分区存在的作用就是为了让程序运行时内存不够用而不至于崩溃,所以说它的作用很大,以至于现在的Linux系统默认会分配Swap内存分区提高系统稳定性。记得上一篇文章讲到我在GitLab安装在一个1H2G的机器上调了很多参数还是很卡的一句话,因为GitLab附带的软件有很多个所以会占很多内存,2G通常不够,我就手动设置了2G/4G的Swap内存分区给那台服务器,还是时不时502,网页加载也很慢,后面直接放弃了。
树莓派装完系统可以先查看内存占用,会看到Swap分区有1G的空间。
为什么要关闭Swap
因为K8s是一个跨机器的集群环境,为了保证能够在部分容器出错的时候能够准确定位到其中的问题,给容器编排提供一个稳定健康的环境,而不是莫名其妙的错误影响整个集群,莫名其妙的错误大部分情况就是容器运行的时候内存用完了有内存溢出导致某些进程被kill从而导致服务不可用,但是容器表面上是健康的(容器本质也是一个特殊的进程,只是隔离和限制了一些资源,这个特殊的容器进程又开启其他很多的任务进程),从而影响整个集群的容器调度。所以在kubelet(K8s控制命令台)在1.8版本后强制要求必须关闭Swap。
怎么关闭Swap
简单粗暴 给/etc/fstab内容加上注释
sed -ri 's/.swap./#&/' /etc/fstab
sed
不懂就要学
sed命令是一个可以按照脚本处理编辑文本的命令,sed全名叫stream editor
- -r 支持扩展表达式,表示要启用正则处理文字,非常强大
- -i 直接修改源文件内容,使用-i后不会再在终端输出文件内容
- 's/.swap./#&/' : s后面的符号斜杠就是指定的分割符号,分割符号这里可以自定义,使用三个分割符号,第一个指定符号,后面两个分割出搜索的内容和替换的内容,搜索.swap.,点号代表一个任意字符,这里指斜杠,用&代表匹配到的内容,匹配到的内容前面加一个#,注释掉这一行内容。
- 末尾没有加g。说明只匹配一个。
先看下源文件的内容:
cat /etc/fstab
查看执行 sed -ri 's/.swap./#&/' /etc/fstab 之后的内容:
设置host解析
hosts文件记录了一些ip地址或网址对应的实际地址,相当于自身机器的域名解析系统,系统访问一个ip或网站的时候会实现查询hosts文件,一旦找到就会跳转到相对应的目标。主要是方便局域网内部的机器之间的网络连接,三个机器都需要设置。
sudo cat >> /etc/hosts << EOF
192.168.2.181 k8smaster
192.168.2.182 k8snode1
192.168.2.184 k8snode2
EOF
使用cat >>表示向文件追加内容。
禁用selinux
系统里面通过各种命令查看不到,该树莓派系统的项目维护人员说了没有,但是系统内核支持。
它是一个 Linux 内核模块,linux子系统软件,很复杂的一个东西,由美国国家安全局开发,国内好像都关闭了,主要是它非常容易出错且难以定位。
打开Cgroup
Cgroup是 Linux 内核提供的一种可以限制、记录、隔离进程组的机制,Docker通过Cgroup技术实现对容器资源的限制。我的系统已经默认开启了这个内核设置。
开启ipv4转发
查找资料是Linux系统开启ipv4转发,相当与一个系统路由,可以识别数据包不用于系统自身就可以把数据包送到另外的网络去。
sudo vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 #注释掉这一行
关闭防火墙
避免影响网络性能,K8s为了安全,其环境是基本上是一个内网环境,只有暴露服务到外面去才暴露出少数端口。
sudo /usr/sbin/iptables -P FORWARD ACCEPT #永久
关掉一些服务
systemctl stop NetworkManager.service
systemctl disable NetworkManager.service
原因是没有使用图形化桌面环境,自己是使用配置文件配置的wifi连接,所以关闭这个服务,保证良好的兼容性。
安装一些常用软件
自己总结的常用软件:
sudo apt-get install -y net-tools lrzsz tree screen lsof tcpdump
正式安装
安装kubeadm, kubelet and kubectl
一个Master节点和两个Node节点上都要安装:
kubeadm
是官方推出的快速部署K8s的工具。
kubelet
K8s集群命令行工具,对集群本身进行管理,进行应用部署。
kubectl
master派到Node节点代表,在Node节点上管理自身容器,Node节点中的超级管理工具。
先更新软件列表:
apt-get update && apt-get install -y apt-transport-https
添加软件密钥,添加软件更新的源服务器的地址:
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
一键安装kubeadm, kubelet and kubectl,需要指定安装的集群版本:
apt-get install -y kubelet=1.20.0-00 kubeadm=1.20.0-00 kubectl=1.20.0-00
安装K8s集群之前需要拉去一些镜像到本地,因为通过kubeadm脚本拉取的镜像远程好像没有会报错,我们需要先拉去远程的镜像并重新打Tag,脚本就会识别到本地有该镜像就不会报错了。
#mirrorgcrio已经没有更新了...可以官方网站去搜有哪个版本的
#MY_REGISTRY=mirrorgcrio
MY_REGISTRY=registry.aliyuncs.com/google_containers
#MY_REGISTRY=registry.cn-hangzhou.aliyuncs.com
K8S_VERSION="1.20.0"
echo ""
echo "=========================================================="
echo "Pull Kubernetes for x64 v$K8S_VERSION Images from docker.io ......"
echo "=========================================================="
echo ""
## 拉取镜像
docker pull ${MY_REGISTRY}/kube-apiserver:v$K8S_VERSION
docker pull ${MY_REGISTRY}/kube-controller-manager:v$K8S_VERSION
docker pull ${MY_REGISTRY}/kube-scheduler:v$K8S_VERSION
docker pull ${MY_REGISTRY}/kube-proxy:v$K8S_VERSION
docker pull ${MY_REGISTRY}/etcd:3.4.13-0
docker pull ${MY_REGISTRY}/pause:3.2
#docker pull ${MY_REGISTRY}/coredns-arm64:1.7.0
docker pull coredns/coredns:1.7.0
## 添加Tag
docker tag ${MY_REGISTRY}/kube-apiserver:v$K8S_VERSION k8s.gcr.io/kube-apiserver:v$K8S_VERSION
docker tag ${MY_REGISTRY}/kube-scheduler:v$K8S_VERSION k8s.gcr.io/kube-scheduler:v$K8S_VERSION
docker tag ${MY_REGISTRY}/kube-controller-manager:v$K8S_VERSION k8s.gcr.io/kube-controller-manager:v$K8S_VERSION
docker tag ${MY_REGISTRY}/kube-proxy:v$K8S_VERSION k8s.gcr.io/kube-proxy:v$K8S_VERSION
docker tag ${MY_REGISTRY}/etcd:3.4.13-0 k8s.gcr.io/etcd:3.4.13-0
docker tag ${MY_REGISTRY}/pause:3.2 k8s.gcr.io/pause:3.2
#docker tag ${MY_REGISTRY}/coredns-arm64:1.7.0 k8s.gcr.io/coredns:1.7.0
docker tag coredns/coredns:1.7.0 k8s.gcr.io/coredns:1.7.0
echo ""
echo "=========================================================="
echo "Pull Kubernetes for x64 v$K8S_VERSION Images FINISHED."
echo "into docker.io/mirrorgcrio, "
echo " by openthings@https://my.oschina.net/u/2306127."
echo "=========================================================="
echo ""
保存为shell脚本,然后执行。三台机器都需要运行进行拉取镜像。
master节点安装
只在Master节点机器执行下面的命令:
#指定IP地址,1.20.0版本:
sudo kubeadm init --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.20.0 --apiserver-advertise-address=192.168.2.181 --pod-network-cidr=192.168.0.0/16 --ignore-preflight-errors=all
-
kubernetes-version:指定集群版本。
-
apiserver-advertise-address:kubeadm 使用 eth0 的默认网络接口(通常是内网IP)做为 Master 节点的 advertise address ,如果我们想使用不同的网络接口,可以使用 --apiserver-advertise-address= 参数来设置
-
pod-network-cidr:pod-network-cidr: 指定pod网络的IP地址范围,它取决于你在下一步选择的哪个网络网络插件,比如我在本文中使用的是Calico网络,指定为192.168.0.0/16。
-
ignore-preflight-errors:忽略所有报错,如果不加,可能会执行失败,cgroups:hugetlb报错,查了下资料,没什么问题。
等几分钟,执行完成:
[apiclient] All control plane components are healthy after 37.009846 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.20" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node b41 as control-plane by adding the labels "node-role.kubernetes.io/master=''" and "node-role.kubernetes.io/control-plane='' (deprecated)"
[mark-control-plane] Marking the node b41 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: kj236o.bff6bhbuiz7oxlqi
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[kubelet-check] Initial timeout of 40s passed.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.2.181:6443 --token 3fkqb5.******** --discovery-token-ca-cert-hash sha256:d516b2d07e3f2e99a1445a20348295258d8972414a4264ff0d79d389c8116b37 --ignore-preflight-errors=all
root@b41:/etc/docker#
输出信息已经展示了怎么加入集群
Node节点加入集群
master节点内网地址一开始使用了192.168.2.181这个内网地址 使用SSH连接到Node节点执行下面的命令:
kubeadm join 192.168.2.181:6443 --token njr783.****** --discovery-token-ca-cert-hash sha256:29f43006779a5c7e59e86d199984f435129a154b3a311dbe42aeab9c571c9f2f --ignore-preflight-errors=all
安装会报错处理说明补充
failed to create kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"
刚安装 K8s 时,docker 的驱动是 cgroupfs k8s 需要使用 systemd,这是直接添加 docker 配置即可
解决办法:
vim /etc/docker/daemon.json
{
"exec-opts":["native.cgroupdriver=systemd"]
}
然后重启docker,注意这个系统自带docker,无需自己安装。
systemctl restart docker
自己装了很多遍,尝试了很多次,出现了难以解决问题也很简单,例如装flannel的时候死活装不上就直接重置整个安装流程。
kubeadm reset
到此时在Master机器上使用查看所有的pod
kubectl get pods --all-namespaces
安装Calico
此时缺一个覆盖网络插件,我安装的是Calic。
Yaml
想要在K8s部署应用就必须了解Yaml文件,Yaml文件是一种通用的文件格式,通常做为配置文件使用,跟打包镜像的DockerFile文件格式差不多, 使用缩进表示其中的层级关系。在K8s中作为一种资源的清单,能清楚的记录在集群中做了什么事情,部署了什么东西,而不是随便输入一条命令,过了几天就不知道做了什么事情了。 首先需要下载网上公开的的Yaml文件,作为菜鸡的我实在没有实力去编写复杂的Yaml文件。
weget https://docs.projectcalico.org/v3.11/manifests/calico.yaml
可以使用cat calico.yaml 查看一下这个文件
可以看到很多kind:CustomResourceDefinition键值对,就是K8s之中的自定义资源类型,Kubernetes 中一切都可视为资源。
我们可以在Master机器上使用以下命令就可以安装完成了:
kubectl apply -f calico.yaml
再看一下所有的Pod,这个1.20版本的的K8s集群是我在半年前装的,现在为了演示把其中的网络插件Calico和Dashboard面板删了,现在重新来安装走一遍流程,因为之前没有留下什么记录,这里做一下补充说明。
稍微补充一下怎么删除Yaml描述文件部署的应用。
kubectl delete -f kubernetes-dashboard.yaml
如果发现Pod的状态一直是Terminating可以使用强制删除Pod命令:
kubectl delete pod dashboard-metrics-scraper-79c5968bdc-f82g2 --force --grace-period=0 -n kubernetes-dashboard
- -n 后面接着是namespace
- pod后面接着是pod名称
- grace-period 宽限期为0,马上执行
强制删除过后会遗留一点问题,需要手动删除机器上遗留的虚部网卡,和残留配置:
ifconfig cali70ee51d9a9b down
ifconfig tunl0 down
rm -rf /etc/cni/net.d
ImagePullBackOff是镜像一直无法拉取的报错,我们需要重新多配置几个Docker的镜像远程仓库地址,注意几台机器都需要配置:
cat /etc/docker/daemon.json
{
"exec-opts":["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://uyqa6c1l.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com",
"https://registry.docker-cn.com"
]
}
接下来又遇到了Pod的状态为:pod Err的情况,现在我们就需要查看pod的日志看看到底是什么问题,注意需要加上namespace参数,K8s中每一个资源只能存在于一个命名空间中(namespace),有些基础的底层资源是不存在任何命名空间中的,命名空间这个概念也比较抽象,主要是实现多租户下的资源隔离,是用户组和用户上一层的权限管理。不同的业务可以使用不同的namesapce进行隔离。对于很多问题也需要更改资源的命名空间进行处理,对于新手来说有点麻烦,需要慢慢了解折腾。
kubectl logs calico-kube-controllers-6b8f6f78dc-5j5bt --namespace kube-system
出现:dial tcp 10.96.0.1:443: connect: no route to host 重新安装,旧的网络插件还是没有删干净配和上面的清除网卡配置加上下面重置防火墙规则试试:
# systemctl stop kubelet
# systemctl stop docker
# iptables --flush #清除所有防护墙规则,不用怕。K8s会进行自我修复
# iptables -tnat --flush
# systemctl start kubelet
# systemctl start docker
现在可以了再使用kubectl get pod --all -namespace 可以看到全部Pod正常了。
那么经过千辛万苦集群安装成功了怎么安装应用呢?接下来装一个集群面板来查看集群的状态。
安装DashBoard
下图是官方的DashBoard,感觉不怎么好看,很多东西对于新手来说不够直观,功能较少。
最主要是自己也没有记录相关过程,所以这次就使用一个新的DashBorad:
安装Kuboard
它的设计理念非常适合我这种新手,让初学者把kubernetes用起来,再去了解其中的各种概念,提高K8s运维的便捷性,让运维工作尽可能在网页界面上完成。还都是中文,中国人开发的面板插件,官网说明已经有1000家公司在生产环境使用这个面板,说明已经非常成熟了。
官网地址:kuboard.cn/ ,官网还提供了非常好的K8s教程。
接下来按照官网的安装教程一键安装:
kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
等待pod创建完成:
watch kubectl get pods -n kuboard
等待时间有点长,真的比官方的DashBoard简单多了,直接使用Master节点的ip地址,面板端口30080:
http://192.168.2.181:30080/
进去之后使用默认的账号密码可以直接看到默认的k8s集群,可以设置添加其他的集群,管理其他的集群,还可以增加面板的一些用户和用户组。
基本功能都有,接下来慢慢折腾。
总结
很长的安装历程,大部分讲解了一些集群安装之前的准备,非常重要,使用kubeadm安装的命令简单但只有两个命令(创建集群,加入集群),但是其中遇到的问题非常的多,可能其中的有些细节或者问题没有说清楚,我遇到的问题基本上都可以通过搜索引擎搜到解决方法,只要自己勇于折腾不怕犯错(头铁)就一定可以完成,自己从零开始到集群正常运行非常有成就感啊。自我感觉自己说的话都比较通俗,可能说得不够准确,其中的遇到的小知识点自己没有弄清楚查了很多零零散散的资料总结了一下,没有涉及到很复杂的知识,当然作为一个新手也难免会有出错的地方,有哪些有问题的地方欢迎大家指出,不甚感激~。
接下来会在集群安装一些真正提供服务的应用测试一下,例如我我很想上篇安装GitLab进行简单CI/CD文章中合成大阿GIAO的游戏部署上去试试,哈哈,有人反映玩了好久,有毒。看到这里的都是真正大佬,感谢大家的支持,期待下篇文章早点出来的话,大家的评论点赞互动才是我的动力哇。