目前我正在做一个小型业余项目,一旦准备就绪,我就会将其开源。此服务在 Google Container Engine 上运行。我选择 GCE 是为了避免配置麻烦,成本实惠,并能学习新东西。
我的 pod 运行良好,我创建了一个类型的服务LoadBalancer
以在端口 80 和 443 上公开该服务。这很完美。
但是,我发现,对于每个LoadBalancer
服务,都会创建一个新的 Google Compute Engine 负载均衡器。这个负载均衡器非常昂贵,而且对于单个实例上的业余项目来说,实在是太过分了。
为了降低成本,我正在寻找一种不使用负载均衡器来公开端口的方法。
我到目前为止已经尝试过:
部署
NodePort
服务。不幸的是,不允许公开 30000 以下的端口。部署一个 Ingress,但这也会创建一个负载均衡器。
尝试禁用
HttpLoadBalancing
(https://cloud.google.com/container-engine/reference/rest/v1/projects.zones.clusters#HttpLoadBalancing),但它仍会创建一个负载均衡器。
有没有办法在没有负载均衡器的情况下为 Google Container Engine 上的单个实例公开端口 80 和 443?
答案1
是的,通过服务上的 externalIP。我使用过的示例服务:
apiVersion: v1
kind: Service
metadata:
name: bind
labels:
app: bind
version: 3.0.0
spec:
ports:
- port: 53
protocol: UDP
selector:
app: bind
version: 3.0.0
externalIPs:
- a.b.c.d
- a.b.c.e
请注意,配置文件中列出的 IP 必须是 GCE 上的内部 IP。
答案2
除了 ConnorJC 的出色且有效的解决方案之外:此问题也描述了相同的解决方案: Kubernetes——我可以避免使用 GCE 负载均衡器来降低成本吗?
“internalIp” 指的是计算实例(又名节点)的内部 IP(如在 Google Cloud Platform -> Google Compute Engine -> VM Instances 上所见)
这评论提示了为什么应该配置内部 IP 而不是外部 IP。
此外,在为端口 80 和 443 配置服务后,我必须创建一条允许流量到达我的实例节点的防火墙规则:
gcloud compute firewall-rules create your-name-for-this-fw-rule --allow tcp:80,tcp:443 --source-ranges=0.0.0.0/0
完成此设置后,我可以通过 http(s)://externalIp 访问我的服务
答案3
如果您只有一个 pod,您可以使用hostNetwork: true
它来实现这一点:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: caddy
spec:
replicas: 1
template:
metadata:
labels:
app: caddy
spec:
hostNetwork: true # <---------
containers:
- name: caddy
image: your_image
env:
- name: STATIC_BACKEND # example env in my custom image
value: $(STATIC_SERVICE_HOST):80
请注意,通过这样做你的 pod 将继承主机的 DNS 解析器而不是 Kubernetes 的。这意味着您无法再通过 DNS 名称解析集群服务。例如,在上面的示例中,您无法static
访问http://静态。您仍然可以通过集群 IP 访问服务,这些 IP 由环境变量。
此解决方案比使用服务的 externalIP 更好,因为它绕过了 kube-proxy,并且您将收到正确的源 IP。
答案4
由于成本和供应商锁定,除非必要,我都不愿意使用云负载均衡器。
相反,我用的是这个:https://kubernetes.github.io/ingress-nginx/deploy/
它是一个为您运行负载均衡器的 pod。该页面有 GKE 特定的安装说明。