Kubernetes 服务外部 ip 待定
Posted
技术标签:
【中文标题】Kubernetes 服务外部 ip 待定【英文标题】:Kubernetes service external ip pending 【发布时间】:2017-10-21 23:51:15 【问题描述】:我正在尝试在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
现在我想在节点的 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 仪表板上显示为挂起,在终端上也显示为待处理。
【问题讨论】:
【参考方案1】:您似乎正在使用自定义 Kubernetes 集群(使用 minikube
、kubeadm
等)。在这种情况下,没有集成 LoadBalancer(与 AWS 或 Google Cloud 不同)。使用此默认设置,您只能使用 NodePort
或 Ingress Controller。
使用Ingress Controller,您可以设置一个映射到您的 pod 的域名;如果使用 Ingress Controller,则无需为 Service 提供 LoadBalancer
类型。
【讨论】:
这并没有真正回答问题?用户使用LoadBalancer
作为服务类型,这是一个有效的服务类型。 NodePort
和 ingress
是其他方法,但不能真正解决问题,对吧?
这是一个有效的服务类型,但它被用于不兼容的平台(至少默认情况下)。为了使用 LoadBalancer,您必须有一个可以为 pod 提供外部 IP 的平台,这是 Google Cloud 或 AWS 所做的事情。
我在 AWS 上使用 kubeadm。我还能LoadBalancer
吗?
如果您使用 minikube,请运行“minikube 隧道”。现在检查您的服务,您将获得公共 IP。这是有关更多信息的文档minikube.sigs.k8s.io/docs/tasks/loadbalancer
您还可以考虑 MetalLB,它是通过标准路由协议为裸机 Kubernetes 集群提供的负载均衡器。 Kubernetes(不作为服务)与 MetalLB 非常吻合。【参考方案2】:
如果你使用 Minikube,有一个神奇的命令!
$ minikube tunnel
希望有人可以为此节省几分钟。
参考链接 https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-tunnel
【讨论】:
我试过minikube tunnel
,它实际上解决了pending
的问题,但是新的外部IP不起作用:我收到一个超时错误...
@a.barbieri 确保您使用的是隧道 ip 而不是 minikube ip。 “使用 IP 10.106.102.98 修补 ingress-nginx”
是的,谢谢彼得。会尝试。无论如何切换到 Docker 桌面,我已经能够通过直接在 localhost 上运行的开箱即用设置来克服这个问题。
@a.barbieri 您能否指出这些选项在哪里以及您必须将它们设置为什么?我也想使用 Docker Desktop 来解决这个问题,但我不知道在哪里以及如何设置它。
@user658182 对不起。自从我用 Kubernetes 做这个探索以来已经两年了。我个人转向了一个更适合我的场景的纯 Docker 解决方案。【参考方案3】:
如果您没有使用 GCE 或 EKS(您使用的是 kubeadm
),您可以将 externalIPs
规范添加到您的服务 YAML。您可以使用与节点的主接口关联的 IP,例如 eth0
。然后,您可以使用节点的外部 IP 从外部访问该服务。
...
spec:
type: LoadBalancer
externalIPs:
- 192.168.0.10
【讨论】:
这里肯定少了一条信息:“externalIPs不由Kubernetes管理,由集群管理员负责。” (kubernetes.io/docs/concepts/services-networking/service)。我必须安装某种“控制器”吗? 我正在关注 Kubernetes 教程 (kubernetes.io/docs/tutorials/stateless-application/guestbook),它在 kubeadm 上运行良好 谢谢 - 很棒,按预期工作。我已经向节点 eth 网络 IP 公开了服务,现在可以在集群外部访问它【参考方案4】:要访问minikube
上的服务,您需要运行以下命令:
minikube service [-n NAMESPACE] [--url] NAME
更多信息在这里:Minikube GitHub
【讨论】:
具体例子:minikube service spark-ui-proxy --url 192.168.99.100:30621 这行得通!这个命令实际上做了什么?【参考方案5】:我使用 kubeadm 创建了一个单节点 k8s 集群。当我尝试 PortForward 和 kubectl proxy 时,它显示外部 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
【讨论】:
或许你应该提一下“172.31.71.218”的来源? @EuRBamarth 我尝试使用我所有节点的 IP 来代替他的 172.31.71.218,它们都可以工作【参考方案6】:在使用 Minikube 时,您可以获取您通过的 IP 和端口 可以通过运行来访问服务:
minikube service [service name]
例如:
minikube service kubia-http
【讨论】:
【参考方案7】:如果在 minikube 上运行,如果您不使用默认命名空间,请不要忘记提及命名空间。
minikube 服务 > --url --namespace=>
【讨论】:
【参考方案8】:如果是您的私有 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 之前:
安装 MetalLB 后:
【讨论】:
MetalLB 会比什么更合适? 对于原问题中描述的场景。 我今天看到了一个使用 TapTun 为 macOS 设置的 MetalLB。有点骇人听闻。我相信可以理解 OP 正在使用本地设置。您是否建议使用本地 TapTun 设置来克服 Linux hyperkit 网络限制? 有什么命令可以获取节点IP范围吗?【参考方案9】:如果您使用的是 minikube,请从终端运行以下命令,
$ minikube ip
$ 172.17.0.2 // then
$ curl http://172.17.0.2:31245
or simply
$ curl http://$(minikube ip):31245
【讨论】:
【参考方案10】:按照@Javier 的回答。我决定为我的负载均衡器“修补外部 IP”。
$ kubectl patch service my-loadbalancer-service-name \
-n lb-service-namespace \
-p '"spec": "type": "LoadBalancer", "externalIPs":["192.168.39.25"]'
这会将“待处理”替换为可用于集群的新修补 IP 地址。
有关此的更多信息。请参阅 karthik 的帖子LoadBalancer support with Minikube for Kubernetes
这不是最干净的方法。我需要一个临时解决方案。希望这可以帮助某人。
【讨论】:
完美答案!【参考方案11】:为在amazon-eks 上运行时遇到此错误的用户添加解决方案。
首先运行:
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:子网没有按照here提到的要求进行标记。
将 VPC 标记为:
Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared
使用以下标记公共子网:
Key: kubernetes.io/role/elb
Value: 1
【讨论】:
【参考方案12】:使用 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->获取master运行的IP)
您的服务可通过 (IP):(port)
访问【讨论】:
【参考方案13】:如果有人在使用 MicroK8s:您需要一个网络负载均衡器。
MicroK8s自带metallb,你可以这样启用:
microk8s enable metallb
<pending>
应该会变成一个实际的 IP 地址。
【讨论】:
或者,如果这在 linux 上很清楚 kubernetes,您可以使用一些基本配置安装 MetalLB(负载均衡器),例如 metallb.universe.tf/configuration【参考方案14】:LoadBalancer ServiceType 仅在底层基础设施支持自动创建负载均衡器并在 Kubernetes 中具有相应支持的情况下才有效,例如 Google Cloud Platform 和 AWS。如果未配置此类功能,则 LoadBalancer IP 地址字段未填充且仍处于挂起状态,并且该服务将与 NodePort 类型的服务以相同的方式工作
【讨论】:
【参考方案15】:您可以修补托管 pod 的节点 IP(节点的私有 IP),这是简单的解决方法。
参考以上帖子,以下对我有用:
kubectl 补丁服务 my-loadbalancer-service-name \ -n lb-服务命名空间 \ -p '"spec": "type": "LoadBalancer", "externalIPs":["xxx.xxx.xxx.xxx 物理服务器的私有IP-节点-部署完成的地方"]'
【讨论】:
【参考方案16】:同样的问题:
os>kubectl get svc right-sabertooth-wordpress
名称类型 CLUSTER-IP EXTERNAL-IP PORT(S)right-sabertooth-wordpress LoadBalancer 10.97.130.7 “待定” 80:30454/TCP,443:30427/TCP p>
os>minikube 服务列表
|-------------|---------------|--- -----------------------------------------|
|命名空间 |姓名 |网址 |
|-------------|---------------|--- -----------------------------------------|
|默认 | Kubernetes |无节点端口|
|默认 |右剑齿-mariadb |无节点端口|
|默认 | right-sabertooth-wordpress | http://192.168.99.100:30454 |
| | | http://192.168.99.100:30427 |
| kube 系统 | kube-dns |无节点端口|
| kube 系统 |分蘖部署 |无节点端口|
|-------------|-----------------|--- ------------------------------|
但是,可以通过 http://192.168.99.100:30454 访问。
【讨论】:
这不是对所提问题的回答。【参考方案17】:暴露你的服务有三种类型 节点端口 集群IP 负载均衡器
当我们使用负载均衡器时,我们基本上要求我们的云提供商给我们一个可以在线访问的 dns 注意不是域名,而是 dns。
所以负载均衡器类型在我们本地的 minikube 环境中不起作用。
【讨论】:
【参考方案18】:检查 kube-controller 日志。我能够通过将 clusterID 标签设置到我部署集群的 ec2 实例来解决这个问题。
【讨论】:
【参考方案19】:如果您不在受支持的云(aws、azure、gcloud 等)上,则不能在没有 MetalLB 的情况下使用 LoadBalancer https://metallb.universe.tf/ 但它还处于测试阶段..
【讨论】:
请提供代码示例来解释您的答案。【参考方案20】:可能是您正在部署服务的子网,没有足够的 ip
【讨论】:
【参考方案21】:对于您的用例,最好的选择是使用 NordPort 服务而不是负载平衡器类型,因为负载平衡器不可用。
【讨论】:
【参考方案22】:我在 Docker 桌面上收到此错误。我只是退出并再次打开它(Docker-desktop)。花了几秒钟,然后它工作正常。
【讨论】:
【参考方案23】:将运行在一组 Pod 上的应用程序公开为网络服务的一般方法在 Kubernetes 中称为服务。 Kubernetes 中有四种类型的服务。
集群IP 该服务只能从集群内访问。
节点端口
您将能够使用NodeIP
:NodePort
从集群外部与服务通信。默认节点端口范围是30000-32767
,并且可以通过在集群创建时定义--service-node-port-range
来更改此范围。
负载均衡器 使用云提供商的负载均衡器向外部公开服务。
外部名称 通过返回带有其值的 CNAME 记录,将服务映射到 externalName 字段的内容(例如 foo.bar.example.com)。没有设置任何类型的代理。
只有 LoadBalancer 为 External-IP 列提供值。只有当 Kubernetes 集群能够为该特定服务分配 IP 地址时,它才有效。您可以使用 metalLB 负载均衡器为您的负载均衡器服务提供 IP。
我希望你的疑虑会消失。
【讨论】:
【参考方案24】:如果您使用的是裸机,则需要 NodePort 类型 https://kubernetes.github.io/ingress-nginx/deploy/baremetal/
LoadBalancer 默认在 Digital Ocean、Aws 等其他云提供商中工作
k edit service ingress-nginx-controller
type: NodePort
spec:
externalIPs:
- xxx.xxx.xxx.xx
使用公共 IP
【讨论】:
【参考方案25】:删除现有服务并创建相同的新服务解决了我的问题。我的问题是使用了我定义的负载平衡 IP,因此外部端点处于挂起状态。当我更改了一个新的负载平衡 IP 时,它仍然无法工作。
最后,删除现有服务并创建一个新服务解决了我的问题。
【讨论】:
进行性维护并不能帮助 OP 了解发生的实际问题。【参考方案26】:如果您尝试在本地云中执行此操作,则需要 L4LB 服务来创建 LB 实例。
否则,您最终会收到您描述的无休止的“待处理”消息。在此处的视频中可见:https://www.youtube.com/watch?v=p6FYtNpsT1M
您可以使用开源工具来解决这个问题,该视频提供了一些关于自动化过程应该如何工作的指导。
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review以上是关于Kubernetes 服务外部 ip 待定的主要内容,如果未能解决你的问题,请参考以下文章
Kubernetes v1.14.0 之 kube-apiserver集群部署