在本地Minikube集群和AWS中拆分Horizo​​n DNS [英] Split Horizon DNS in local Minikube cluster and AWS

查看:58
本文介绍了在本地Minikube集群和AWS中拆分Horizo​​n DNS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最初,我已经在AWS ECS中部署了前端Web应用程序和所有后端APIS,每个后端API都有一个Route53记录,并且前端已连接到.env文件中的这些API.现在,我想从ECS迁移到EKS,并且尝试将所有这些应用程序部署在Minikube本地群集中.我想保持前端应用程序中的.env不变(对所有环境变量使用相同的URL),如果后端API没有,则应用程序应首先通过服务发现在本地集群中查找后端API.存在于群集中,它应该连接到外部服务,即ECS中部署的API.简而言之,首先是本地(Minikube cluster),然后是外部(AWS).如何在Kubernetes中实现?

Initially, I've deployed my frontend web application and all the backend APIS in AWS ECS, each of the backend APIs has a Route53 record, and the frontend is connected to these APIs in the .env file. Now, I would like to migrate from ECS to EKS and I am trying to deploy all these application in a Minikube local cluster. I would like to keep my .env in my frontend application unchanged(using the same URLs for all the environment variables), the application should first look for the backend API inside the local cluster through service discovery, if the backend API doesn't exist in the cluster, it should connect to the the external service, which is the API deployed in the ECS. In short, first local(Minikube cluster)then external(AWS). How to implement this in Kubernetes?

http://backendapi.learning.com->部署在pod中的后端API->如果未显示-> ECS中部署的后端API

http:// backendapi.learning.com --> backend API deployed in the pod --> if not presented --> backend API deployed in the ECS

.env

BACKEND_API_URL = http://backendapi.learning.com

代码中的一个示例,其中前端正在调用后端API

one of the example in the code in which the frontend is calling the backend API

export const ping = async _ => {
    const res = await fetch(`${process.env.BACKEND_API_URL}/ping`);
    const json = await res.json();
    return json;
}

推荐答案

假设您的设置是:

  • 基于微服务架构.
  • 在Kubernetes集群(frontendbackend)中部署的应用程序是Dockerized
  • 应用程序能够在Kubernetes上运行.
  • Basing on microservices architecture.
  • Applications deployed in Kubernetes cluster (frontend and backend) are Dockerized
  • Applications are capable to be running on top of Kubernetes.
  • etc.

您可以使用Services配置Kubernetes集群(minikube实例)以将您的请求中继到其他位置.

You can configure your Kubernetes cluster (minikube instance) to relay your request to different locations by using Services.

在Kubernetes中,术语服务"指是一种将运行在一组Pod上的应用程序公开为网络服务的抽象方法.

In Kubernetes terminology "Service" is an abstract way to expose an application running on a set of Pods as a network service.

某些Services类型如下:

  • ClusterIP:在群集内部IP上公开服务.选择此值将使该服务仅可从群集内访问.这是默认的ServiceType.
  • NodePort:在静态端口(NodePort)上在每个节点的IP上公开服务.将自动创建NodePort服务所路由到的ClusterIP服务.您可以通过请求<NodeIP>:<NodePort>从集群外部联系NodePort服务.
  • LoadBalancer:使用云提供商的负载平衡器在外部公开服务.会自动创建外部负载均衡器路由到的NodePortClusterIP服务.
  • ExternalName:通过返回带有值的CNAME记录,将服务映射到externalName字段的内容(例如foo.bar.example.com).没有设置任何代理.
  • ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.
  • NodePort: Exposes the Service on each Node's IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You'll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
  • LoadBalancer: Exposes the Service externally using a cloud provider's load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.
  • ExternalName: Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record with its value. No proxying of any kind is set up.

https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

您可以使用Headless Service with selectorsdnsConfig(在Deployment清单中)实现问题中引用的设置.

You can use Headless Service with selectors and dnsConfig (in Deployment manifest) to achieve the setup referenced in your question.

让我解释更多:

让我们假设您有一个backend:

  • nginx-one-位于内部外部
  • nginx-one - located inside and outside

您的frontend清单的最基本形式应如下所示:

Your frontend manifest in most basic form should look following:

  • deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  selector:
    matchLabels:
      app: frontend
  replicas: 1
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: ubuntu
        image: ubuntu
        command: 
        - sleep
        - "infinity" 
      dnsConfig: # <--- IMPORTANT 
        searches: 
        - DOMAIN.NAME 

具体看一下:

      dnsConfig: # <--- IMPORTANT 
        searches: 
        - DOMAIN.NAME 

