【问题标题】:DNS doesn't remove not ready pod in AKS with Azure CNI enabled在启用 Azure CNI 的情况下,DNS 不会删除 AKS 中未就绪的 pod
【发布时间】:2021-11-06 23:31:24
【问题描述】:

AKS 如何使未准备好的 pod 无法接受请求?仅当您在该部署之前有正确的服务时才有效?

我想首先解释一下我在未配置 azure cni 的 aks 中发现的情况,然后继续解释我在启用 azure cni 的 aks 中看到的情况。

在没有启用 cni 的 AKS 中,如果我在像 curl -I some-pod.some-service.some-namespace.svc.cluster.local:8080 这样的服务后面的未准备好的 pod 上的 url 上执行 curl,我在响应中得到的是无法解析的主机名或类似的东西。这意味着据我了解 DNS 没有此条目。这就是在正常情况下,aks 处理未准备好的 pod 以不接收请求的方式。

在启用了 azure cni 的 AKS 中,如果我在未就绪的 pod 上执行相同的请求,它能够解析主机名并能够将请求发送到 pod。但是,有一个警告是,当我尝试通过该服务的外部私有 ip 执行请求时,该请求不会到达未准备好的 pod,这是预期的并且似乎工作正常。但是,当我再次尝试执行上面提到的curl -I some-pod.some-service.some-namespace.svc.cluster.local:8080 的请求时,它可以工作,但它不应该。为什么 azure cni 的 DNS 有这个值?

我可以做些什么来将 azure cni 配置为更像 AKS 的默认行为,其中这样的 curl 请求要么无法解析该主机名,要么会拒绝连接或其他什么?

【问题讨论】:

  • 通常一个 pod 具有以下 DNS 解析:pod-ip-address.my-namespace.pod.cluster-domain.example。例如,default 命名空间中的 Pod 的 IP 地址为 172.17.0.3,并且您的集群的域名为 cluster.local,则该 Pod 的 DNS 名称为:172-17-0-3.default.pod.cluster.local。由 Service 公开的 DeploymentDaemonSet 创建的任何 pod 都具有以下可用的 DNS 解析:pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example。您能否相应地编辑您尝试访问的 FQDN?

标签: azure kubernetes azure-aks cni


【解决方案1】:

假设 not ready pod 引用 Readiness Probe 失败的 pod。 kubelet 使用就绪探针来了解容器何时准备好开始接受流量。当 Pod 的所有容器都准备好时,就认为 Pod 准备好了。此信号的一种用途是控制哪些 Pod 用作服务的后端。当 Pod 未准备好时,它会从服务负载均衡器中移除。 [Reference]

但是,确定 pod 就绪的逻辑可能与 pod 是否可以服务请求有关,也可能没有任何关系,并且完全取决于用户。

例如,具有以下清单的 Pod:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: readiness
  name: readiness-pod
spec:
  containers:
  - name: readiness-container
    image: nginx
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

无论 nginx 是否为应用程序服务,都根据文件 /tmp/healthy 的存在来决定准备情况。因此,运行应用程序并在 k run - 上使用服务readiness-svc 公开它:

kubectl exec readiness-pod -- /bin/bash -c 'if [ -f /tmp/healthy ]; then echo "/tmp/healthy file is present";else echo "/tmp/healthy file is absent";fi'
/tmp/healthy file is absent

kubectl get pods -o wide
NAME            READY   STATUS    RESTARTS   AGE    IP            NODE                                NOMINATED NODE   READINESS GATES
readiness-pod   0/1     Running   0          11m    10.240.0.28   aks-nodepool1-29819654-vmss000000   <none>           <none>
source-pod      1/1     Running   0          6h8m   10.240.0.27   aks-nodepool1-29819654-vmss000000   <none>           <none>

kubectl describe svc readiness-svc
Name:              readiness-svc
Namespace:         default
Labels:            test=readiness
Annotations:       <none>
Selector:          test=readiness
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.0.23.194
IPs:               10.0.23.194
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:
Session Affinity:  None
Events:            <none>

kubectl exec -it source-pod -- bash
root@source-pod:/# curl -I readiness-svc.default.svc.cluster.local:80
curl: (7) Failed to connect to readiness-svc.default.svc.cluster.local port 80: Connection refused
root@source-pod:/# curl -I 10-240-0-28.default.pod.cluster.local:80
HTTP/1.1 200 OK
Server: nginx/1.21.3
Date: Mon, 13 Sep 2021 14:50:17 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT
Connection: keep-alive
ETag: "6137835f-267"
Accept-Ranges: bytes

因此,我们可以看到,当我们尝试从source-pod 连接到端口 80 上的服务readiness-svc.default.svc.cluster.local 时,连接被拒绝。这是因为 kubelet 没有在 readiness-pod 容器中找到 /tmp/healthy 文件来执行 cat 操作,因此标记 Pod readiness-pod 未准备好服务流量并将其从后端删除服务 readiness-svc。但是,pod 上的 nginx 服务器仍然可以为 Web 应用程序提供服务,如果您直接连接到 pod,它将继续这样做。

容器的就绪探测失败不要删除DNS records of PodsPod 的 DNS 记录与 Pod 本身共享其生命周期。

这种行为是 Kubernetes 的特征,不会随网络插件而改变。我们已尝试重现此问题,并观察到使用 kubenetAzure CNI 网络插件的 AKS 群集的相同行为.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-14
    • 2021-08-15
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2019-07-17
    相关资源
    最近更新 更多