我正在尝试在 Kubernetes (Minikube) 中创建一个应用程序,并将其服务公开给同一集群中的其他应用程序,但如果我尝试在 Kubernetes 节点中访问此服务,我的连接被拒绝。
此应用程序仅侦听 HTTP 127.0.0.1:9897
地址并发送响应。
以下是我的 yaml 文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: exporter-test
namespace: datenlord-monitoring
labels:
app: exporter-test
spec:
replicas: 1
selector:
matchLabels:
app: exporter-test
template:
metadata:
labels:
app: exporter-test
spec:
containers:
- name: prometheus
image: 34342/hello_world
ports:
- containerPort: 9897
---
apiVersion: v1
kind: Service
metadata:
name: exporter-test-service
namespace: datenlord-monitoring
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '9897'
spec:
selector:
app: exporter-test
type: NodePort
ports:
- port: 8080
targetPort: 9897
nodePort: 30001
在我应用这个 yaml 文件后,pod 和服务部署正确,我确信这个 pod 工作正常,因为当我登录 pod 时
kubectl exec -it exporter-test-* -- sh
,然后运行curl 127.0.0.1:9897
,我可以得到正确的响应。
另外,如果我运行 kubectl port-forward exporter-test-* -n datenlord-monitoring 8080:9897
,我可以从 localhost:8080
得到正确的响应。所以这个应用程序应该运行良好。
但是,当我尝试通过 exporter-test-service.datenlord-monitoring.svc:30001
从同一 K8s 集群中的其他应用程序访问此服务或仅在 k8s 节点中运行 curl nodeIp:30001
或在 k8s 节点中运行 curl clusterIp:8080
时,我得到了 { {1}}
有人遇到过同样的问题吗?感谢您的帮助!谢谢!
答案 0 :(得分:0)
你在这里混合了两件事。 NodePort 是应用程序可从集群外部使用的端口。在集群内部,您需要通过服务端口而不是 NodePort 访问您的服务。
尝试将 exporter-test-service.datenlord-monitoring.svc:30001 更改为 exporter-test-service.datenlord-monitoring.svc:8080
答案 1 :(得分:0)
欢迎来到社区!
您观察到的行为没有问题。 简而言之,kubernetes 集群(在本例中为 minikube)有自己的隔离网络,内部 DNS。
在节点上访问您的服务的一种方式:您为您的服务指定了 nodePort
,这使得该服务可以在 localhost:30001
上访问。您可以通过在您的主机上运行来检查它:
$ kubectl get svc -n datenlord-monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
exporter-test-service NodePort 10.111.191.159 <none> 8080:30001/TCP 2m45s
# Test:
curl -I localhost:30001
HTTP/1.1 200 OK
另一种向主机网络公开服务的方法是使用 minikube tunnel
(在另一个控制台中运行)。您需要将服务类型从 NodePort
更改为 LoadBalancer
:
$ kubectl get svc -n datenlord-monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
exporter-test-service LoadBalancer 10.111.191.159 10.111.191.159 8080:30001/TCP 18m
# Test:
$ curl -I 10.111.191.159:8080
HTTP/1.1 200 OK
为什么有些选项不起作用。
通过服务的 DNS
+ NodePort
连接到服务。 NodePort 用于将主机 IP 和 NodePort
链接到 kubernetes 集群内的服务端口。在 kubernetes 集群之外无法访问内部 DNS(除非您不在主机上向 /etc/hosts
添加 IP)
在集群内部,您应该使用内部 DNS 和内部服务端口,在您的情况下为 8080
。您可以使用同一命名空间中的单独容器(例如图像 curlimages/curl
)检查它是如何工作的,并获得以下信息:
$ kubectl exec -it curl -n datenlord-monitoring -- curl -I exporter-test-service:8080
HTTP/1.1 200 OK
或者来自不同命名空间中的 pod:
$ kubectl exec -it curl-default-ns -- curl -I exporter-test-service.datenlord-monitoring.svc:8080
HTTP/1.1 200 OK
我附上了有用的链接,可以帮助您了解这种差异。
编辑:部署的 pod 内的 DNS
$ kubectl exec -it exporter-test-xxxxxxxx-yyyyy -n datenlord-monitoring -- bash
root@exporter-test-74cf9f94ff-fmcqp:/# cat /etc/resolv.conf
nameserver 10.96.0.10
search datenlord-monitoring.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
有用的链接: