如何解决在本地 Minikube 集群和 AWS 中拆分地平线 DNS 服务示例连接到您的后端编辑:
最初,我已经在 AWS ECS
中部署了我的前端 Web 应用程序和所有后端 API,每个后端 API 都有一个 Route53
记录,并且前端连接到 .env
中的这些 API {1}} 个文件。现在,我想从 ECS
迁移到 EKS
,并尝试将所有这些应用程序部署在 Minikube
本地集群中。我想在我的前端应用程序中保持我的 .env
不变(对所有环境变量使用相同的 URL),如果后端 API 没有,应用程序应该首先通过服务发现在本地集群中查找后端 API '不存在于集群中,它应该连接到外部服务,即部署在 ECS
中的 API。简而言之,首先是本地(Minikube cluster
)然后是外部(AWS
)。如何在 Kubernetes
中实现这一点?
http://backendapi.learning.com --> pod 中部署的后端 API --> 如果未提供 --> 部署在 ECS 中的后端 API
.env
BACKEND_API_URL = http://backendapi.learning.com
代码中前端调用后端API的示例之一
export const ping = async _ => {
const res = await fetch(`${process.env.BACKEND_API_URL}/ping`);
const json = await res.json();
return json;
}
解决方法
假设您的设置是:
- 基于微服务架构。
- 部署在 Kubernetes 集群(
frontend
和backend
)中的应用程序是Dockerized
- 应用能够在 Kubernetes 之上运行。
- 等
您可以配置您的 Kubernetes 集群(minikube
实例)以使用 Services
将您的请求中继到不同的位置。
服务
在 Kubernetes 术语中,“服务”是将在一组 Pod 上运行的应用程序公开为网络服务的抽象方式。
某些类型的 Services
如下:
-
ClusterIP
:在集群内部 IP 上公开服务。选择此值会使服务只能从集群内部访问。这是默认的ServiceType
。 -
NodePort
:在静态端口(NodePort
)的每个节点的 IP 上公开服务。自动创建ClusterIP
服务路由到的NodePort
服务。您将能够通过请求<NodeIP>
:<NodePort>
从集群外部联系 NodePort 服务。 -
LoadBalancer
:使用云提供商的负载均衡器在外部公开服务。NodePort
和ClusterIP
服务(外部负载平衡器路由到的服务)是自动创建的。 -
ExternalName
:通过返回带有其值的externalName
记录,将服务映射到foo.bar.example.com
字段的内容(例如CNAME
)。未设置任何类型的代理。
https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
您可以使用 Headless Service with selectors
和 dnsConfig
(在 Deployment
清单中)来实现您的问题中提到的设置。
让我解释一下:
示例
假设您有一个 backend
:
-
nginx-one
- 位于内部和外部
最基本形式的 frontend
清单应如下所示:
-
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
字段。 -
searches
:用于在 Pod 中查找主机名的 DNS 搜索域列表。此属性是可选的。指定后,提供的列表将合并到从所选 DNS 策略生成的基本搜索域名中。删除重复的域名。 Kubernetes 最多允许 6 个搜索域。
至于 Services
的 backends
。
-
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
之后!)。默认情况下,您可以通过以下方式与其通信:
-
service-name
(nginx-one
) -
service-name.namespace.svc.cluster.local
(nginx-one.default.svc.cluster.local
) - 仅限本地
连接到您的后端
假设您使用 curl
(为简单起见)从 frontend
到 backend
发送请求,当涉及到 DNS
解析时,您将有一个特定的顺序:
- 检查集群内的
DNS
记录 - 检查
DNS
中指定的dnsConfig
记录
连接到您的 backend
的具体细节如下:
- 如果带有
Pod
的backend
在集群中可用,DNS
解析将指向 Pod 的 IP(而不是ClusterIP
) - 如果
Pod
backend
由于各种原因在集群中不可用,DNS
解析将首先检查内部记录,然后选择使用DOMAIN.NAME
dnsConfig
(minikube
之外)。 - 如果没有与特定
Service
(backend
) 关联的nginx-one
,DNS
解析将使用DOMAIN.NAME
中的dnsConfig
在集群外搜索它。
附注!
Headless Service with selector
在这里起作用,因为它的目的是直接指向 Pod
的 IP 而不是 ClusterIP
(只要 Service
存在,它就存在)。如果您使用“普通”Service
,即使没有与选择器匹配的 ClusterIP
可用,您也会始终尝试与 Pods
通信。使用 headless
时,如果没有 Pod
,DNS
分辨率会进一步查找(外部来源)。
其他资源:
- Minikube.sigs.k8s.io: Docs: Start
- Aws.amazon.com: Blogs: Compute: Enabling dns resolution for amazon eks cluster endpoints
编辑:
您还可以查看其他选项:
备选方案 1:
- 使用 CoreDNS 中的重写规则插件将
backendapi.learning.com
的 DNS 查询重写为backendapi.default.svc.cluster.local
备选方案 2:
- 将 hostAliases 添加到前端 Pod
您还可以使用 Configmaps 重复使用 .env
文件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。