我正在使用 MicroK8S 学习 K8S。我有一个三节点集群,每个节点有 16G RAM。集群已自动进入 HA 模式。集群位于我的家庭局域网上。
这是我的节点:
姓名 | 知识产权 | 颜色 | 角色 |
---|---|---|---|
阿伦 | 192.168.50.251 | 黄色的 | 领导者 |
尼卡 | 192.168.50.74 | 蓝色的 | 工人 |
山崎 | 192.168.50.135 | 绿色的 | 工人 |
设置
我在集群中的一个 pod 上运行了一个 Web 应用。它在端口 9090 上响应。下面是我让它运行的方法。
我在开发笔记本电脑上有一个图像,我将其转换成 tarball:
docker save k8s-workload > k8s-workload.docker.tar
然后我把这个 tarball 发送给集群的领导者:
scp k8s-workload.docker.tar 192.168.50.251:/home/myuser/
然后我将该图像侧载到集群上的所有节点中:
root@arran:/home/myuser# microk8s images import < k8s-workload.docker.tar
Pushing OCI images to 192.168.50.251:25000
Pushing OCI images to 192.168.50.135:25000
Pushing OCI images to 192.168.50.74:25000
然后,我在每个节点上验证图像的 MIME 类型和校验和,因为我有一些存在的问题:
root@arran:/home/myuser# microk8s ctr images list | grep workload
docker.io/library/k8s-workload:latest application/vnd.docker.distribution.manifest.v2+json sha256:725b...582b 103.5 MiB linux/amd64
最后我运行工作负载,确保 K8S 不会尝试拉取镜像(这是不必要的,但默认策略是无论如何都要尝试):
root@arran:/home/myuser# microk8s kubectl run k8s-workload --image=k8s-workload --image-pull-policy='Never' --port=9090
pod/k8s-workload created
然后我从领导节点确认这已成功:
root@arran:/home/myuser# microk8s kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
k8s-workload 1/1 Running 0 83m 10.1.134.216 yamazaki <none> <none>
运行应用程序
为了从我的开发笔记本电脑访问 Web 应用程序,我首先在一个节点上公开该应用程序。该 pod 在 Yamazaki 节点上运行,因此我最初从该节点运行它:
root@yamazaki:/home/myuser# microk8s kubectl port-forward pod/k8s-workload 9090 --address='0.0.0.0'
Forwarding from 0.0.0.0:9090 -> 9090
这很好用。
问题
我希望通过向集群中的任何节点(而不仅仅是这个节点)发出请求来访问该应用程序。目前该应用程序仅在一个节点上运行,我希望即使我向另一个节点发出 Web 请求,它也能正常工作。
我知道 K8S 有内部网络可以做我想做的事情。例如,如果我port-forward
在 Arran 上运行命令(并在 Yamazaki 上终止相同的命令),那么即使 pod 仅在 Yamazaki 上运行,应用程序仍将运行。但我仍然只能从一个 IP(Arran,端口转发器正在运行)访问该应用程序。
当然,我可以通过在每个节点的 SSH 会话上运行端口转发器来做我想做的事情。但我想运行一些在所有 SSH 会话终止后仍能继续存在的程序。
理想情况下,我希望使用控制台命令执行此操作,但我不知道是否需要 YAML 清单。从我目前的研究来看,我认为我需要一个 ClusterIP。
更新/研究 1
我正在阅读裸机上的 K8S 手册页负载平衡。部分页面推荐用户应用 646 行的配置文件,这对于学习场景来说可能是适得其反的。
此示例看起来更合理,但并不清楚如何指示 LB 在所有主机上运行。
更新/研究 2
我也找到此资源特别是针对 MicroK8S,它推荐使用入口插件。不幸的是,这要求将我的工作负载设置为服务,而目前我只有一个 Pod,所以我认为这是不可能的。
答案1
让我们使用NodePort
service
,它是一种将一组上运行的应用程序公开Pods
为网络服务的抽象方式,它将每个端口上的传入流量路由Node
到您的Service
。
我们可以这样定义:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
ports:
- port: 9090
targetPort: 9090
nodePort: 30090
selector:
run: k8s-workload
然后我们应用清单,它应该可以工作microk8s kubectl apply -f my-service.yaml