mongodb - 在 Kubernetes 中运行复制的 MongoDB 4.2:未收到 replset 配置
问题描述
我在 AWS 上运行 Kubernetes 集群,需要配置一个复制的 MongoDB 4.2 数据库。我正在使用 StatefulSets 以便其他 Pod(例如 REST API NodeJS Pod)轻松连接到 mongo 实例(例如 dsn: "mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2. mongo:27017/app")。
mongo-configmap.yaml(提供一个 shell 脚本来在 mongo 容器创建时执行复制初始化):
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-init
data:
init.sh: |
#!/bin/bash
# wait for the readiness health check to pass
until ping -c 1 ${HOSTNAME}.mongo; do
echo "waiting for DNS (${HOSTNAME}.mongo)..."
sleep 2
done
until /usr/bin/mongo --eval 'printjson(db.serverStatus())'; do
echo "connecting to local mongo..."
sleep 2
done
echo "connected to local."
HOST=mongo-0.mongo:27017
until /usr/bin/mongo --host=${HOST} --eval 'printjson(db.serverStatus())'; do
echo "connecting to remote mongo..."
sleep 2
done
echo "connected to remote."
if [[ "${HOSTNAME}" != 'mongo-0' ]]; then
until /usr/bin/mongo --host=${HOST} --eval="printjson(rs.status())" \
| grep -v "no replset config has been received"; do
echo "waiting for replication set initialization"
sleep 2
done
echo "adding self to mongo-0"
/usr/bin/mongo --host=${HOST} --eval="printjson(rs.add('${HOSTNAME}.mongo'))"
fi
if [[ "${HOSTNAME}" == 'mongo-0' ]]; then
echo "initializing replica set"
/usr/bin/mongo --eval="printjson(rs.initiate(\
{'_id': 'rs0', 'members': [{'_id': 0, \
'host': 'mongo-0.mongo:27017'}]}))"
fi
echo "initialized"
while true; do
sleep 3600
done
mongo-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: mongo
labels:
app: mongo
spec:
clusterIP: None
ports:
- port: 27017
selector:
app: mongo
mongo-statefulset.yaml(一个 Pod 中的 2 个容器,1 个用于实际数据库,另一个用于复制的初始化):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo
labels:
app: mongo
spec:
selector:
matchLabels:
app: mongo
serviceName: "mongo"
replicas: 3
template:
metadata:
labels:
app: mongo
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongodb
image: mongo:4.2
command:
- mongod
args:
- --replSet
- rs0
- "--bind_ip_all"
ports:
- containerPort: 27017
name: web
volumeMounts:
- name: database
mountPath: /data/db
livenessProbe:
exec:
command:
- /usr/bin/mongo
- --eval
- db.serverStatus()
initialDelaySeconds: 10
timeoutSeconds: 10
- name: init-mongo
image: mongo:4.2
command:
- bash
- /config/init.sh
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
configMap:
name: "mongo-init"
volumeClaimTemplates:
- metadata:
name: database
annotations:
volume.beta.kubernetes.io/storage-class: mongodb-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 5Gi
应用这些配置后,3 个 mongo pod 开始运行(mongo-0、mongo-1、mongo-2)。但是,其他 pod 无法连接到这些 mongo pod。进一步查看 mongo-0 pod(应该是主实例)发现复制不起作用。
kubectl exec -it mongo-0 -- /bin/bash
然后运行 'mongo' 启动 mongo shell,并在 mongo shell 中输入 'rs.status()' 会产生以下输出:
{
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94,
"codeName" : "NotYetInitialized"
}
解决方案
显然,mongo-4.x 图像没有安装“ping”,因此,脚本的其余部分没有执行。将这两行添加到 mongo-configmap.yaml 中的脚本可以解决问题:
apt-get update
apt-get install iputils-ping --yes
推荐阅读
- wcf - .NET Core 无法通过 HTTP 客户端发送 SOAP 请求
- excel - 选择大小写以从列中读取值
- list - 列表中的每个 blitted 图像都会消失而不是保留在屏幕上。我想用图像填满整个屏幕,因为它在随机位置闪烁
- azure-data-factory - 数据集空参数值
- javascript - IOS safari app url问题“Safari无法打开页面,因为地址无效。”
- swift - 无法将类型“()->()”的值转换为预期的参数类型“(LongPressGesture.Value)-> Void”(又名“(Bool)->()”)
- oracle11g - 递归查询可能吗?
- powershell - 如果 ValidatePattern 抛出错误 Powershell,则设置变量
- android - Jetpack Compose 中的自定义 Toast
- function - Google 表格中的条件