当没有外部 IP 但有 istio-ingressgateway 时,如何为 KNative 配置 DNS?

问题描述

knative docs 描述如下:

要为 Knative 配置 DNS,请从设置网络中获取外部 IP 或 CNAME,并使用您的 DNS 提供商进行如下配置

  • 如果网络层产生了外部 IP 地址,则为域配置通配符 A 记录:

    # Here knative.example.com is the domain suffix for your cluster

    *.knative.example.com == A 35.233.41.212

  • 如果网络层产生了 CNAME,则为域配置 CNAME 记录:

    # Here knative.example.com is the domain suffix for your cluster

    *.knative.example.com == CNAME a317a278525d111e89f272a164fd35fb-1510370581.eu-central-1.elb.amazonaws.com

但是,我的环境没有外部负载均衡器,因此没有 EXTERNAL-IP:

$ kubectl --namespace istio-system get service istio-ingressgateway
NAME                   TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                      AGE
istio-ingressgateway   NodePort   10.110.132.172   <none>        15021:31278/TCP,80:32725/TCP,443:30557/TCP,15443:32309/TCP   8h

我确实配置了 istio-ingresgateway:

$ kubectl get po -l istio=ingressgateway -n istio-system \
     -o jsonpath='{.items[*].status.hostIP}'
10.1.0.193 10.1.0.132 10.1.0.174

我可以简单地设置 DNS 吗?

*.knative.example.com     [some TTL]   IN   A    10.1.0.193
*.knative.example.com     [some TTL]   IN   A    10.1.0.132
*.knative.example.com     [some TTL]   IN   A    10.1.0.174

解决方法

到目前为止,按如下方式设置 DNS 对我来说还可以:

if(isset($_POST['adddoc']))
{
$docTitle=$_POST['doc_title'];

$file=$_FILES['doc'];

$doc_name=$_FILES['doc']['name'];
$doc_tmpName=$_FILES['doc']['tmp_name'];
$doc_size=$_FILES['doc']['size'];
$doc_error=$_FILES['doc']['error'];
$doc_type=$_FILES['doc']['type'];

$docExt=explode('.',$doc_name);
$docActualExt= strtolower(end($docExt));
$doc_allow=array('pdf','xlsx');

    if($doc_error === 0)
    {
        if($doc_size < 10000000)
        {

            $docDestination='upload/'.$doc_name;
            move_uploaded_file($doc_tmpName,$docDestination);

            $query="INSERT INTO documents (doc_title,doc) VALUES (?,?)";
            $stmt=mysqli_stmt_init($conn);
            if(mysqli_stmt_prepare($stmt,$query)){
                mysqli_stmt_bind_param($stmt,"ss",$docTitle,$doc_name);
                mysqli_stmt_execute($stmt);
               
                $_SESSION['success']="Doc added";
            header('Location: doc.php');

            }
            else{
                $_SESSION['status']="Not added";
                header('Location: adddoc.php');

            }

        }
        else
        {
            $_SESSION['status']="The file is too big!";
            header('Location: adddoc.php');
          
        }
    }
    else
    {
        $_SESSION['status']="Error uploading file";
            header('Location: adddoc.php');
    }
}
,

您似乎在这里使用了 hostPort 网络;如果是这种情况,那么 Kubernetes 会将主机 IP 地址的端口 80 和 443 映射到 Istio 的 Envoy pod。只要您的 istio-ingressgateway pod 保持在同一台机器上的调度,本周就可以工作(例如,如果您使用守护进程集并且集群中有 3 个节点,请将所有三个节点 IP 都放在 DNS 中)。这里有几个地方可以解决这个问题,Kubernetes LoadBalancer 服务会更好地工作:

  • 如果其中一台主机出现故障,1/N 个客户端将尝试使用错误的 IP 地址,并且可能会出错或超时,然后重试。您需要将主机从 DNS 中移除才能完成这项工作。
  • 如果您的主机数量多于 istio-ingressgateway Pod,则每次重新安排这些 Pod 之一(部署更新、主机内核升级等)时,您都会遇到上述中断。如果主机少于 5-7 台,则使用 DaemonSet 可以避免这种情况,但较大的记录集可能会导致其他问题。
  • 您不能使用 Horizo​​ntalPodAutoscaler (HPA) 来调整 istio-ingressgateway pod 的数量(有关不匹配后果,请参见上文)

如果可能,您可以将 MetalLB 视为上述任何您关注的成本软件负载平衡器。如果以上都不是主要问题,那么 nodePort 服务比 LoadBalancer 服务简单一些。