【发布时间】:2021-12-11 03:39:46
【问题描述】:
我是 Kubernetes 新手,我是第一次在 Kubernetes 上部署应用程序。我想部署一个 postgreSQL statefulset 和一个简单的 spring boot pod 副本集。我创建了一个无头服务,它将附加到以下 statefulset。
# Headless Service
apiVersion: v1
kind: Service
metadata:
name: ecom-db-h
spec:
ports:
- targetPort: 5432
port: 80
clusterIP: None
selector:
app: ecom-db
---
# PostgreSQL StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: ecomdb-statefulset
labels:
app: ecom-db
spec:
serviceName: ecom-db-h
selector:
matchLabels:
app: postgresql-db
replicas: 2
template:
# Pod Definition
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: db
image: postgres:13
ports:
- name: postgres
containerPort: 5432
# volumeMounts:
# - name: ecom-db
# mountPath: /var/lib/postgresql/data
env:
- name: POSTGRES_DB
value: ecommerce
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: <password>
#volumes:
# - name: ecom-db
# persistentVolumeClaim:
# claimName: ecom-pvc
这是我为 Spring Boot 应用程序 pod 创建的副本集:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: ecom-server
labels:
app: ecom-server
tier: backend
spec:
# modify replicas according to your case
replicas: 2
selector:
matchLabels:
type: backend
template:
# Pod definition
metadata:
labels:
app: ecom-server
type: backend
spec:
containers:
- name: ecommerce-server
image: <my.private.repo.url>/spring-server:kubernetes-test
imagePullPolicy: Always
imagePullSecrets:
- name: regcred
我使用的是默认命名空间,这里是 application.properties:
spring.datasource.url=jdbc:postgresql://ecom-db-h.default.svc.cluster.local/ecommerce?useSSL=false
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.username=postgres
spring.datasource.password=<password>
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.format_sql=true
spring.jpa.hibernate.id.new_generator_mappings=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect
但是我的 spring boot 容器总是退出并出现以下错误:
Caused by: java.net.UnknownHostException: ecom-db-h.default.svc.cluster.local
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.postgresql.core.PGStream.createSocket(PGStream.java:231)
at org.postgresql.core.PGStream.<init>(PGStream.java:95)
at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213)
... 136 common frames omitted
这意味着副本集无法找到无头服务,或者我的无头服务根本没有连接到有状态的 Pod。我错过了 YAML 文件中的某些内容吗?还是我以错误的方式使用无头服务?
更新:
感谢@Thomas 和@harsh-manvar,我了解到无头服务并不意味着连接到数据库。相反,我应该使用普通的 ClusterIP 服务。问题是我这样做了,但我仍然遇到同样的错误。这是我的新 YAML 文件:
application.properties 修改:
spring.datasource.url=jdbc:postgresql://db-svc.default.svc.cluster.local/ecommerce?useSSL=false
statefulset.yaml 修改
# ClusterIP service instead of the headless service
apiVersion: v1
kind: Service
metadata:
name: db-svc
spec:
ports:
- name: pgql
port: 80
targetPort: 5432
protocol: TCP
selector:
app: db
---
# PostgreSQL StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: db-sts
labels:
app: db-sts
spec:
serviceName: db-svc
selector:
matchLabels:
app: db
replicas: 2
template:
# Pod Definition
metadata:
labels:
app: db
spec:
containers:
- name: db
image: postgres:13
ports:
- name: postgres
containerPort: 5432
# volumeMounts:
# - name: ecom-db
# mountPath: /var/lib/postgresql/data
env:
- name: POSTGRES_DB
value: ecommerce
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: mss#123
#volumes:
# - name: ecom-db
# persistentVolumeClaim:
# claimName: ecom-pvc
这是新的错误:
Caused by: java.net.UnknownHostException: db-svc.default.svc.cluster.local
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.postgresql.core.PGStream.createSocket(PGStream.java:231)
at org.postgresql.core.PGStream.<init>(PGStream.java:95)
at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213)
... 136 common frames omitted
我的 statefulset pod 运行顺利,服务已创建:
NAME READY AGE
statefulset.apps/db-sts 2/2 26m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/db-svc ClusterIP 10.108.39.189 <none> 5432/TCP 26m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30m
NAME READY STATUS RESTARTS AGE
db-sts-0 1/1 Running 0 26m
db-sts-1 1/1 Running 0 26m
ecom-server-5jbs2 0/1 CrashLoopBackOff 9 (44s ago) 25m
ecom-server-rtpmg 0/1 CrashLoopBackOff 8 (4m46s ago) 25m
NAME ENDPOINTS AGE
db-svc 10.244.1.48:5432,10.244.2.85:5432 18h
第二次更新:
在 pod 中运行 alpine-shell 容器以检查 DNS 解析后,我执行了“nslookup db-svc.default.svc.cluster.local”并得到了这个:
nslookup db-svc.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: db-svc.default.svc.cluster.local
Address: 10.107.101.52
这意味着服务确实存在并且可以从这个容器中访问它。奇怪的是,当我执行 pgsql 命令尝试连接到 postgres 数据库服务器时,我根本没有得到任何响应,命令甚至没有退出。这是错误
WARN SqlExceptionHelper - SQL Error: 0, SQLState: 08001
ERROR SqlExceptionHelper - The connection attempt failed.
Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:315)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:51)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:225)
at org.postgresql.Driver.makeConnection(Driver.java:465)
at org.postgresql.Driver.connect(Driver.java:264)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:358)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:477)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:560)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:43)
... 122 common frames omitted
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:607)
at org.postgresql.core.PGStream.createSocket(PGStream.java:231)
at org.postgresql.core.PGStream.<init>(PGStream.java:95)
at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213)
... 136 common frames omitted
【问题讨论】:
标签: java spring postgresql spring-boot kubernetes