Kubernetes服务外部IP挂起。

312

我正在尝试在 Kubernetes 上部署 nginx,Kubernetes 版本为 v1.5.2,我已经使用 3 个副本部署了 nginx,YAML 文件如下:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment-example
spec:
  replicas: 3
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.10
        ports:
        - containerPort: 80

现在我想将其端口80暴露在节点的端口30062上,为此我创建了以下服务:

kind: Service
apiVersion: v1
metadata:
  name: nginx-ils-service
spec:
  ports:
    - name: http
      port: 80
      nodePort: 30062
  selector:
    app: nginx
  type: LoadBalancer

该服务的表现良好,但在Kubernetes仪表板和终端上仍显示为挂起状态。 终端输出仪表板状态

32个回答

6
Kubernetes 中将运行在一组 Pod 上的应用程序公开为网络服务的一般方法称为服务。 Kubernetes 中有四种类型的服务。
ClusterIP 该服务仅可以从集群内部访问。
NodePort 您可以使用 NodeIP:NodePort 从集群外部与该服务通信。默认节点端口范围是 30000-32767,并且可以通过在集群创建时定义 --service-node-port-range 来更改此范围。
LoadBalancer 使用云提供商的负载均衡器将服务外部公开。
ExternalName 通过返回具有其值的 CNAME 记录,将服务映射到 externalName 字段(例如 foo.bar.example.com)。不设置任何代理。
仅 LoadBalancer 为 External-IP 列提供价值。并且它仅在 Kubernetes 集群能够为该特定服务分配 IP 地址时才起作用。您可以使用 metalLB 负载均衡器来为负载均衡器服务分配 IP。
我希望您的疑虑可以消除。

6

如果有人正在使用MicroK8s:您需要一个网络负载均衡器。

MicroK8s附带metallb,您可以像这样启用它:

microk8s enable metallb

<pending>应转换为实际的IP地址。


或者如果您正在Linux上使用清晰的kubernetes,您可以安装MetalLB(负载均衡器),并进行一些基本配置,例如https://metallb.universe.tf/configuration/。 - Dawid Świtoń-Maniakowski

5

针对那些在上运行时遇到此错误的用户,提供一个解决方案。

首先运行以下命令:

kubectl describe svc <service-name>

然后查看下面示例输出中的events字段:

Name:                     some-service
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"some-service","namespace":"default"},"spec":{"ports":[{"port":80,...
Selector:                 app=some
Type:                     LoadBalancer
IP:                       10.100.91.19
Port:                     <unset>  80/TCP
TargetPort:               5000/TCP
NodePort:                 <unset>  31022/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason                  Age        From                Message
  ----     ------                  ----       ----                -------
  Normal   EnsuringLoadBalancer    68s  service-controller  Ensuring load balancer
  Warning  SyncLoadBalancerFailed  67s  service-controller  Error syncing load balancer: failed to ensure load balancer: could not find any suitable subnets for creating the ELB

查看错误信息:

Failed to ensure load balancer: could not find any suitable subnets for creating the ELB

在我的情况下,创建ELB时未提供合适的子网原因如下: 1: EKS集群部署在错误的子网组上-内部子网而不是公共面向子网。 (*) 默认情况下,如果没有提供 service.beta.kubernetes.io/aws-load-balancer-internal: "true" 注释,则类型为LoadBalancer的服务将创建面向公众的负载均衡器。
2: 子网未按此处提到的要求标记。
使用以下标记标记VPC:
Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared

使用以下内容标记公共子网:

Key: kubernetes.io/role/elb
Value: 1

4

如果你使用的是裸机(bare metal),你需要使用NodePort类型, https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

在其他云供应商(如Digital Ocean、Aws等)中,LoadBalancer默认起作用。

k edit service ingress-nginx-controller
type: NodePort

spec:
   externalIPs:
   - xxx.xxx.xxx.xx 

使用公共IP


4

您可以修补托管Pod的节点的IP地址(节点私有IP),这是一个简单的解决方法。

参考以上帖子,以下操作适用于我:

kubectl patch service my-loadbalancer-service-name \ -n lb-service-namespace \ -p '{"spec": {"type": "LoadBalancer", "externalIPs":["xxx.xxx.xxx.xxx物理服务器-部署节点的私有IP"]}}'


3

minikube隧道

以下解决方案适用于我的情况。

首先,请尝试此命令:

minikube tunnel

如果这对你不起作用,请按照以下步骤操作:
我重启minikube容器。
docker minikube stop 

那么

docker minikube start

之后重新运行 kubernetes

minikube dashboard

执行完成后:

 minikube tunnel

3

Use NodePort:

$ kubectl run user-login --replicas=2 --labels="run=user-login" --image=kingslayerr/teamproject:version2  --port=5000

$ kubectl expose deployment user-login --type=NodePort --name=user-login-service

$ kubectl describe services user-login-service

(记录端口号)

$ kubectl cluster-info

(IP-> 获取主服务器运行的IP地址)

您的服务可以通过(IP):(端口)访问


2
我有同样的问题。 Windows 10桌面版+ Docker Desktop 4.7.1(77678)+ Minikube v1.25.2
根据官方文档 official docs 上的说明,我解决了这个问题。
PS C:\WINDOWS\system32> kubectl expose deployment sito-php --type=LoadBalancer --port=8080 --name=servizio-php
service/servizio-php exposed
PS C:\WINDOWS\system32> minikube tunnel
 * Tunnel successfully started

 * NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

 * Starting tunnel for service servizio-php.


PS E:\docker\apache-php> kubectl get service
NAME           TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes     ClusterIP      10.96.0.1      <none>        443/TCP          33h
servizio-php   LoadBalancer   10.98.218.86   127.0.0.1     8080:30270/TCP   4m39s

打开浏览器http://127.0.0.1:8080/


2

如果您正在使用 minikube 并尝试访问kind的服务NodePortLoadBalancer,则无法在本地系统上获取外部IP以访问该服务。因此,一个好的选择是使用minikube IP。

使用下面的命令,在您的服务暴露后获取minikube IP。

minikube service service-name --url

现在使用该URL来达到您的目的。

2

如果底层基础设施支持自动创建负载均衡器并在Kubernetes中具有相应的支持,例如Google Cloud平台和AWS,则LoadBalancer ServiceType才能正常工作。如果未配置此类功能,则LoadBalancer IP地址字段不会填充,并仍处于待处理状态,该服务将与NodePort类型服务相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接