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

Azure上K8s集群LoadBalancer IP pending,求助通过Ingress暴露流量

Fixing ExternalIP Pending & Setting Up Ingress for Your Kubernetes Hard Way Cluster on Azure

Hey there! Let's work through this together—Kubernetes the Hard Way is awesome for learning, but those cloud-native LoadBalancer integrations don't come pre-installed, which is exactly why you're seeing that <pending> ExternalIP. Let's switch gears to Ingress, which is a reliable way to expose your services without relying on cloud provider LoadBalancer controllers.

Why Your LoadBalancer Isn't Working

Kubernetes LoadBalancer services depend on a cloud provider-specific controller to provision a public load balancer (like Azure's Standard Load Balancer). Since you built your cluster manually via Kubernetes the Hard Way, this controller isn't included out of the box. Your cluster has no way to communicate with Azure's API to create the load balancer, hence the stuck <pending> status. Even setting externalIPs won't work unless your node network is explicitly configured to route that IP to your pods.

Step 1: Update Your Nginx Service to ClusterIP

Ingress routes traffic to ClusterIP services (the default service type if you don't specify), so let's adjust your existing service first. Replace your nginx-service.yaml with this:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-service
  name: nginx-service
spec:
  type: ClusterIP  # Changed from LoadBalancer
  ports:
    - name: "80"
      port: 80
      targetPort: 80
    - name: "443"
      port: 443
      targetPort: 443
  selector:
    app: nginx-service

Apply the change with:

kubectl apply -f nginx-service.yaml

Step 2: Install the Nginx Ingress Controller

Ingress needs a controller to handle incoming traffic routing. Let's deploy the official Nginx Ingress Controller manually (no external links required):

2.1 Create the Ingress Namespace

Save this as ingress-namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx

Apply it:

kubectl apply -f ingress-namespace.yaml

2.2 Set Up RBAC Permissions

Save this as ingress-rbac.yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
  name: ingress-nginx
  namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
  name: ingress-nginx
rules:
  - apiGroups: [""]
    resources: ["configmaps", "endpoints", "nodes", "pods", "secrets"]
    verbs: ["list", "watch"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses/status"]
    verbs: ["update"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingressclasses"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
  name: ingress-nginx
  namespace: ingress-nginx
rules:
  - apiGroups: [""]
    resources: ["namespaces"]
    verbs: ["get"]
  - apiGroups: [""]
    resources: ["configmaps", "pods", "secrets", "endpoints"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses/status"]
    verbs: ["update"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingressclasses"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
  name: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx
subjects:
  - kind: ServiceAccount
    name: ingress-nginx
    namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
  name: ingress-nginx
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx
subjects:
  - kind: ServiceAccount
    name: ingress-nginx
    namespace: ingress-nginx

Apply it:

kubectl apply -f ingress-rbac.yaml

2.3 Deploy the Controller & Service

Save this as ingress-controller.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/component: controller
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/component: controller
    spec:
      containers:
        - name: controller
          image: registry.k8s.io/ingress-nginx/controller:v1.8.2
          args:
            - /nginx-ingress-controller
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
            - --controller-class=k8s.io/ingress-nginx
            - --ingress-class=nginx
          securityContext:
            capabilities:
              add: ["NET_BIND_SERVICE"]
            runAsUser: 101
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          livenessProbe:
            httpGet:
              path: /healthz
              port: 10254
            initialDelaySeconds: 10
          readinessProbe:
            httpGet:
              path: /healthz
              port: 10254
            initialDelaySeconds: 10
      serviceAccountName: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

Apply it:

kubectl apply -f ingress-controller.yaml

Wait for the controller pod to be ready:

kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=120s

Step 3: Create an Ingress Resource

Now create an Ingress manifest (nginx-ingress.yaml) to route traffic to your Nginx service. This example handles HTTP traffic; we can add HTTPS later if needed:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: your-domain.com  # Replace with your domain (or remove this line to use the public IP directly)
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 80

Apply the Ingress:

kubectl apply -f nginx-ingress.yaml

Step 4: Access Your Service

Retrieve the public IP assigned to the Ingress controller:

kubectl get service ingress-nginx-controller -n ingress-nginx

Use this EXTERNAL-IP to access your Nginx app via browser or curl:

curl http://<ingress-external-ip>

You should see the Nginx default page if everything is configured correctly.

Troubleshooting Quick Checks

  • If the Ingress IP is still <pending>, verify the controller pods are running: kubectl get pods -n ingress-nginx
  • Ensure your Azure nodes have public IPs or are in a subnet with outbound internet access
  • For HTTPS, you can add TLS certificates by updating the Ingress manifest with a tls section and referencing a secret containing your certs

内容的提问来源于stack exchange,提问作者Manoj Kumar Maharana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:42:29