最近一直在学习 kubernetes(k8s)相关的知识,为了实践学到的知识,选用了 k3s 作为实际部署集群的工具,已经为位于美国的四台虚拟机搭建了一个集群,这四台虚拟机中将一台 2 核 3G 的作为 server,满足了 k3s 的最低硬件要求,目前工作良好。
不过我本来想把自己闲置的甲骨文机器也搞个集群的,但是发现甲骨文的机器似乎作为 server 有点吃力。
由于手上没有其他更高配置的虚拟机,灵光一闪,决定直接在家里 pve 里面搞一台虚拟机作为 k3s server,然后通过 tailscale 来连通所有的甲骨文机器。需要使用 tailscale 主要有两个原因:
- 家里没有公网 IP,所以甲骨文的虚拟机无法直接和它通信,所以借助万能的 tailscale 来组网,实现一个 k3s over tailscale 的效果。
- 甲骨文给的虚拟机,虽然有公网 ip,外部访问虚拟机 ip 能正确的获得响应,但这个公网 IP 不是直接给虚拟机的,所以虚拟机查看网卡的 ip 得到的是局域网的 ip,所以对于虚拟机来说,它也算没有公网。
tailscale 作为内网穿透利器,有很多免费的中继服务器。并且 k3s 对 tailscale 的支持也是开箱即用的。
具体步骤:
一:配置家里的 k3 server
server 位于家中,作为集群的控制中心。通过 pve 的模版 快速创建了一个操作系统,我安装的是 ubuntu 22。
安装完系统之后,ssh 进入创建的虚拟机。然后执行下面的步骤:
-
安装 tailscale:
curl -fsSL https://tailscale.com/install.sh | sh -
安装 k3s server:
curl -sfL https://get.k3s.io | sh - -
获取 k3s token:
cat /var/lib/rancher/k3s/server/node-token, 将结果作为 K3S_TOKEN 保存 -
创建 tailscale auth token,后面 agent 使用 tailscale 连接需要的授权信息,结果作为 TAILSCALE_TOKEN
-
配置 tailscale 的 nameserver(这个步骤似乎可以不做)
-
新增 k3s 配置文件
/etc/rancher/k3s/config.yaml,里面的内容修改为:
vpn-auth: "name=tailscale,joinKey=${TAILSCALE_TOKEN}"
你需要将 ${TAILSCALE_TOKEN} 替换为第四步获得的实际值。
- 修改完配置文件重启服务
sudo systemctl restart k3s
二:验证 k3s server 已经通过 tailscale 连接
接着我们需要确保安装的 k3s 服务正确的使用了 tailscale,这样才能让后面连上 tailscale vpn 的机器都能讲它作为 server。
通过 sudo kubectl get node
你应该能看到一个 master 节点已经就绪,类似:
ubuntu@k3s-jp-home-server:~$ sudo kubectl get node
NAME STATUS ROLES AGE VERSION
k3s-jp-home-server Ready control-plane,master 1m v1.27.5 k3s1
我这台主机叫 k3s-jp-home-server,它就是当前虚拟机的 hostname
-
通过
sudo kubectl describe node k3s-jp-home-server查看这个节点的细节信息,留意里面的 ip,我这里获取到的 IP 是 100.91.43.90: -
获取当前 tailscale 的节点的 IP:
sudo tailscale status找到这台刚刚注册的这台机器的 ip,不出意外的话这个 ip 就是上面截图的 ip。我们将这个 IP 记做TAILSCALE_IP -
最后通过
curl -vk https://100.91.43.90:6443/cacerts(替换成你自己的 ip),应该能看到 k3s server 生成的自签名证书。将https://100.91.43.90:6443作为K3S_URL
到这里我们就拥有了一个在 tailscale vpn 下面可用的 k8s 主节点。
三:在甲骨文云配置 k3s agent
- 进入甲骨文云管理后台,新建一条规则,允许所有协议(相当于关闭了防火墙)
- ssh 登陆到虚拟机,删除 ubuntu iptable 加载器,升级 iptable 并重启
apt-get remove iptables-persistant - 安装 tailscale:
curl -fsSL https://tailscale.com/install.sh | sh - 运行 tailscale:
tailscale up这样才能连接到 家里的 server - 通过
tailscale status确认状态正常,然后通过 curl 确认甲骨文能通过 tailscale 连接到家里的 server:
curl -vk https://100.91.43.90:6443/cacerts
能看到自签名证书后,说明甲骨文能连接到家里的 server 了。 - 安装 k3s agent:
export K3S_URL=https://100.91.43.90:6443
export K3S_TOKEN=Kxxx::server:xxx
curl -sfL https://get.k3s.io | K3S_URL=${K3S_URL} K3S_TOKEN=${K3S_TOKEN} sh -
- 配置 k3s 使用 tailscale。和配置 server 一样,新增文件
/etc/rancher/k3s/config.yaml,里面的内容修改为vpn-auth: "name=tailscale,joinKey=${TAILSCALE_TOKEN}" - 重启 k3s agent 使得刚刚的配置生效:
sudo systemctl restart k3s-agent
四:验证 k3s agent 成功加入集群
回到家里的终端在通过 sudo kubectl get node 应该能看到刚刚加入的机器。
❯ kubectl get node
NAME STATUS ROLES AGE VERSION
k3s-jp-home-server Ready control-plane,master 30m v1.27.5 k3s1
instance-20220922-2113 Ready 3m v1.27.5 k3s1
我这里多出来了一台 instance-20220922-2113
同时通过 sudo kubectl describe node instance-20220922-2113 查看加入的 agent 的 ip,应该是 tailscale 提供的 ip 范围(100.64.0.0/10)而不是甲骨文的内网 ip(比如 10.0.0.x)
按照上述方法把自己剩下的甲骨文加到这个集群后的效果:
到这里,我们就把所有的免费甲骨文加到集群里面去了。
五:验证 k3s 集群功能正常
部署一个最简单的 whoami 验证一下集群里面各台机器的联通性 (它的原始文件来自 这里,镜像从 nginx 换成了 whoami,方便查看 pod 信息)
新建一个 traefik.yaml 文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: nginx.tomyail.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
这个配置大致的意思就是新建五个 pod,然后用名字是 nginx-service 的服务 连接这五个 pod,对外暴露一个 ip,最后通过 ingress 将 http 流量路由到这个 nginx-service 服务。新建五个是因为我有五个 node,所以他们大概率会分散到每台机器上。(k8s 如何将 pod 分配到 node 的策略有一堆配置可以学习呢)
之后 sudo kubectl apply -f traefik.yaml 执行部署。稍等片刻查看部署状态:sudo kubectl get pod -o wide
ubuntu@k3s-jp-home-server:~$ sudo kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-58ffdc8f48-qzwrb 1/1 Running 0 26h 10.42.2.7 oracle-korea-2
nginx-deployment-58ffdc8f48-7r4bt 1/1 Running 0 26h 10.42.1.6 oracle-korea-1
nginx-deployment-58ffdc8f48-525k6 1/1 Running 0 26h 10.42.0.12 k3s-jp-home-server
nginx-deployment-58ffdc8f48-cgzlf 1/1 Running 0 23h 10.42.3.3 oracle-toyko-1
nginx-deployment-58ffdc8f48-blmh6 1/1 Running 3 (22h ago) 23h 10.42.4.8 instance-20220922-2113
在 server 的机器上,curl 上面这几个 ip,看到下面的这些信息就表示集群里面的 whoami 部署成功了
ubuntu@k3s-jp-home-server:~$ curl 10.42.3.3
Hostname: nginx-deployment-58ffdc8f48-cgzlf
IP: 127.0.0.1
IP: ::1
IP: 10.42.3.3
IP: fe80::645a:46ff:fe5d:e2f3
RemoteAddr: 10.42.3.1:56192
GET / HTTP/1.1
Host: 10.42.3.3
User-Agent: curl/7.58.0
Accept: */*
最后就是进入 cloudflare,为刚刚的 nginx 服务增加一条 dns A 记录,这个记录的 IP 可以是任何一个集群里面有公共 ip 的机器。当然你可以选择用一些自动化工具来自动根据 ingress 自动更新 cloudflare dns 记录,比如 external-dns 。
最后你就可以通过 nginx.tomyail.com 访问我部署的这个服务了。
如果你希望看到包含图文的更详细文章,欢迎访问我的博客:使用k3s 和 tailscale 在甲骨文云和家之间搭建 kubernetes集群

学习了
好文绑定
学习