k8s搭建mongo分片
创建公共资源
1. 创建名称空间
kubectl create ns mongo-shard
2. 创建集群内部认证证书
openssl rand -base64 741 > ./keyFile.txt
kubectl create secret generic mongo-shard-keyfile -n mongo-shard --from-file=keyfile=./keyFile.txt
# keyFile base64
cat keyFile.txt | base64
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mongo-shard-keyfile
type: Opaque
data:
# 上述base64内容
keyfile: NHZIUlFlV2lVUi9VT2pjWVFNN1M3bEJWWTJWaXlmRHc2UFQvRmQxNE1kbFY5eDZDSTRhMEZJWXNKanhPYmdKLwpDNHdvVVpacHp2QURyMGVxUG5OaHhaR0VwQi9tcU03R05nZXF6NDlJV0VYaG9Db2psVkpGK2YzcXR6M3kzVWtKCkYrVEFwanc2cHV6cFZHd083K0Z1Zm5ZL3JRa1JUM1F1RU5VNFdpckdOelVOb2x2UXhuenZGVmlpRjF4M0Vzb1MKZ05FSXNSN2xNMFUxb25yaGJhNGlyUFZROEZOQk43WERRNy93TnRaVkk2RnpVb3BkQjI4VXpic2FRV29WZnNHYgo3L1hDeG5BYUR5RklXZktmaWExRWN2VWxKZEUwQVJ1VVN1TDdreTBmUzlzRmh4QjZlZVJQVkF4US9IQU9ZWkRHCm9EaTZxVXFKVmhnTkFqM01rQ3plTVhMUUx5WDJuMUdsYW13cWhEVm5uYUtwaWpkNW84YmlBeTVlcyt2UC9pTXEKcm5OTFFGWDZuR1UxS2ZsWXJkdjZZVTZmNEdBN285Yys1UGhqOS9JN0xtdllvQnVMR002RFdEU1RlVzV1TVhFNgoxS29KVXZ4NjhqcnBSaEJKS2k3WGdrNHdSZENudVFtZ0hVWUdhR0R0Q2MxRHNGM0ZOWUhpbUFvZ04xSlBKakJ3CjYrTldYaVdVYjJIbUpLVHZtL2h3bHZNNm56REhqb0tWcS9vK2lYbXYvc0FZbzhEbEZ4L3ZoRUdZclJnUEVXYnQKT2YyV09oam00RVVkdWFoalJKWWZWM2k3c3QvMDU0U3g1WEZmMnZ3UnhGVmw1WUYxVzNLeEZYL3I1N3ZkZUNhWgprQ3hOWCtKckRUTVlYTjZLYTRQYXJkQXNZK0pFeGFLOTFYZko1YTN1R0d1aWRXcWFFTHBNa0NnZ2NTaklwZ2xlCncrK2tYTFNSei9XZXNJSjljc3BYY2x0L1dSTVp0eW0rajBDbVlZejZLVFk2c2dOL2l4U1diMitGanpxUnF0blIKZmhuSnMxWUQ0MDVpUS9aUHFjNkxzdHFNc2dXRUIxL1ZqZUQwOUdiSEFSemR0YmFJZjFEWmc2RUNzbEk2VkR3WQpMN21GQ1VLcmFjd2k4aEQ4V1FjTVo0RFpCTWluRGVLSkNlZHpMdytMVDFJL01VanNQS1plOWg3R2NtNElTNzg5CitLcDNXRzZ0Rk1DTmw0Q3dLeERnS1dkTlV3YXNBc21iNkMvZVBqWnFzdGNjWGhGVWJQaFNsNmxTa2hnSTFwWGEKN05haFdRYWtwL1RnZC8xbHI3VzJDN2FucWcwQQo=
kubectl apply -f secret.yaml -n mongo-shard
创建第一个分片
1. 创建副本集
# ./shard1/shard1.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo-shard1
spec:
serviceName: mongo-shard1-svc
replicas: 3
selector:
matchLabels:
app: mongo-shard1
template:
metadata:
labels:
app: mongo-shard1
spec:
containers:
- name: mongo
image: mongo:5.0.5
ports:
- containerPort: 27017
command:
- "mongod"
- "--bind_ip_all"
- "--replSet"
- "shard1"
- "--keyFile"
- "/etc/keyfile/keyfile"
- "--port"
- "27017"
- "--shardsvr"
volumeMounts:
- name: data
mountPath: /data/db
- name: keyfile
mountPath: /etc/keyfile
readOnly: true
resources:
limits:
cpu: 1000m
memory: 1024Mi
volumes:
- name: keyfile
secret:
secretName: mongo-shard-keyfile
defaultMode: 256
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 2G
storageClassName: rook-ceph-block
---
apiVersion: v1
kind: Service
metadata:
name: mongo-shard1-svc
spec:
selector:
app: mongo-shard1
ports:
- port: 27017
targetPort: 27017
protocol: TCP
clusterIP: None
kubectl apply -f ./shard1/shard1.yaml -n mongo-shard
2. 初始化副本集
- 初始化副本集
kubectl exec -it -n mongo-shard mongo-shard1-0 -- mongo
rs.initiate({
_id: "shard1",
"members": [
{
"_id": 0,
"host": "mongo-shard1-0.mongo-shard1-svc"
},
{
"_id": 1,
"host": "mongo-shard1-1.mongo-shard1-svc"
},
{
"_id": 2,
"host": "mongo-shard1-2.mongo-shard1-svc"
}
]
})
rs.status()
- 创建用户
const adminDb = db.getSiblingDB('admin');
# 创建root用户
adminDb.createUser({
user: "root",
pwd: "Root123456!",
roles: [
{
role: "root",
db: "admin"
}
]
});
# 登录root用户
adminDb.auth('root','Root123456!')
# 创建admin用户
adminDb.createUser({
user: "admin",
pwd: "Root123456!",
roles: [
{
role: "userAdminAnyDatabase",
db: "admin"
},
{
role: "clusterAdmin",
db: "admin"
},
]
});
3. 验证副本集
const testDb = db.getSiblingDB('test');
# 创建test数据库用户
testDb.createUser({
user: "test",
pwd: "Test123456!",
roles: ["dbOwner"]
})
# 添加数据
testDb.temp.insert({name:"tokily"})
# 当前数据库获取数据
testDb.temp.find()
# 退出mongo
exit
# 连接其他mongo
kubectl exec -it -n mongo-shard mongo-shard1-1 -- mongo -utest -pTest123456! test
# 开启副本可读
rs.secondaryOk()
# 查询是否存在相同文档
db.temp.find()
# 验证完毕退出
exit
创建config
1. 创建config副本集
# ./config/config.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo-config
spec:
serviceName: mongo-config-svc
replicas: 3
selector:
matchLabels:
app: mongo-config
template:
metadata:
labels:
app: mongo-config
spec:
containers:
- name: mongo
image: mongo:5.0.5
ports:
- containerPort: 27017
command:
- "mongod"
- "--bind_ip_all"
- "--replSet"
- "config"
- "--keyFile"
- "/etc/keyfile/keyfile"
- "--port"
- "27017"
- "--configsvr"
volumeMounts:
- name: data
mountPath: /data/db
- name: keyfile
mountPath: /etc/keyfile
readOnly: true
resources:
limits:
cpu: 1000m
memory: 1024Mi
volumes:
- name: keyfile
secret:
secretName: mongo-shard-keyfile
defaultMode: 256
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
storageClassName: rook-ceph-block
---
apiVersion: v1
kind: Service
metadata:
name: mongo-config-svc
spec:
selector:
app: mongo-config
ports:
- port: 27017
targetPort: 27017
protocol: TCP
clusterIP: None
kubectl apply -f ./config/config.yaml -n mongo-shard
2. 初始化config副本集
kubectl exec -it -n mongo-shard mongo-config-0 -- mongo
rs.initiate({
_id: "config",
"members": [
{
"_id": 0,
"host": "mongo-config-0.mongo-config-svc"
},
{
"_id": 1,
"host": "mongo-config-1.mongo-config-svc"
},
{
"_id": 2,
"host": "mongo-config-2.mongo-config-svc"
}
]
})
exit
创建mongos
1. 创建mongos负载
# ./mongos/mongos.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-mongos
spec:
replicas: 3
selector:
matchLabels:
app: mongo-mongos
template:
metadata:
labels:
app: mongo-mongos
spec:
containers:
- name: mongo-mongos
image: mongo:5.0.5
resources:
limits:
memory: "512Mi"
cpu: "1000m"
ports:
- containerPort: 27017
command:
- "mongos"
- "--bind_ip_all"
- "--port"
- "27017"
- "--keyFile"
- "/etc/keyfile/keyfile"
- "--configdb"
- "config/mongo-config-0.mongo-config-svc:27017,mongo-config-1.mongo-config-svc:27017,mongo-config-2.mongo-config-svc:27017"
volumeMounts:
- name: keyfile
mountPath: /etc/keyfile
readOnly: true
volumes:
- name: keyfile
secret:
secretName: mongo-shard-keyfile
defaultMode: 256
---
apiVersion: v1
kind: Service
metadata:
name: mongo-mongos-svc
spec:
type: NodePort
selector:
app: mongo-mongos
ports:
- port: 27017
targetPort: 27017
nodePort: 30018
kubectl apply -f ./mongos/mongos.yaml -n mongo-shard
2. 创建用户
# 任意mongos pod
kubectl exec -it -n mongo-shard mongo-mongos-7c44757b6d-d8bjn -- mongo
const adminDb = db.getSiblingDB('admin');
adminDb.createUser({
user: "root",
pwd: "Root123456!",
roles: [
{
role: "root",
db: "admin"
}
]
});
adminDb.auth('root','Root123456!')
adminDb.createUser({
user: "admin",
pwd: "Root123456!",
roles: [
{
role: "userAdminAnyDatabase",
db: "admin"
},
{
role: "clusterAdmin",
db: "admin"
},
]
});
添加第一个分片
1. 添加shard1
# 添加第一个分片
sh.addShard("shard1/mongo-shard1-0.mongo-shard1-svc:27017,mongo-shard1-1.mongo-shard1-svc:27017,mongo-shard1-2.mongo-shard1-svc:27017")
# 查看分片状态
sh.status()
2. 验证分片
# company库开启分片
sh.enableSharding("company")
# 创建分片策略
sh.shardCollection("company.emp", {_id: 'hashed'})
# 查看分片状态
sh.status()
# 添加数据
use company
for (var i = 0; i < 100; i++) {
db.emp.insert({i: i});
}
# 查看数据分布
db.emp.getShardDistribution()
exit
创建第二个分片
1. 创建副本集
# ./shard2/shard2.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo-shard2
spec:
serviceName: mongo-shard2-svc
replicas: 3
selector:
matchLabels:
app: mongo-shard2
template:
metadata:
labels:
app: mongo-shard2
spec:
containers:
- name: mongo
image: mongo:5.0.5
ports:
- containerPort: 27017
command:
- "mongod"
- "--bind_ip_all"
- "--replSet"
- "shard2"
- "--keyFile"
- "/etc/keyfile/keyfile"
- "--port"
- "27017"
- "--shardsvr"
volumeMounts:
- name: data
mountPath: /data/db
- name: keyfile
mountPath: /etc/keyfile
readOnly: true
resources:
limits:
cpu: 1000m
memory: 1024Mi
volumes:
- name: keyfile
secret:
secretName: mongo-shard-keyfile
defaultMode: 256
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 2G
storageClassName: rook-ceph-block
---
apiVersion: v1
kind: Service
metadata:
name: mongo-shard2-svc
spec:
selector:
app: mongo-shard2
ports:
- port: 27017
targetPort: 27017
protocol: TCP
clusterIP: None
kubectl apply -f ./shard2/shard2.yaml -n mongo-shard
2. 初始化副本集
- 初始化副本集
kubectl exec -it -n mongo-shard mongo-shard2-0 -- mongo
rs.initiate({
_id: "shard2",
"members": [
{
"_id": 0,
"host": "mongo-shard2-0.mongo-shard2-svc"
},
{
"_id": 1,
"host": "mongo-shard2-1.mongo-shard2-svc"
},
{
"_id": 2,
"host": "mongo-shard2-2.mongo-shard2-svc"
}
]
})
rs.status()
- 创建用户
const adminDb = db.getSiblingDB('admin');
# 创建root用户
adminDb.createUser({
user: "root",
pwd: "Root123456!",
roles: [
{
role: "root",
db: "admin"
}
]
});
# 登录root用户
adminDb.auth('root','Root123456!')
# 创建admin用户
adminDb.createUser({
user: "admin",
pwd: "Root123456!",
roles: [
{
role: "userAdminAnyDatabase",
db: "admin"
},
{
role: "clusterAdmin",
db: "admin"
},
]
});
3. 验证副本集
const testDb = db.getSiblingDB('test1');
# 创建test数据库用户
testDb.createUser({
user: "test",
pwd: "Test123456!",
roles: ["dbOwner"]
})
# 添加数据
testDb.temp.insert({name:"tokily"})
# 当前数据库获取数据
testDb.temp.find()
# 退出mongo
exit
# 连接其他mongo
kubectl exec -it -n mongo-shard mongo-shard2-1 -- mongo -utest -pTest123456! test1
# 开启副本可读
rs.secondaryOk()
# 查询是否存在相同文档
db.temp.find()
exit
添加第二个分片
1. 添加shard2
# 连接任意mongos
kubectl exec -it -n mongo-shard mongo-mongos-7c44757b6d-d8bjn -- mongo
# 登录
const adminDb = db.getSiblingDB('admin');
adminDb.auth('root','Root123456!')
# 添加第二个分片
sh.addShard("shard2/mongo-shard2-0.mongo-shard2-svc:27017,mongo-shard2-1.mongo-shard2-svc:27017,mongo-shard2-2.mongo-shard2-svc:27017")
# 查看分片状态
sh.status()
2. 验证分片
# company库开启分片
sh.enableSharding("company1")
# 创建分片测虐
sh.shardCollection("company1.emp", {_id: 'hashed'})
# 查看分片状态
sh.status()
# 添加数据
use company1
for (var i = 0; i < 100; i++) {
db.emp.insert({i: i});
}
# 查看数据分布
db.emp.getShardDistribution()
exit
注意事项
- 本文档使用名为“rook-ceph-block”的ceph块存储sc,读者可自行替换其他存储方案
- 本文档所定义的资源配额、镜像版本、命名等,皆根据笔者环境指定,读者可自行替换