K8s中 loadBalancer类型的service在没有外部ip的情况下如何 访问?

在 play-with-k8s https://labs.play-with-k8s.com/ 搭建了一个k8s集群,部署了一个service

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

image.png


  1. get service的情况
    image.png
  2. get pods的情况
    image.png

每一个pod中都有一个nginx容器,我手动进入到了每一个nginx容器中 修改index.htmll 为1111,22,333.

问题: service 是loadbalancer类型,且没有外部ip 我该如何 通过service 访问 到后端三个nginx容器, 从而看到负载均衡的情况。

尝试的方案:

1.因为没有外部ip,所以无法通过外部ip访问service,只能通过内部ip

所以我进入到了 其中的一个 nginx容器,然后执行 curl http://service-clusterip:80 端口访问,但是nginx容器中 没有curl命令, 也没有 ping 等等命令。

然后我使用你 apt install curl 安装curl,提示 无法解析域名 http://deb.debian.org/debian

然后我又修改 nginx容器的 /etc/apt/sources.list 改为 阿里源,清华源都不行,都是无法解析域名。 感觉好像是 容器被限制了无法访问到外部互联网。 但是在node节点上是可以访问百度、阿里等外部网络的。

image.png

image.png

阅读 1.4k
avatarAI BotBETA

在 Kubernetes 集群中,如果你有一个 LoadBalancer 类型的 Service,但是没有外部 IP 地址,那么你不能直接从外部网络访问这个 Service。不过,你仍然可以在集群内部访问它。

在你的情况下,由于你无法从 Nginx 容器的内部直接访问外部网络(可能是因为网络策略或其他安全限制),你可以尝试以下步骤来在集群内部访问 LoadBalancer 类型的 Service:

  1. 使用 Kubernetes 集群的内部 DNS:Kubernetes 会为 Service 创建一个 DNS 记录,你可以使用 Service 的名称来访问它。在你的情况下,你可以尝试从另一个 Pod 内部使用 curl 命令来访问 my-nginx-svc:80
  2. 创建一个新的 Pod 来测试访问:如果你无法修改现有的 Pod,你可以创建一个新的 Pod,并在其中安装 curl。然后,你可以从这个新 Pod 中访问 my-nginx-svc:80 来观察负载均衡的行为。

例如,你可以创建一个带有 curl 的简单 Pod,如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: curl-test
spec:
  containers:
  - name: curl
    image: radial/busyboxplus:curl
    command: ["sh"]
    args: ["-c", "while true; do curl -s my-nginx-svc:80; sleep 1; done"]

这个 Pod 会持续地向 my-nginx-svc 发送 HTTP 请求,并打印响应。由于 LoadBalancer 类型的 Service 在集群内部表现为一个 ClusterIP,因此这个 Pod 应该能够访问它,即使 Service 没有外部 IP 地址。

  1. 检查网络策略和安全组设置:如果上述步骤不起作用,可能是因为你的集群启用了网络策略或安全组,限制了 Pod 之间的通信。你需要检查这些设置,确保它们允许你的 Pod 访问 Service。

请注意,LoadBalancer 类型的 Service 在没有云提供商支持的环境中(例如,在 minikube 或 kind 等本地环境中)可能不会分配外部 IP 地址。在这种情况下,你需要依赖 ClusterIP 或其他类型的 Service(如 NodePort)来从外部访问你的应用。

3 个回答

1、要想访问nginx服务,可以新建一个类型为nodePort的service服务,或者将原来的loadblance类型的服务改为nodePort类型,这样就可以通过节点的ip和端口访问到nginx,或者可以搭建MetalLB负载均衡器,也可以自动分配loadblance ip;

2、容器无法解析外部域名,可以查看coredns的配置,看看上游域名解析配的是什么,如下是我的codedns配置,圈红部分表示上游dns服务器继承节点的dns配置,所以我的pod可以通过节点配置的dns解析到外网的域名上,这里面还有个前提就是pod能够访问外网。
image.png

如果你指明了必须要用loadbalancer类型的service,也是有解决方案的。
k8s默认是没有给 裸机 环境使用的负载均衡器的,默认能用的大概只有 nodeport 类型的service能实现从外部访问服务(nodeport也是可以支持负载均衡的)。

你可以试试 MetalLB 这个负载均衡器实现,部署了之后,能给locadbalance类型的service分配一个和node同内网IP,可以在局域网中访问。(这也是我自己在用的一个方案,还是挺好用的)


突然发现你用的好像是在云上的模拟环境,如果在模拟的环境中,那么大概率是服务商限制了外网访问,访问不通镜像站是正常的。

另外容器pod内DNS异常,这个大概率也和service的IP没关系。

新手上路,请多包涵

LoadBalancer模式的本质其实是带负载均衡的NodePort模式,它会将接收的流量分发到所以节点的对应NodePort端口。没有LoadBalancer IP的话,此时的LoadBalancer相当于是不生效的,它就等同于NodePort模式,直接接访问 <任意节点IP>:<NodePort端口> 就能访问到服务。
如果要使LoadBalancer生效就需要安装LoadBalancer组件,比如MetalLB。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题