剖析以上部分:

dnsConfig-dnsConfig字段是可选的,它可以与任何dnsPolicy设置一起使用.但是,当Pod的dnsPolicy设置为"None"时,必须指定dnsConfig字段.

dnsConfig - the dnsConfig field is optional and it can work with any dnsPolicy settings. However, when a Pod's dnsPolicy is set to "None", the dnsConfig field has to be specified.

  • searches:用于在Pod中查找主机名的DNS搜索域的列表.此属性是可选的.指定后,提供的列表将合并到根据所选DNS策略生成的基本搜索域名中.重复的域名将被删除. Kubernetes最多允许6个搜索域.

    searches: a list of DNS search domains for hostname lookup in the Pod. This property is optional. When specified, the provided list will be merged into the base search domain names generated from the chosen DNS policy. Duplicate domain names are removed. Kubernetes allows for at most 6 search domains.

  • 关于backendsServices.

    • service.yaml:
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-one
    spec:
      clusterIP: None # <-- IMPORTANT
      selector:
        app: nginx-one
      ports:
        - name: http
          protocol: TCP
          port: 80
          targetPort: 80
    

    Service之上会告诉您的前端,您的backends(nginx)可以通过Headless service获得(为什么Headless会在以后出现!).默认情况下,您可以通过以下方式与之通信:

    Above Service will tell your frontend that one of your backends (nginx) is available through a Headless service (why it's Headless will come in hand later!). By default you could communicate with it by:

    • service-name(nginx-one)
    • service-name.namespace.svc.cluster.local(nginx-one.default.svc.cluster.local)-仅在本地
    • service-name (nginx-one)
    • service-name.namespace.svc.cluster.local (nginx-one.default.svc.cluster.local) - only locally

    假设您正在使用curl(为简单起见)将请求从frontend发送到backend,则对于DNS分辨率,您将具有特定的顺序:

    Assuming that you are sending the request using curl (for simplicity) from frontend to backend you will have a specific order when it comes to the DNS resolution:

    • 检查集群内的DNS记录
    • 检查在dnsConfig
    • 中指定的DNS记录
    • check the DNS record inside the cluster
    • check the DNS record specified in dnsConfig

    连接到backend的详细信息如下:

    The specifics of connecting to your backend will be following:

    • 如果群集中有带有backendPod,则DNS分辨率将指向Pod的IP(不是ClusterIP)
    • 如果由于各种原因集群中的Pod backend不可用,DNS分辨率将首先检查内部记录,然后选择在dnsConfig中使用DOMAIN.NAME(在minikube).
    • 如果没有与特定backend(nginx-one)关联的Service,则DNS分辨率将使用dnsConfig中的DOMAIN.NAME来在群集外部进行搜索.
    • If the Pod with your backend is available in the cluster, the DNS resolution will point to the Pod's IP (not ClusterIP)
    • If the Pod backend is not available in the cluster due to various reasons, the DNS resolution will first check the internal records and then opt to use DOMAIN.NAME in the dnsConfig (outside of minikube).
    • If there is no Service associated with specific backend (nginx-one), the DNS resolution will use the DOMAIN.NAME in the dnsConfig searching for it outside of the cluster.

    旁注!

    Headless Service with selector之所以在这里起作用,是因为它的目的是直接指向Pod的IP,而不是ClusterIP(只要Service存在,它就一直存在).如果您使用的是正常" Service,即使没有与选择器匹配的Pods,您也将始终尝试与ClusterIP进行通信.通过使用headless,如果没有Pod,则DNS分辨率将在线下更远(外部来源).

    The Headless Service with selector comes into play here as its intention is to point directly to the Pod's IP and not the ClusterIP (which exists as long as Service exists). If you used a "normal" Service you would always try to communicate with the ClusterIP even if there is no Pods available matching the selector. By using a headless one, if there is no Pod, the DNS resolution would look further down the line (external sources).


    其他资源:


    Additional resources:

    您还可以查看其他选项:

    You could also take a look on alternative options:

    替代选项1:

    • 使用CoreDNS中的重写规则插件将backendapi.learning.com的DNS查询重写为backendapi.default.svc.cluster.local
    • Use rewrite rule plugin in CoreDNS to rewrite DNS queries for backendapi.learning.com to backendapi.default.svc.cluster.local

    替代选项2:

    • 添加
    • Add hostAliases to the Frontend Pod

    您还可以使用 Configmaps 重用.env文件.

    You can also use Configmaps to re-use .env files.

    这篇关于在本地Minikube集群和AWS中拆分Horizo​​n DNS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