kubernetes DNS - 让服务通过 DNS 自行联系

标签 kubernetes dns kube-proxy

可以通过向其所属服务的 DNS 发送网络请求来访问 kubernetes 集群中的 Pod。网络请求必须发送到[service].[namespace].svc.cluster.local并在该服务的所有成员之间实现负载平衡。

这可以很好地让某个 Pod 到达另一个 Pod,但如果某个 Pod 尝试通过他所属的服务到达自身,则会失败。它总是会导致超时。

这是 Kubernetes 中的错误(在我的例子中是 minikube v0.35.0)还是需要一些额外的配置?


这是一些调试信息:

让我们从其他 Pod 联系该服务。这工作正常:

daemon@auth-796d88df99-twj2t:/opt/docker$ curl -v -X POST -H "Accept: application/json" --data '{}' http://message-service.message.svc.cluster.local:9000/message/get-messages
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.107.209.9...
* TCP_NODELAY set
* Connected to message-service.message.svc.cluster.local (10.107.209.9) port 9000 (#0)
> POST /message/get-messages HTTP/1.1
> Host: message-service.message.svc.cluster.local:9000
> User-Agent: curl/7.52.1
> Accept: application/json
> Content-Length: 2
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 2 out of 2 bytes
< HTTP/1.1 401 Unauthorized
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< X-Frame-Options: DENY
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Content-Security-Policy: default-src 'self'
< X-Permitted-Cross-Domain-Policies: master-only
< Date: Wed, 20 Mar 2019 04:36:51 GMT
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 12
< 
* Curl_http_done: called premature == 0
* Connection #0 to host message-service.message.svc.cluster.local left intact
Unauthorized

现在我们尝试让 Pod 联系他所属的服务:

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.107.209.9...
* TCP_NODELAY set
* connect to 10.107.209.9 port 9000 failed: Connection timed out
* Failed to connect to message-service.message.svc.cluster.local port 9000: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to message-service.message.svc.cluster.local port 9000: Connection timed out

如果我正确读取了curl调试日志,则dns解析为IP地址10.107.209.9。可以通过该 IP 从任何其他 pod 访问该 pod,但该 pod 无法使用它来访问自身。

以下是尝试访问自身的 pod 的网络接口(interface):

daemon@message-58466bbc45-lch9j:/opt/docker$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
296: eth0@if297: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:09 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.9/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

这是部署到 minikube 的 kubernetes 文件:

apiVersion: v1
kind: Namespace
metadata:
  name: message

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: message
  name: message
  namespace: message
spec:
  replicas: 1
  selector:
    matchLabels:
      app: message
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: message
    spec:
      containers:
        - name: message
          image: message-impl:0.1.0-SNAPSHOT
          imagePullPolicy: Never
          ports:
            - name: http
              containerPort: 9000
              protocol: TCP
          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace    
            - name: KAFKA_KUBERNETES_NAMESPACE
              value: kafka
            - name: KAFKA_KUBERNETES_SERVICE
              value: kafka-svc
            - name: CASSANDRA_KUBERNETES_NAMESPACE
              value: cassandra
            - name: CASSANDRA_KUBERNETES_SERVICE
              value: cassandra
            - name: CASSANDRA_KEYSPACE
              value: service_message
---

# Service for discovery
apiVersion: v1
kind: Service
metadata:
  name: message-service
  namespace: message
spec:
  ports:
    - port: 9000
      protocol: TCP
  selector:
    app: message
---

# Expose this service to the api gateway
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: message
  namespace: message
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: api.fload.cf
      http:
        paths:
          - path: /message
            backend:
              serviceName: message-service
              servicePort: 9000

最佳答案

这是已知的minikube issue 。讨论包含以下解决方法:

1)尝试:

minikube ssh
sudo ip link set docker0 promisc on 

2) 使用headless service :集群IP:无

关于kubernetes DNS - 让服务通过 DNS 自行联系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55326310/

相关文章:

kubernetes - 在Kubernetes节点上重启后删除iptables规则

tomcat - kubernetes redinessProbe httpGet on tomcat 图像报告连接被拒绝

kubernetes - 为什么从主机而不是gcloud交互式shell使用gcloud命令如此困难?

asp.net - 如何将一个域映射到另一个域的子文件夹?

url - 如何获取域的 URL 列表

amazon-ec2 - Kubernetes - 连接跟踪不会将包破坏回原始目标 IP (DNAT)

kubernetes - 在Google Kubernetes引擎上进行垂直自动缩放?

Kubernetes:通过 Ingress 将非 HTTP 请求路由到容器

Azure 私有(private) DNS 配置不适用于 P2S VPN

kubernetes - 在POD中使用服务的ClusterIP地址