无法远程连接到 OpenShift 部署中的 Postgres 数据库,但可以通过带有端口转发的本地主机

Can't Connect to Postgres Database in OpenShift Deployment remotely but can via localhost with portforwarding

设置摘要

我有一个包含三个 pods 的远程 Openshift 集群。一个为 Web 应用程序提供服务的 nginx pod,一个为 .NET 网络提供服务的 .NET pod api,以及一个 Postgres 数据库 pod。

问题

我能够将 nginx pod 连接到 .NET pod 并且在发出 api 请求时没有问题。但是,我无法从 .NET pod 到 Openshift 集群中的 Postgres pod 进行通信。我可以从 Openshift Web 控制台中的 .NET pod 终端卷曲 Postgres pod,并且能够使用 Postrgres pod 的服务名称连接 Postgres pod 本身(而不是数据库),因此 Postgres pod 的 DNS 解析工作正常。使用 Openshift 的端口转发将流量从我本地机器的 localhost:5432 转发到我的 Postgres Pod 的端口 5432,我可以连接到 Postgres 数据库,同时使用连接字符串 运行 在本地连接 .NET API Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=postgres。只要我连接到本地数据库,我就可以毫无问题地查询、插入等。所以通过 localhost 连接到数据库显然是可行的。但是当在 Openshift 集群内时,我无法让 .NET pod 连接到 Postgres Pod 数据库。数据库应该将来自另一个 pod 的连接视为远程连接,对吗?但它根本不起作用。 postgres 日志也没有显示任何有关连接尝试的信息。

我的 .NET 使用 Host=postgres;Port=5432;Database=postgres;Username=postgres;Password=postgres。这存储在我的 appsettings.json 中。这是在我的 Startup.cs.

中读到的
// (U) add database context
services.AddDbContext<StigContext>(
    options => options.UseNpgsql(Configuration["DbConnectionString"])
);

.NET 数据库连接方法,当我 运行 并通过 Openshift 的端口转发本地连接到我机器上的远程 Postgres pod 时,此端点 returns 为真。

public IActionResult TestDatabaseConnection()
{          
    try 
    {              
        stigContext.Database.OpenConnection();
        return Ok(stigContext.Database.CanConnect());
    }
    catch (Exception e)
    {
        var error = e.Message + "\n" + e.ToString() + "\n" + e.StackTrace;
        return Ok(error);
    }              
}

Postgres 部署和服务,PVC 通过 Openshift Web 控制台完成

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  selector:
    matchLabels:
      app: postgres
  replicas: 1
  template:
    metadata:
      annotations:
          sidecar.istio.io/inject: "true"
          sidecar.istio.io/proxyCPULimit: 200m
          sidecar.istio.io/proxyMemory: 64Mi
          sidecar.istio.io/proxyMemoryLimit: 256Mi
          sidecar.istio.io/rewriteAppHTTPProbers: "true"
      labels:
        app: postgres
        version: v1
    spec:
      containers:
      - name: postgres 
        image: custom-docker-image-for-postgres:latest
        imagePullPolicy: Always
        env:
        - name: POSTGRES_DB
          value: postgres
        - name: POSTGRES_USER
          value: postgres
        - name: POSTGRES_PASSWORD
          value: postgres
        - name: POSTGRES_HOST_AUTH_METHOD
          value: trust
        - name: PGDATA
          value: /var/lib/postgresql/data/mydata
        ports:
        - containerPort: 5432
        volumeMounts:
        - name: postgres-pv-storage
          mountPath: /var/lib/postgresql/data
        resources:
          requests:
            memory: "128Mi"
            cpu: "30m"   
          limits:
            memory: "512Mi"
            cpu: "60m"                     
      volumes:
      - name: postgres-pv-storage
        persistentVolumeClaim:
          claimName: postgres-pv-claim
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: postgres
    service: postgres
  name: postgres
spec:
  ports:
    - name: http
      port: 5432
  selector:
    app: postgres

我在 运行ning Postgres pod 上 运行 一些命令来显示 运行ning 配置...

$ postgres -C listen_addresses
*
$ postgres -C hba_file
/var/lib/postgresql/data/mydata/pg_hba.conf
$ cat /var/lib/postgresql/data/mydata/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust

# warning trust is enabled for all connections
# see https://www.postgresql.org/docs/12/auth-trust.html
host all all all trust
$ postgres -C port
5432

它似乎应该能够通过 pod 到 pod 通信进行远程连接,但绝对不能。我不知道问题是什么。我不知道为什么它不起作用。如果需要,我可以提供任何其他信息。希望这是清楚的。任何建议表示赞赏。

在 appsettings.json 中将主机更改为 postgresql 服务 dns(Postgres pod 服务名称)。

tdlr:我的 postgres 服务的服务定义端口名称是 'http' 而不是 'tcp'。名称字段实际上是协议,因此您在此处输入的内容很重要。

在此处找到解决方案 https://github.com/istio/istio/issues/16506#issuecomment-636224246

如果您的部署不使用 istio,这可能不是问题。

我的 postgres 部署的更新服务 yml 是

apiVersion: v1
kind: Service
metadata:
  labels:
    app: postgres
    service: postgres
  name: postgres
spec:
  ports:
    - name: tcp
      port: 5432
  selector:
    app: postgres