【问题标题】:Not able to access statefulset pod via headless service using fqdn无法使用 fqdn 通过无头服务访问 statefulset pod
【发布时间】:2021-10-06 21:12:23
【问题描述】:

我有一个看起来像这样的 k8 设置

ingress -> headless service (k8 service with clusterIp: none) -> statefulsets ( 2pods)

Fqdn 看起来像这样:

nslookup my-service
Server:         100.4.0.10
Address:        100.4.0.10#53

Name:   my-service.my-namespace.svc.cluster.local
Address: 100.2.2.8
Name:   my-service.my-namespace.svc.cluster.local
Address: 100.1.4.2

我正在尝试使用以下 fqdn 直接通过服务访问其中一个 pod,但无法这样做。

curl -I my-pod-0.my-service.my-namespace.svc.cluster.local:8222
curl: (6) Could not resolve host: my-pod-0.my-service.my-namespace.svc.cluster.local

如果我尝试直接访问该服务,那么它可以正常工作(作为负载均衡器)

curl -I my-service.my-namespace.svc.cluster.local:8222
HTTP/1.1 200 OK
Date: Sat, 31 Jul 2021 21:24:42 GMT
Content-Length: 656

如果我尝试使用它的集群 ip 直接访问 pod,它也可以正常工作

curl -I 100.2.2.8:8222
HTTP/1.1 200 OK
Date: Sat, 31 Jul 2021 21:29:22 GMT
Content-Length: 656
Content-Type: text/html; charset=utf-8

但我的用例要求我能够使用 fqdn 访问 statefulset pod,即 my-pod-0.my-service.my-namespace.svc.cluster.local 。我在这里错过了什么?

【问题讨论】:

    标签: kubernetes dns kubernetes-ingress kubernetes-pod


    【解决方案1】:

    示例 statefulset 名为 foo,图像为 nginx

    k get statefulsets.apps
    NAME   READY   AGE
    foo    3/3     8m55s
    

    这个有状态集创建了以下 pod(foo-0,foo-1,foo-2):

    k get pod -o wide
    NAME      READY   STATUS    RESTARTS   AGE     IP             NODE        NOMINATED NODE   READINESS GATES
    busybox   1/1     Running   1          3h47m   10.1.198.71    ps-master   <none>           <none>
    foo-0     1/1     Running   0          12m     10.1.198.121   ps-master   <none>           <none>
    foo-1     1/1     Running   0          12m     10.1.198.77    ps-master   <none>           <none>
    foo-2     1/1     Running   0          12m     10.1.198.111   ps-master   <none>           <none>
    

    现在创建一个无头服务(clusterIP is none),如下所示:(确保使用与您的 statefulset 相同的正确选择器)

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: foo
    spec:
      type: ClusterIP
      clusterIP: None
      ports:
      - port: 80
        name: web
      selector:
        app: foo
    

    现在,执行nslookup 以查看适用于服务的dns 分辨率。(可选步骤)

    k exec -it busybox -- nslookup nginx.default.svc.cluster.local
    Server:    10.152.183.10
    Address 1: 10.152.183.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      nginx.default.svc.cluster.local
    Address 1: 10.1.198.77 foo-1.nginx.default.svc.cluster.local
    Address 2: 10.1.198.111 foo-2.nginx.default.svc.cluster.local
    Address 3: 10.1.198.121 foo-0.nginx.default.svc.cluster.local
    

    现在验证每个 pod 的单独分辨率是否正常工作:

    k exec -it busybox -- nslookup foo-1.nginx.default.svc.cluster.local
    Server:    10.152.183.10
    Address 1: 10.152.183.10 kube-dns.kube-system.svc.cluster.local
    
    Name:      foo-1.nginx.default.svc.cluster.local
    Address 1: 10.1.198.77 foo-1.nginx.default.svc.cluster.local
    

    更多信息:Here

    注意:在这种情况下,OP 对headless 服务和statefulset 的映射不正确,可以使用以下命令进行验证:

    k get statefulsets.apps foo -o jsonpath="{.spec.serviceName}{'\n'}"
    nignx
    

    确保映射。

    【讨论】:

    • 但不幸的是,这破坏了我的整个用例,我只知道 pod 名称(my-pod-0,my-pod-1),我无法知道荚。另外,如果我知道 pod 的 ip,我可以使用 ip 访问它,而无需使用 fqdn。互联网上有很多文章声称我应该能够访问,使用它的名称的 pod,包括官方文档kubernetes.io/docs/concepts/workloads/controllers/statefulset/… web-{0..N-1}.nginx.default.svc.cluster.local
    • 我发现了问题.. 看起来我的 statefulset 中的 serviceName 属性是错误的。一旦我更正了它,我就可以使用 pod 名称来解决它。我会接受您的回答,但您能否在回答中突出显示此信息,以确保将来有人不会再犯同样的错误。
    • 我不知道出了什么问题以及为您解决了什么问题,我只是按照文档中的说明进行了操作,对我来说效果很好。整个实验作为 POC 粘贴在答案中。
    • 正如我提到的 statefulset yaml 有一个名为 serviceName 的属性,在我的情况下这个值是错误的。一旦我修复了值(到 my-service),dns 开始解析 my-pod-0.my-service.my-namespace.defualt.svc.local 的 fqdn
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    相关资源
    最近更新 更多