无法远程连接到 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
设置摘要
我有一个包含三个 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