Kubernetes服务外部ip挂起

我试图在kubernetes上部署nginx, kubernetes版本是v1.5.2, 我已经部署了nginx的3个副本,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

现在我想在节点的30062端口上公开它的80端口,为此我在下面创建了一个服务,

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

这个服务工作得很好,但它不仅在kubernetes仪表板上也在终端上显示为待定。 终端输出仪表盘状态 < / p >

277038 次浏览

看起来你正在使用一个自定义的Kubernetes集群(使用minikubekubeadm或类似的)。在这种情况下,没有集成LoadBalancer(不像AWS或谷歌Cloud)。在这个默认设置下,你只能使用NodePort或入口控制器。

通过入口控制器,你可以设置一个映射到你的pod的域名;如果你使用入口控制器,你不需要给你的服务LoadBalancer类型。

要访问minikube上的服务,您需要运行以下命令:

minikube service [-n NAMESPACE] [--url] NAME

更多信息:Minikube GitHub

如果你没有使用GCE或EKS(你使用了kubeadm),你可以在YAML服务中添加externalIPs规范。您可以使用与节点的主接口相关联的IP,例如eth0。然后,您可以使用节点的外部IP从外部访问该服务。

...
spec:
type: LoadBalancer
externalIPs:
- 192.168.0.10

使用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)(港):访问

我使用kubeadm创建了一个单节点k8s集群。当我尝试PortForwardkubectl代理时,它显示外部IP为待定。

$ kubectl get svc -n argocd argocd-server
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
argocd-server   LoadBalancer   10.107.37.153   <pending>     80:30047/TCP,443:31307/TCP   110s

在我的情况下,我打了这样的服务:

kubectl patch svc <svc-name> -n <namespace> -p '{"spec": {"type": "LoadBalancer", "externalIPs":["172.31.71.218"]}}'

在此之后,它开始通过公共IP服务

$ kubectl get svc argo-ui -n argo
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
argo-ui   LoadBalancer   10.103.219.8   172.31.71.218   80:30981/TCP   7m50s

如果你正在使用Minikube,有一个神奇的命令!

$ minikube tunnel

希望有人能节省几分钟的时间。

< p >引用链接 https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-tunnel < / p >

同样的问题:

Os >kubectl get SVC right sabertooth-wordpress

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
/strong> LoadBalancer 10.97.130.7 "pending" 80:30454/TCP,443:30427/TCP

Os >minikube服务列表

|-------------|----------------------------|--------------------------------|

|命名空间|名称| url |

|-------------|----------------------------|--------------------------------|

| default | kubernetes |无节点端口|

| default | right-sabertooth-mariadb | |无节点端口

| default | right-sabertooth-wordpress | http://192.168.99.100:30454 |

| | | __abc0 |

| kube-system | kube-dns | |无节点接口

| kube-system | tiller-deploy | |无节点接口

|-------------|----------------------------|--------------------------------|

然而,它可以通过http://192.168.99.100:30454访问。

删除现有服务,并创建一个相同的新服务解决了我的问题。我的问题是我定义的负载平衡IP被使用,因此外部端点正在等待。当我改变一个新的负载平衡IP时,它仍然不能工作。

最后,删除现有的服务并创建一个新的服务解决了我的问题。

如果运行在minikube上,如果不使用default,不要忘记提到namespace。

Minikube服务<<Service_name >>——url——namespace=<<namespace_name > >

检查kube-controller日志。我能够通过将clusterID标记设置为我部署集群的ec2实例来解决这个问题。

下面是@Javier的回答。我已经决定为我的负载均衡器“修补外部IP”。

 $ kubectl patch service my-loadbalancer-service-name \
-n lb-service-namespace \
-p '{"spec": {"type": "LoadBalancer", "externalIPs":["192.168.39.25"]}}'

这将用一个新的补丁IP地址替换那个“pending”,你可以为你的集群使用。

了解更多。请参阅恋人的Minikube为Kubernetes提供LoadBalancer支持上的帖子

这么做可不干净。我需要一个临时的解决方案。希望这能帮助到一些人。

当你使用Minikube时,你可以得到IP和端口

minikube service [service name]

例如:

minikube service kubia-http

如果你不在受支持的云上(aws, azure, gcloud等),你不能在没有MetalLB https://metallb.universe.tf/ 但它还在测试阶段。< / p >

如果你正在使用minikube,那么从终端运行下面的命令,

$ minikube ip
$ 172.17.0.2 // then
$ curl http://172.17.0.2:31245
or simply
$ curl http://$(minikube ip):31245

LoadBalancer ServiceType只有在底层基础设施支持自动创建负载均衡器并在Kubernetes中有各自的支持时才会工作,就像谷歌云平台和AWS一样。如果没有配置这样的特性,LoadBalancer IP地址字段不会填充,仍然处于待定状态,服务将以与NodePort类型的服务相同的方式工作

