在 k8s 集群内访问 mongodb 是通过 headless service,为了能在 k8s 集群外访问,我们另外部署了 NodePort service,但在应用中连接 mongodb 时出现 "Server returned not primary error" 错误
apiVersion: v1
kind: Service
metadata:
name: mongodb-nodeport
namespace: production
spec:
type: NodePort
selector:
app.kubernetes.io/component: mongodb
app.kubernetes.io/instance: mongodb-default
app.kubernetes.io/name: mongodb
ports:
- nodePort: 31100
port: 27017
targetPort: 27017
mongodb 的 pod 是通过 statefulset 部署的
mongodb-default-0 1/1 Running 1 (6d5h ago) 30d
mongodb-default-1 1/1 Running 1 (8d ago) 31d
通过一对一服务(一个 service 对应一个 pod)解决了
apiVersion: v1
kind: Service
metadata:
name: mongodb-nodeport-0
namespace: production
spec:
type: NodePort
selector:
statefulset.kubernetes.io/pod-name: mongodb-default-0
ports:
- nodePort: 31100
port: 27017
targetPort: 27017
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-nodeport-1
namespace: production
spec:
type: NodePort
selector:
statefulset.kubernetes.io/pod-name: mongodb-default-1
ports:
- nodePort: 31101
port: 27017
targetPort: 27017
应用中的 mongodb 连接字符串
"mongodb://user:password@mongodb-prod:31101,mongodb-prod:31102"
应用的日志中出现下面的错误
System.TimeoutException: A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "1", Type : "ReplicaSet", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/mongodb-default-0.mongodb-default-headless.production.svc.cluster.local:27017" }", EndPoint: "Unspecified/mongodb-default-0.mongodb-default-headless.production.svc.cluster.local:27017", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.
---> System.Net.Sockets.SocketException (00000005, 0xFFFDFFFF): Name or service not known
at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, Int64 startingTimestamp)
@dudu: 增加了2个负载均衡,通过四层转发,分别将 27017 端口转发到 mongodb-nodeport-0(端口31100) 与 mongodb-nodeport-1(端口31101), 将 mongodb-default-0.mongodb-default-headless.production.svc.cluster.local 与 mongodb-default-1.mongodb-default-headless.production.svc.cluster.local 分别解析到这2个负载均衡解决了问题
添加的主机名解析:
10.0.1.210 mongodb-prod0
10.0.1.221 mongodb-prod1
10.0.1.210 mongodb-default-0.mongodb-default-headless.production.svc.cluster.local
10.0.1.221 mongodb-default-1.mongodb-default-headless.production.svc.cluster.local
应用中的 mongodb 连接字符串
"mongodb://user:password@mongodb-prod0:27017,mongodb-prod1:27017"