Pod用于连接到同一集群中的Postgresql Pod的Connectionstring?

时间:2020-02-10 16:58:38

标签: postgresql kubernetes npgsql

我目前正在开发将在kubernetes容器中运行的应用程序。它应该连接到在同一集群中运行的postgressql pod。

但是由于某种原因我不能推断出连接字符串应该是什么

我现在这样定义postgressql部署:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:10.4
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 5432
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgredb
      volumes:
        - name: postgredb
          persistentVolumeClaim:
            claimName: postgres-pv-claim   

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

但需要一个连接字符串

            x.UseNpgsql("Host=postgres-service:5432;Database=postgres;Username=postgres;Password=postgres"));

哪个似乎不起作用?

一样简单
using System;
using System.Net.NetworkInformation;

    namespace pingMe
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
                Ping ping = new Ping();
                PingReply pingresult = ping.Send("postgres-service.default.svc.cluster.local");
                if (pingresult.Status.ToString() == "Success")
                {
                    Console.WriteLine("I can reach");
                }
            }
        }
    }

解决这个问题

集群内触发错误

    System.Net.NetworkInformation.PingException: An exception occurred during a Ping request.
 ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name or service not known
   at System.Net.Dns.InternalGetHostByName(String hostName)
   at System.Net.Dns.GetHostAddresses(String hostNameOrAddress)
   at System.Net.NetworkInformation.Ping.GetAddressAndSend(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options)
   --- End of inner exception stack trace ---
   at System.Net.NetworkInformation.Ping.GetAddressAndSend(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options)
   at System.Net.NetworkInformation.Ping.Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options)
   at System.Net.NetworkInformation.Ping.Send(String hostNameOrAddress)
   at API.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env, SchemaContext schemaContext) in /src/API/Startup.cs:line 42
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.b__0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass13_0.b__2(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
Unhandled exception. System.Net.NetworkInformation.PingException: An exception occurred during a Ping request.

Kubernetes服务

kubectl get svc postgres-service
NAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
postgres-service   ClusterIP   10.106.91.9   <none>        5432/TCP   74m

Dockerfile:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["pingMe/pingMe.csproj", "pingMe/"]
RUN dotnet restore "pingMe/pingMe.csproj"
COPY . .
WORKDIR "/src/pingMe"
RUN dotnet build "pingMe.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "pingMe.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "pingMe.dll"]

本地豆荚:

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: local-deployment
spec:
  replicas: 1
  revisionHistoryLimit: 3
  template:
    metadata:
      labels:
        app: local-pod
    spec:
      containers:
      - name: local-deployment
        image: api:dev5
        imagePullPolicy: Never
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /WeatherForecast
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 3

4 个答案:

答案 0 :(得分:0)

tl; dr:postgres-service.default.svc

请参见explanation in the docsdefault是您的名称空间名称,群集域部分可以省略。

答案 1 :(得分:0)

pod中的/etc/resolv.conf文件是否具有coredns pod的IP?它应该如下所示:

u@pod$ cat /etc/resolv.conf
nameserver 10.0.0.10 # IP of core dns pod
search default.svc.cluster.local svc.cluster.local cluster.local example.com
options ndots:5

还要检查您是否能够查找其他任何服务

nslookup kubernetes.default.svc

请选中此guide,以了解如何调试kubernetes中服务的问题。

答案 2 :(得分:0)

我已经阅读了所有答案和评论,让我们重新开始,以便我们有新的观点。

我目前正在开发将在kubernetes容器中运行的应用程序。它应该连接到在同一集群中运行的PostgreSql pod。

为了帮助您,我们需要分别测试您环境的每个步骤。

首先,一个澄清:

  • 服务不接受ping ,要测试服务,您必须测试公开的应用程序的端口。这样设计的。

步骤1-我们需要确保PostgreSQL服务正常运行。

这是我部署的PostgreSQL:

