在Oracle Cloud上自建Kubernetes

可能是Oracle Cloud免费账户玩的腻了,冒着被封号的风险直接尝试去升级了付费账户,运气不错,升级成功了。

但是福祸相依,升级成功之后,我如愿以偿的得到了ARM版的总共4核心24G的配置的机器,根据Oracle的规则,只能有两个硬盘,所以我就打算CPU、内存、硬盘对半拆出两台机器运行ubuntu on arm64组一个k3s集群。

为什么选择k3s以及ubuntu server arm64?

首先预告一下,这个是我完全失败的,这两个组合坑了将近两天两夜,我一直以为是自己的组网问题,从没怀疑过单机版的k3s也是无法跑起来的。还好我之前使用过k3s成功搭建过好几次集群都是正常的,所以我才会怀疑是不是ubuntu系统的原因。

结果排查下来,还真的是ubuntu问题。 我后面接着跑过sealos、kubesphere都是失败,最后我换成了Oracle Linux 8,终于成功了。

不过针对ubuntu on oracle cloud,也是有一些东西可以记录的。

问题1: 明明我在VPC安全组里面放行了端口,为啥还是不通呢?

答案:因为ubuntu会自带防火墙,默认只开了22、80、443这几个常用端口,这样会导致双重防火墙。建议直接通过下面命令关闭防火墙:

sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCaEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F

sudo netfilter-persistent save

我在这里面卡了好几个小时,因为大部分的云厂商的方式都是靠外面的VPC防火墙,内部的是全开的。突然内部还有一层防火墙真的是让我有点措手不及。我当时是通过docker运行一个nginx 80来确认是系统内部防火墙的原因的,docker有一点好处就是,它会尝试把暴露的端口在防火墙里面设置允许。

问题2: 为啥我在ubuntu上面安装k3s失败?

答案: 这是一个未解之谜。 我没有找到对应的答案,因为我感觉也不是k3s的问题,sealos、kubesphere都是失败的。 我当时记得错误大概就是CoreDNS pod无法启动,日志显示无法链接6443端口api,我观察了网卡是存在的,ip也是有的,但是ping它就是不可到达,真的是见鬼了。

折腾k3s以及ubuntu server arm64我学到了什么?

我学会了用terraform直接来管理oracle cloud的vm实例,因为网络一直不通导致两个集群的pod始终无法100%可用,所以我一直怀疑是系统操作哪一步不对,以我的性格一定要用干净的系统重来,避免被自己走过的路再坑一把。

我连续创建又删除了五六次之后,我实在受不了了,因为每次创建都得选规格不说,每次的公网ip还是不断变化的,我从oracle cloud创建两台机器之后,回来ssh终端里面还得去改ip,所以我只能在GPT4的帮助下,快速将terraform搭建起来,还好oracle cloud官方自己维护了provider,所以这里面没有花多少时间就快速完成了。

目前还遗留的一个问题就是静态ip和实例绑定,无法一次通过terraform完成,按照官方教程还要在里面跑oracle cli,所以我就直接在控制台里面手动绑定了。

也多亏了terraform,我可以反复的快速创建和删除,差不多在一分钟之内完成,这样我就可以快速的验证我的操作是否正确,而不是等待oracle cloud的实例创建完成,然后再去验证。

那么后面为什么又换成了Oracle Linux呢?

说实话,我并不想用它的。我对于yum系早就没太多感情,特别是centos 7已经被redhat给划上了句号,我就一直是Debian系的忠实用户,但是之前反复重开了好几次实例,确认是网卡创建成功了但是就是无法通信,不得不让我怀疑在arm64的架构下面网卡是存在问题的。

所以我在控制台里面手动创建了一台新的Oracle Linux 8 arm64版本的,结果安装k3s之后,不出我所料是失败的;但是我看到系统已经被我弄脏了,死马当活马医给它试了一下sealos,结果成功了。 然后我又重新开了一个实例确认还是OK的,最后我感觉把对应的image id拷贝的terraform文件里面,启动安装成了sealos。

sealos好用吗?

首先,它真的是很好用的,真的是太简单了。 只需要把sealos的cli下载下来,然后直接一句sealos run labring/kubernetes:v1.27.7 labring/helm:v3.9.4 labring/cilium:v1.13.4 --single就完成了。但是为啥我最后是选择了单节点而不是集群呢,原因是我折腾累了,使用两个节点的集群,依然是没有任何的可靠性,收益比太多。

如果我哪一天业务真的需要容灾以及负载均衡,那么我肯定是直接选择托管版本的kubernetes,或者是两台以上单独使用一个负载均衡在前面。前提是实例要足够多。

为什么还有caddy server?

但是我这样使用下来遇到的问题是,启动之后发现没有网关,所以我继续使用helm安装了ingress-nginx和metallb,可能感觉metalb我用的方式不对,或者是不需要它,因为它只虚拟出了一个内网ip,我最后还是通过caddy监听80和443端口,转发流量到ingress-nginx上面。

caddy的安装稍微遇到了点问题, 因为我想着既然都是使用集群,到时候应用会很多,不可能一个个手动配置CaddyFile。想要一步到位配置一个泛域名过去。

这里面遇到的问题是caddy 如果想要签发泛域名证书,就必须得使用dns验证方式,之前单域名的方式才能通过http验证。仔细自考一下这样设计还是很合理的,因为不可能因为一个网站被黑客攻下,结果签出泛域名证书把整个域名给黑掉吧。

后面先是通过yum源安装了caddy,然后再去网站上下载了携带dns模块的caddy二进制,直接把它覆盖掉了,然后再去配置dns验证,最后成功了。

CaddyFile的配置如下:

*.walle.ing {
        reverse_proxy 10.55.0.0:80 {
                header_up Host {http.request.host}
                header_up X-Real-IP {http.request.remote.host}
        }

        tls {
                dns cloudflare {env.CF_API_TOKEN}
        }
}

总结

随着我发布了一个nginx yml上去,配置了test域名解析到ingress成功,就说明我本次的折腾已经结束了。目前该玩的已经告一段落了,先继续折腾Unity去吧。