您可以修补pod托管的节点的IP(节点的私有IP),这是简单的解决方案。

参考上述职位,以下对我来说很有用:

kubectl patch service my-loadbalancer-service-name \ -n lb-service-namespace \ - p '{"规范":{“类型”:“loadbalance”、“externalIPs”:[" xxx.xxx.xxx。xxx物理服务器私有IP -部署节点-部署所在节点"]}}'

. xxx物理服务器私有IP -部署节点-部署节点

如果它是您的私有k8s集群,MetalLB将是一个更好的选择。以下是步骤。

步骤1:在集群中安装MetalLB

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
# On first install only
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

步骤2:使用configmap配置它

apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.42.42.100-172.42.42.105 #Update this with your Nodes IP range

步骤3:创建您的服务以获得外部IP(可能是私有IP)。

马其顿:

MetalLB安装前: enter image description here < / p >

MetalLB安装后: enter image description here < / p >

enter image description here

为那些在上运行时遇到此错误的人添加解决方案。

首先运行:

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集群部署在错误的子网组-内部子网而不是公共子网。< br > (*)默认情况下,如果没有提供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
有三种公开服务的类型 Nodeport ClusterIP loadbalance < / p > 当我们使用负载均衡器时,我们基本上要求我们的云提供商给我们一个可以在线访问的dns

.

.

.

所以负载均衡器类型不工作在我们的本地minikube环境。

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

MicroK8s自带metallb,你可以这样启用它:

microk8s enable metallb

<pending>应该变成一个实际的IP地址。

可能是您部署服务的子网没有足够的ip

在Kubernetes中,将运行在一组Pods上的应用程序公开为网络服务的一般方法称为service。Kubernetes中有四种类型的服务。

< p > ClusterIP

.服务只能从集群内部访问 < p > NodePort 你将能够从集群外部使用NodeIP与服务通信:NodePort.default节点端口范围是30000-32767,这个范围可以在创建集群时通过定义--service-node-port-range来改变 < p > loadbalance

.使用云提供商的负载均衡器在外部公开服务 < p > ExternalName 通过返回带有值的CNAME记录,将服务映射到externalName字段的内容(例如,foo.bar.example.com)。没有设置任何类型的代理

只有LoadBalancer为External-IP列提供值。只有当Kubernetes集群能够为特定的服务分配IP地址时,它才能工作。你可以使用metalLB负载均衡器为你的负载均衡器服务提供ip。

我希望你的疑虑能消失。

对于您的用例,最好的选择是使用NordPort服务而不是loadbalancer类型,因为loadbalancer不可用。

我在docker桌面上得到这个错误。我只是退出并再次打开它(Docker-desktop)。只花了几秒钟,然后就没问题了。

如果你正在使用裸金属,你需要NodePort类型 https://kubernetes.github.io/ingress-nginx/deploy/baremetal/ < / p >

LoadBalancer默认工作在其他云提供商,如数字海洋,Aws等

k edit service ingress-nginx-controller
type: NodePort


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

使用公共IP

如果您尝试在on-prem云中执行此操作,则需要一个L4LB服务来创建LB实例。

否则你就会有无尽的“悬而未决”。你描述的信息。它可以在视频中看到:https://www.youtube.com/watch?v=p6FYtNpsT1M

您可以使用开源工具来解决这个问题,视频提供了一些关于自动化过程应该如何工作的指导。

minikube隧道

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

首先,试试这个命令:

minikube tunnel

如果这对你不起作用。遵循以下几点:

我重新启动minikube容器。

docker minikube stop

然后

docker minikube start

之后重新运行kubernetes

minikube dashboard

完成后执行:

 minikube tunnel

我在AWS EKS上也有同样的问题

问题是这样解决的:

您的Amazon虚拟私有云(Amazon VPC)的正确标记 子网< / p >

需要的AWS IAM (Identity and Access Management)权限 一个有效的Kubernetes服务定义Load 有足够的空闲IP地址 在你的子网

需要确保以下标签

Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared

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

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

供参考,也确保sts是为您正在工作的区域启用sts设置可以在用户,区域设置下找到。

我也有同样的问题。 Windows 10 Desktop + Docker Desktop 4.7.1 (77678) + Minikube v1.25.2

. Windows 10 Desktop + Docker Desktop 4.7.1 (77678) + Minikube v1.25.2

根据我这边的官方文档,我用:

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/上的打开浏览器

删除所有旧的服务并创建新的服务解决了我的问题。IP被绑定到旧的服务。试试“$kubectl get svc"然后逐个删除所有svc“$kubectl delete svc 'svc name' "

那些正在使用minikube并试图访问NodePortLoadBalancer类服务的对象。

我们没有获得外部IP来访问本地的服务 系统。因此,一个很好的选择是使用minikube IP

一旦你的服务被公开,使用下面的命令来获取minikube IP。

minikube service service-name --url

现在使用这个URL来达到你的目的。