運行一個Daemonset的控制器來管理節點,禁用巨頁,因為MongoDB 是建議關掉 Transparent Huge page的 否則可能導致性能下降,內存鎖,甚至系統重啟等問題,當然最好是調整Mongodb 的 Pod 所在的節點
# hostvm-ds.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: hostvm-configurer labels: app: startup-script spec: selector: matchLabels: app: startup-script template: metadata: labels: app: startup-script spec: hostPID: true containers: - name: hostvm-configurer image: cnych/startup-script:v1 securityContext: privileged: true env: - name: STARTUP_SCRIPT value: | #! /bin/bash set -o errexit set -o pipefail set -o nounset # Disable hugepages echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag
然後配置 ServiceAccount、Headless SVC 和 StatefulSet,資源清單文件如下
# mongo.yaml apiVersion: v1 kind: Namespace metadata: name: mongo --- apiVersion: v1 kind: ServiceAccount metadata: name: mongo namespace: mongo --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: mongo subjects: - kind: ServiceAccount name: mongo namespace: mongo roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io --- apiVersion: v1 kind: Service metadata: name: mongo namespace: mongo labels: name: mongo spec: ports: - port: 27017 targetPort: 27017 clusterIP: None selector: role: mongo --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mongo namespace: mongo spec: serviceName: mongo replicas: 3 selector: matchLabels: role: mongo environment: staging template: metadata: labels: role: mongo environment: staging replicaset: MainRepSet spec: affinity: podAntiAffinity: # 添加 Pod 反親和性,將副本打散在不同的節點 preferredDuringSchedulingIgnoredDuringExecution: # 軟策略 - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: replicaset operator: In values: - MainRepSet topologyKey: kubernetes.io/hostname terminationGracePeriodSeconds: 10 serviceAccountName: mongo containers: - name: mongo image: mongo:5.0.8 command: - mongod - "--wiredTigerCacheSizeGB" - "0.25" - "--bind_ip" - "0.0.0.0" - "--replSet" - MainRepSet #- "--smallfiles" #- "--noprealloc" ports: - containerPort: 27017 volumeMounts: - name: mongo-data mountPath: /data/db resources: requests: cpu: 1 memory: 2Gi - name: mongo-sidecar image: cvallance/mongo-k8s-sidecar env: - name: MONGO_SIDECAR_POD_LABELS value: "role=mongo,environment=staging" - name: KUBE_NAMESPACE value: "mongo" - name: KUBERNETES_MONGO_SERVICE_NAME value: "mongo" volumeClaimTemplates: - metadata: name: mongo-data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: gluster-heketi-storageclass # 提供一個可用的 Storageclass resources: requests: storage: 1Gi
這裡我們給 Mongo 的 Pod 添加了一個 sidecar 容器,主要用於副本集的配置,該 sidecar 會每5s檢查一次新成員。通過幾個環境變量配置指定了 Pod 的標籤、命名空間和 Service。
為了保證應用的穩定性,我們通過 podAntiAffinity 指定了 Pod 的反親和性,這樣可以保證不會有兩個副本出現在同一個節點上。
此外需要提供一個可用的 StorageClass,這樣可以保證不同的副本數據持久化到不同的 PV。
直接運行上面的兩個資源清單文件即可:
$ kubectl apply -f hostvm-ds.yaml
$ kubectl apply -f mongo.yaml
查看狀態
當然如果想從集群外部訪問 mongo,可以為這些 Pod 部署一些內部的負載均衡器,或者使用 nginx-ingress、traefik 這些 Ingress 控制器來創建 Ingress 暴露出去。
我們集群中部署了 Traefik v2.7 版本,該版本是支持 TCP 服務的,我們可以通過創建一個如下所示的 IngressRoute 對象來暴露 mongo 服務:
# ingressroute-tcp.yaml apiVersion: traefik.containo.us/v1alpha1 kind: IngressRouteTCP metadata: name: mongodb-tcp namespace: mongo spec: entryPoints: - tcp # 需要通过静态方式开启 mongo 的入口点 routes: - match: HostSNI(`*`) services: - name: mongo port: 27017
kubectl apply -f ingressroute-tcp.yaml -n mongo
設定密碼
##進入mongodb
kubectl -n mongo exec -ti mongo-0 -- mongo admin Defaulted container "mongo" out of: mongo, mongo-sidecar MongoDB shell version v5.0.8 connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("f99f8e06-c8e0-4e4d-8dba-46316285e737") } MongoDB server version: 5.0.8 ================ Warning: the "mongo" shell has been superseded by "mongosh", which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in an upcoming release. For installation instructions, see https://docs.mongodb.com/mongodb-shell/install/ ================ Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see https://docs.mongodb.com/ Questions? Try the MongoDB Developer Community Forums https://community.mongodb.com --- The server generated these startup warnings when booting: 2022-06-01T03:29:34.799+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2022-06-01T03:29:34.799+00:00: You are running this process as the root user, which is not recommended 2022-06-01T03:29:34.799+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- MainRepSet:SECONDARY>
##設定密碼
> db.createUser({ user:'admin',pwd:'910921',roles:[ { role:'userAdminAnyDatabase', db: 'admin'}]}); Successfully added user: { "user" : "admin", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] } > db.auth('admin', '910921') 1 > db.changeUserPassword("admin","390191");
Hits: 68