You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从外部访问VirtualBox中kubeadm部署的Kubernetes集群服务?

Alright, let's walk through the best ways to expose your Kubernetes services to external traffic, given your 3-node CentOS VirtualBox cluster (master, node1, node2) set up with bridge networking. All these methods work with your existing setup since your nodes have reachable IPs on your local network (192.168.19.x):

1. NodePort Service (Quick & Simple for Testing)

This is the easiest method if you're just testing or need to expose a single service quickly. NodePort exposes your service on a static port across all cluster nodes.

How to set it up:

  • Create a Service manifest of type NodePort (replace the selector and ports with your app's details):
    apiVersion: v1
    kind: Service
    metadata:
      name: my-app-service
    spec:
      type: NodePort
      selector:
        app: my-app # Match the labels on your Pods
      ports:
        - protocol: TCP
          port: 80 # Port the service listens on internally
          targetPort: 80 # Port your app is running on in the Pod
          nodePort: 30080 # Optional: Specify a port between 30000-32767; omit to let K8s auto-assign
    
  • Apply the manifest with kubectl apply -f nodeport-service.yaml

How to access:

From any machine on the same local network as your VirtualBox nodes, visit http://<node-ip>:<node-port> — e.g., http://192.168.19.87:30080 or http://192.168.19.88:30080 (any node's IP works since NodePort binds to all nodes).

Notes:

  • Make sure your CentOS firewall allows traffic on the NodePort range:
    sudo firewall-cmd --add-port=30000-32767/tcp --permanent
    sudo firewall-cmd --reload
    
  • VirtualBox bridge networking should already let external machines reach your node IPs, but double-check you can ping 192.168.19.87/88/89 from your external machine first.

2. LoadBalancer Service with MetalLB (Production-Grade Fixed IP)

Kubernetes doesn't include a built-in LoadBalancer implementation for bare-metal clusters (like yours). MetalLB fills this gap by assigning a static external IP from your local network range to your LoadBalancer services.

Step 1: Install MetalLB

Download the latest MetalLB native manifests from the project's official repo, save it locally as metallb-native.yaml, then apply it:

kubectl apply -f metallb-native.yaml

Step 2: Configure an IP Address Pool

Create a config to tell MetalLB which IPs it can use (pick a range of unused IPs in your 192.168.19.x subnet):

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: local-network-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.19.90-192.168.19.95 # Unused IPs in your network
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: advertise-pool
  namespace: metallb-system

Apply this with kubectl apply -f metallb-config.yaml

Step 3: Create a LoadBalancer Service

apiVersion: v1
kind: Service
metadata:
  name: my-app-lb-service
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Apply it, then run kubectl get service my-app-lb-service — you'll see an EXTERNAL-IP from your configured range.

How to access:

Visit http://<external-ip> (e.g., http://192.168.19.90) from any external machine on your network. MetalLB will route traffic to your service across the cluster nodes.

3. Ingress Controller (For Multiple Services with Domain Names)

If you have multiple services to expose and want to use friendly domain names instead of IPs/ports, an Ingress Controller (like Nginx Ingress) is the way to go. It acts as a reverse proxy for your cluster services.

Step 1: Install Nginx Ingress Controller

Download the Nginx Ingress manifests for bare-metal clusters from the official Kubernetes ingress-nginx repo, save it locally as nginx-ingress.yaml, then apply it:

kubectl apply -f nginx-ingress.yaml

Step 2: Create an Ingress Resource

Define how traffic should route to your service (replace the host and service details):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.k8s.local # Custom domain name
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-service # Name of your ClusterIP/NodePort service
            port:
              number: 80

Apply with kubectl apply -f ingress.yaml

Step 3: Configure DNS/Hosts File

Since myapp.k8s.local isn't a public domain, add an entry to your external machine's hosts file:

192.168.19.87 myapp.k8s.local # Use master or any node's IP where the Ingress controller is running

How to access:

Visit http://myapp.k8s.local from your external machine — the Ingress controller will route traffic to your service.

Notes:

  • Open port 80 and 443 on your cluster nodes' firewalls:
    sudo firewall-cmd --add-port=80/tcp --permanent
    sudo firewall-cmd --add-port=443/tcp --permanent
    sudo firewall-cmd --reload
    

Final Recommendations

  • Use NodePort for quick testing or small setups.
  • Use LoadBalancer + MetalLB if you need a static, dedicated IP for production services.
  • Use Ingress Controller if you have multiple services and want to use domain names.

内容的提问来源于stack exchange,提问作者Salvatore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:25:49