I have install a kubernetes cluster using three VMs in virtualBox, and my host machine's IP is 192.168.50.166, and the node information in cluster is
vm1 192.168.50.28 worker-node-1
vm2 192.168.50.29 worker-node-2
vm3 192.168.50.30 master-node
if I can have a single public IP (140.112.1.1) in my host machine, how can I expose my services like
http://140.112.1.1:xxxx/services
I think maybe I should buy another network interface in my host machine and assign public IP to this interface, but I don't known how to communicate with my cluster.
What you are searching for is the LoadBalancer service and the Ingress resource.
Kubernetes can offer LoadBalancing service (https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer), which basically acts as a way to transfer traffic from an external LoadBalancer to the backend Pods.
If you are hosting your Kubernetes cluster on top of a cloud service (Azure, Google and so on), there are a good amount of chances that you already have something that provides Load Balancer functionalities for your cluster.
If that's not the case and you want to host a Load Balancer service on top of the Kubernetes cluster, so that all your nodes partecipate in serving the public IP (or more than one public IP), a common approach is to deploy MetalLB on Kubernetes (https://metallb.universe.tf/)
Second, by using Ingress resources (https://kubernetes.io/docs/concepts/services-networking/ingress/), it is possible to manage external access to different Pods (and Services) based on the path of the request, typically HTTP or HTTPS.
It's basically a way to route incoming traffic to different Services (and different Pods) in the cluster, based on the path of the request, plus can offer SSL and a lot of other functionalities.
A common approach to serve Ingress resources on a cluster, is by using NGINX Ingress (https://kubernetes.github.io/ingress-nginx/)
With the combination of LoadBalancer + Ingress you can expose all your services behind a LoadBalancer attached to an external IP address, everything nicely in HTTP or HTTPS with certificates and so on.
With the supposition that you are hosting your Kubernetes cluster on almost-bare-metal (normal VMs like if they were bare-metal machines), you could: