1

我正在尝试将在Kind中运行的 pod与在 Docker 容器中运行的本地 Postgres 数据库连接起来。我尝试添加以下服务,但使用 DNS 名称时 pod 仍然无法连接postgres.dev.svc

kind: Service
apiVersion: v1
metadata:
  name: postgres
  namespace: dev
spec:
  type: ExternalName
  externalName: 10.0.2.2

还有其他方法可以连接这两个组件吗?

4

2 回答 2

2

首先,这不是ExternalName服务类型的正确使用。尽管将 IP 地址放在externalName字段中是完全可行的,即资源将被创建并且您不会收到来自 kubernetes API 服务器的任何投诉。❗<strong>但此值被视为由数字组成的域名,而不是 IP 地址。您可以在官方 kubernetes 文档中了解它:

注意: ExternalName 接受 IPv4 地址字符串,但作为由数字组成的 DNS 名称,而不是作为 IP 地址。类似于 IPv4 地址的 ExternalNames 不会由 CoreDNS 或 ingress-nginx 解析,因为 ExternalName 旨在指定规范的 DNS 名称。要对 IP 地址进行硬编码,请考虑使用无头服务

所以你真正需要的是没有选择器的服务

服务最常抽象出对 Kubernetes Pod 的访问,但它们也可以抽象出其他类型的后端。例如:

  • 您希望在生产中拥有一个外部数据库集群,但在您的测试环境中,您使用自己的数据库。
  • 您希望将您的服务指向不同 命名空间 或另一个集群中的服务。
  • 您正在将工作负载迁移到 Kubernetes。在评估该方法时,您只在 Kubernetes 中运行一部分后端。

在任何这些场景中,您都可以在没有 Pod 选择器的情况下定义服务 。例如:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

由于此 Service 没有选择器,因此不会自动创建相应的 Endpoints 对象。您可以通过手动添加 Endpoints 对象,手动将服务映射到其运行的网络地址和端口:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376

在您的特定情况下,您的Service定义可能如下所示:

apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  ports:
    - protocol: TCP
      port: 5432
      targetPort: 5432

并且相应的Endpoints对象可能如下所示:

apiVersion: v1
kind: Endpoints
metadata:
  name: postgres
subsets:
  - addresses:
      - ip: 10.0.2.2
    ports:
      - port: 5432

当然,IP 地址10.0.2.2必须可以从您的 kubernetes 集群中访问。

于 2021-06-29T16:18:17.167 回答
1

我可以给出一些建议,我将如何尝试调试这样的问题。

  1. 确保您可以从您的工作站或其他主机登录到数据库,以便我们可以排除此问题与 docker/database-host 相关。

  2. 检查您是否可以从集群访问数据库,或者流量是否被防火墙阻止。您可以为此用例生成一个 tmp 容器kubectl run -i --tty --rm debug --image=busybox --restart=Never -- sh,然后尝试 ping、curl、wget ... ip(busybox 仅包含 wget,但可以随意使用其他图像)

  3. 硬编码连接字符串中的 Ip,而不是在命名空间中为 dns 使用外部服务。

如果这不能解决问题,您可能需要发布更详细的描述。

于 2021-06-29T11:32:17.970 回答