如何使用NodePort(或其他方法)暴露我的WebAPI,以便公共网络可以访问它?

huangapple go评论57阅读模式
英文:

How do I expose my WebAPI using NodePort (or other method) so that the public net can hit it?

问题

我正在尝试使用部署和服务在K8s上托管WebApi。我希望我的API可以通过节点的公共IP在公共网络上公开访问。我在云提供商的VM上拥有这个集群,就像云VM上的裸机一样。我已经使用Kubeadm引导了这个集群。

我能够使用节点端口类型从虚拟网络内部访问API。我的API监听端口80。

以下是YAML片段:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <api>-deployment
  labels:
    app: <api>
spec:
  replicas: 1
  selector:
    matchLabels:
      app: <api>
  template:
    metadata:
      labels:
        app: <api>
    spec:
      containers:
        - name: <api>
          image: <api_image>
          ports:
            - containerPort: 80
apiVersion: v1
kind: Service
metadata:
  name: <api>
  labels:
    app: <api>
spec:
  type: NodePort
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30000
  selector:
    app: <api>

问题是,我只能从我的本地虚拟网络中访问API,即使用虚拟网络内其他VM的私有IP地址。(我已经在网络安全组中允许了端口30000的白名单)

我在IIS上托管了相同的解决方案,并在我的VM上打开了端口,在我的云提供商上配置了安全组规则,然后ping了该VM的公共IP(云提供商门户网站上提到的公共IP),一切正常。我正在尝试在这里做同样的事情。

我应该使用NodePort吗?还有没有其他快速简单的方法?我只想让我的API能够从公共网络公开访问,即使用一个单一的IP地址(在逻辑上是显示在我的云提供商VM门户网站上的节点的公共IP地址),而不使用额外的云提供商相关的负载均衡器。

我知道Ingress存在,但它如何解决我的问题呢?我的API已经可以访问,只是无法在虚拟网络外部访问。这里到底出了什么问题?

(尽管我希望将API公开给公众,但它主要将被其他系统而不是人类使用)

编辑:这里是屏幕截图

kubectl get pods

kubectl get svc

kubctl get svc -o wide

谢谢!

英文:

I am trying to host a WebApi on K8s using deployments and service. I want my API to be publicly accessible from the public net using the Public IP of the node. I have this cluster on a Cloud provider's VM. Like bare metal but on cloud VMs. I have used Kubeadm to bootstrap this cluster.

I am able to access the API from inside the vnet (virtual network) using node port type. My API listens on 80.

Here are the YAML snippets:

apiVersion: apps/v1
kind: Deployment
metadata:
&#160; name: &lt;api&gt;-deployment
&#160; labels:
&#160;&#160;&#160; app: &lt;api&gt;
spec:
&#160; replicas: 1
&#160; selector:
&#160;&#160;&#160; matchLabels:
&#160;&#160;&#160;&#160;&#160; app: &lt;api&gt;
&#160; template:
&#160;&#160;&#160; metadata:
&#160;&#160;&#160;&#160;&#160; labels:
&#160;&#160;&#160;&#160;&#160;&#160;&#160; app: &lt;api&gt;
&#160;&#160;&#160; spec:
&#160;&#160;&#160;&#160;&#160; containers:
&#160;&#160;&#160;&#160;&#160; - name: &lt;api&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; image: &lt;api_image&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; ports:
&#160;&#160;&#160;&#160;&#160;&#160;&#160; - containerPort: 80
apiVersion: v1
kind: Service
metadata:
&#160; name: &lt;api&gt;
&#160; labels:
&#160;&#160;&#160; app: &lt;api&gt;
spec:
&#160; type: NodePort
&#160; ports:
&#160; - name: http
&#160;&#160;&#160; protocol: TCP
&#160;&#160;&#160; port: 80
&#160;&#160;&#160; targetPort: 80
&#160;&#160;&#160; nodePort: 30000
&#160; selector:
&#160;&#160;&#160; app: &lt;api&gt;

The issue is that I can only access my API from my local vnet ie using the private IP address from other VMs inside the vnet. (I have already whitelisted port 30000 from my network security group so that it allows)

I hosted the same solution on IIS and opened up ports in my VM, configured security group rules on my cloud provider and and then pinged the public IP (public IP mentioned on the cloud provider's portal) of that VM and it worked without a problem. I am trying to do the same here.

Should I be using NodePort ? Is there any other way that is quick and simple ? I just want my API to publicly accessible from public net i.e. accessible with one singular IP address (logically the node’s public IP address that is displayed on my cloud provider’s portal of the VM) without using extra cloud provider related Load Balancers.

I know Ingree exists but how does this solve my problem here ? My API is already accessible, just not outside the vnet. What exactly is going wrong here ?

(Even though I want expose the API to public, it'll mainly be used by other systems not humans)

Edit: here are the screenshots

kubectl get pods

kubectl get svc

kubctl get svc -o wide

Thanks

答案1

得分: 0

如果您的虚拟机位于私有子网内(即未分配公共IP地址),并且您希望您的API可以公开访问,那么您需要拥有一个带有公共IP的虚拟机,充当您集群的反向代理/跳转框/入口点。

如果您想要一个快速解决方案,您可以在新的虚拟机上部署一些反向代理服务器,例如 ApacheNginx,它将转发您的请求到 &lt;api-service&gt;:&lt;NortPort&gt;,这样您就可以使用新的跳转框来访问您的API。

尽管这种方法有效,但并不是最具可扩展性的选择,正如您提到的,您需要一个 Ingress Controller,它还需要一个集群的入口点/负载均衡器。更多详细信息请参考我的 SO回答

阅读这篇文章以了解有关裸机考虑的信息。

英文:

If your VM is inside a private subnet (i.e. no public IP assigned to it) and you want your API to be publicly accessible, then you need to have a VM (with a public IP) that acts as a reverse proxy/jump box/entry point to your cluster

If you want a quick solution, you can just deploy some reverse proxy server like Apache or Nginx on the new VM which will forward your request to the &lt;api-service&gt;:&lt;NortPort&gt;, that way you will be able to access your API using the new jump box

Although this works but not the most scalable option, so like you mentioned you need to have an Ingress Controller which would also need an entry point/ Load Balancer for your cluster. More details are here in my SO answer

Read this for bare-metal considerations

huangapple
  • 本文由 发表于 2023年2月16日 17:05:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75469922.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定