$ kubectl get all 
NAME                                 READY   STATUS    RESTARTS   AGE
pod/postgresql-0   1/1     Running   0          99m

NAME                          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
service/postgresql            ClusterIP   10.0.8.179   <none>        5432/TCP   99m
service/postgresql-headless   ClusterIP   None         <none>        5432/TCP   99m
service/kubernetes            ClusterIP   10.0.0.1     <none>        443/TCP    8d

NAME                          READY   AGE
statefulset.apps/postgresql   1/1     99m
  • A节-运行一个postgresql-client交互式Shell Pod:
$ kubectl run postgresql-client --rm --tty -i --restart='Never' \
--namespace default \
--image docker.io/bitnami/postgresql:11.6.0-debian-10-r0 \
--env="PGPASSWORD=postgres" \
--command -- psql --host postgres \
-U postgres -d postgres -p 5432

如果凭据正确,您将看到postgres=#。尝试运行诸如\du之类的命令:

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

如果:它有效!转到步骤2

如果不是:

  • B部分-使用postgresql-client进行手动测试。

启动Ubuntu shell的单个执行pod:

kubectl run -i --tty --rm --image ubuntu test-shell -- /bin/bash

然后安装postgresql客户端和nslookup:

apt update && apt install postgresql-client -y && apt install dnsutils -y

运行nslookup到服务:

root@test-shell-845c969686-h9gz2:/# nslookup postgresql
Server:         10.0.0.10
Address:        10.0.0.10#53

Name:   postgresql.default.svc.cluster.local
Address: 10.0.8.179

正如您所见,由于我们在同一个集群命名空间中工作,对跪跪蝎子PostgreSQL的所有调用都被正确分配,而无需指定FQDN。

运行pg_isready (请记住host是服务,而不是Pod)

root@test-shell-845c969686-h9gz2:/# pg_isready --host=postgresql --port=5432 --username=postgres --dbname=postgresql
postgresql:5432 - accepting connections

您也可以将其作为连接字符串进行测试:

结构为export my_conn='postgresql://user:password@FQDN/DATABASE'

root@test-shell-845c969686-h9gz2:/# export my_conn='postgresql://postgres:postgres@postgresql/postgres'
root@test-shell-845c969686-h9gz2:/# pg_isready -d $my_conn
kneeling-scorpion-postgresql:5432 - accepting connections

最后,让我们像使用postegresql-client窗格那样再次进行登录连接:

root@test-shell-845c969686-vh9zh:/# psql --host=postgresql --port=5432 --username=postgres --dbname=postgres  
Password for user postgres: 
psql (10.10 (Ubuntu 10.10-0ubuntu0.18.04.1), server 11.6)
Type "help" for help.

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

如果:它有效!转到步骤2

如果不是:

  • 您的PostgreSQL可能存在一些问题。
  • 在这一点上,我建议您再次尝试此测试,但要使用干净的数据库,例如Helm Chart:stable/postgresqlDocumentation Here。确实很容易在需要时安装和删除。

第2步-缩小范围至客户端:

在这一点上,我假设您的数据库连接工作正常。 因此,我们必须回顾一些事情:

  • 如果您可以从其他Pod连接到数据库,建议您尝试从B部分中使用的Ubuntu POD部署并运行APP的实例

如果仍然无法正常运行,那么现在您可以缩小应用程序内部的范围。

如果您在重现此解决方案方面遇到任何困难,请在评论中让我知道。

答案 3 :(得分:0)

我不确定我理解为什么。但是我所有的asp。网络核心容器化应用程序无法解析服务名称。

这些必须在单独的步骤中使用 https://docs.microsoft.com/en-us/dotnet/api/system.net.dns.gethostname?view=netframework-4.8 ,然后将其作为IP地址传递,从上一步中解决。

我基于nslookup的响应方式,最初由于未缓存dns记录而失败,然后解析了主机名,因为可以通过广播找到它。

我猜因为最初的dns查找失败,所以它触发并引发异常,而我的失败总是...