Skip to content

DM Docker/K8s部署

容器化部署优势

  • 环境一致性:容器封装了所有依赖,确保开发、测试和生产环境一致
  • 快速部署:基于镜像快速启动数据库实例,减少部署时间
  • 资源隔离:容器之间资源隔离,提高安全性和可靠性
  • 弹性扩展:结合 K8s 实现自动化扩缩容,适应业务需求变化
  • 简化管理:通过容器编排工具简化集群管理和维护
  • 版本控制:镜像版本化管理,便于回滚和升级

部署方案选择

部署方案适用场景优势
Docker 单机开发测试、小规模生产简单易用,快速部署
K8s 单节点测试环境、小规模生产具备 K8s 管理能力,资源利用率高
K8s 集群大规模生产环境高可用、弹性扩展、自动化管理

Docker 部署

镜像准备

使用官方镜像

DM 数据库提供官方 Docker 镜像,可从达梦官方仓库或 Docker Hub 获取。

bash
# 从达梦官方仓库拉取镜像
docker pull dameng/dm8:latest

# 或从 Docker Hub 拉取
docker pull dmdbms/dm8:latest

自定义构建镜像

如果需要自定义配置,可以基于官方镜像构建自定义镜像。

Dockerfile 示例

dockerfile
FROM dameng/dm8:latest

# 设置环境变量
ENV DM_HOME=/opt/dmdbms
ENV PATH=$DM_HOME/bin:$PATH

# 复制自定义配置文件
COPY dm.ini $DM_HOME/data/DAMENG/
COPY dmarch.ini $DM_HOME/data/DAMENG/

# 设置权限
RUN chown -R dmdba:dinstall $DM_HOME/data/DAMENG/

# 暴露端口
EXPOSE 5236

# 启动命令
CMD ["/opt/dmdbms/bin/dmserver", "/opt/dmdbms/data/DAMENG/dm.ini"]

构建镜像

bash
docker build -t my-dm8:latest .

运行 Docker 容器

基本运行

bash
docker run -d \
  --name dm8 \
  -p 5236:5236 \
  -v /data/dm8/data:/opt/dmdbms/data \
  -v /data/dm8/log:/opt/dmdbms/log \
  -e PAGE_SIZE=16 \
  -e EXTENT_SIZE=32 \
  dameng/dm8:latest

挂载数据卷

为了数据持久化,建议挂载数据卷:

bash
# 创建数据卷
docker volume create dm8-data
docker volume create dm8-log

# 运行容器
docker run -d \
  --name dm8 \
  -p 5236:5236 \
  -v dm8-data:/opt/dmdbms/data \
  -v dm8-log:/opt/dmdbms/log \
  dameng/dm8:latest

使用环境变量配置

DM 容器支持通过环境变量配置数据库实例:

bash
docker run -d \
  --name dm8 \
  -p 5236:5236 \
  -v dm8-data:/opt/dmdbms/data \
  -e DB_NAME=DAMENG \
  -e INSTANCE_NAME=DMSERVER \
  -e PORT_NUM=5236 \
  -e BUFFER=2048 \
  -e MAX_SESSIONS=200 \
  dameng/dm8:latest

Docker 容器管理

查看容器状态

bash
docker ps -a | grep dm8
docker logs -f dm8

进入容器

bash
docker exec -it dm8 /bin/bash

停止和启动容器

bash
docker stop dm8
docker start dm8

备份和恢复

bash
# 从容器中导出备份文件
docker cp dm8:/opt/dmdbms/backup/full_backup.bak /data/backup/

# 向容器中导入备份文件
docker cp /data/backup/full_backup.bak dm8:/opt/dmdbms/backup/

Kubernetes 部署

部署准备

环境要求

  • Kubernetes 集群版本 1.18 及以上
  • 集群节点具有足够的 CPU、内存和存储资源
  • 配置了持久化存储类(StorageClass)
  • 安装了 kubectl 命令行工具

命名空间创建

bash
kubectl create namespace dmdb

持久化存储配置

StorageClass 配置

DM 数据库需要高性能持久化存储,建议使用 SSD 存储。以下是 NFS 和 Ceph RBD 存储类示例:

NFS StorageClass 示例

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
provisioner: k8s.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

Ceph RBD StorageClass 示例

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:
  clusterID: ceph-cluster-id
  pool: rbd
  imageFormat: "2"
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: ceph-secret
  csi.storage.k8s.io/provisioner-secret-namespace: dmdb
  csi.storage.k8s.io/node-stage-secret-name: ceph-secret
  csi.storage.k8s.io/node-stage-secret-namespace: dmdb
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: Immediate

单实例部署

Deployment 配置

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dm8-single
  namespace: dmdb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dm8-single
  template:
    metadata:
      labels:
        app: dm8-single
    spec:
      containers:
      - name: dm8
        image: dameng/dm8:latest
        ports:
        - containerPort: 5236
        env:
        - name: DB_NAME
          value: "DAMENG"
        - name: INSTANCE_NAME
          value: "DMSERVER"
        - name: PORT_NUM
          value: "5236"
        - name: BUFFER
          value: "2048"
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "8Gi"
        volumeMounts:
        - name: dm8-data
          mountPath: /opt/dmdbms/data
        - name: dm8-log
          mountPath: /opt/dmdbms/log
      volumes:
      - name: dm8-data
        persistentVolumeClaim:
          claimName: dm8-data-pvc
      - name: dm8-log
        persistentVolumeClaim:
          claimName: dm8-log-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dm8-data-pvc
  namespace: dmdb
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: ceph-rbd
  resources:
    requests:
      storage: 50Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dm8-log-pvc
  namespace: dmdb
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: ceph-rbd
  resources:
    requests:
      storage: 20Gi
---
apiVersion: v1
kind: Service
metadata:
  name: dm8-single-service
  namespace: dmdb
spec:
  selector:
    app: dm8-single
  ports:
  - name: dm8-port
    port: 5236
    targetPort: 5236
  type: ClusterIP

部署命令

bash
kubectl apply -f dm8-single-deployment.yaml

高可用部署

DMDSC 集群部署

DMDSC(达梦共享存储集群)是 DM 数据库的高可用解决方案,支持在 K8s 上部署。

部署架构

  • 2 个 DMDSC 实例
  • 1 个 DMCSS(集群同步服务)
  • 1 个 DMASM(共享存储管理)
  • 共享存储(使用 Ceph 或 NFS)

部署步骤

  1. 创建共享存储

    yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: dm-shared-pvc
      namespace: dmdb
    spec:
      accessModes:
      - ReadWriteMany
      storageClassName: nfs-storage
      resources:
        requests:
          storage: 100Gi
  2. 部署 DMCSS

    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dmcss
      namespace: dmdb
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: dmcss
      template:
        metadata:
          labels:
            app: dmcss
        spec:
          containers:
          - name: dmcss
            image: dameng/dm8:latest
            command: ["/opt/dmdbms/bin/dmcss", "PATH=/opt/dmdbms/bin", "DM_HOME=/opt/dmdbms"]
            volumeMounts:
            - name: dm-shared
              mountPath: /opt/dmdbms/data
          volumes:
          - name: dm-shared
            persistentVolumeClaim:
              claimName: dm-shared-pvc
  3. 部署 DMASM

    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dmasm
      namespace: dmdb
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: dmasm
      template:
        metadata:
          labels:
            app: dmasm
        spec:
          containers:
          - name: dmasm
            image: dameng/dm8:latest
            command: ["/opt/dmdbms/bin/dmasmsvr", "PATH=/opt/dmdbms/bin", "DM_HOME=/opt/dmdbms"]
            volumeMounts:
            - name: dm-shared
              mountPath: /opt/dmdbms/data
          volumes:
          - name: dm-shared
            persistentVolumeClaim:
              claimName: dm-shared-pvc
  4. 部署 DMDSC 实例

    yaml
    # DMDSC 实例 1
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: dmscs-1
      namespace: dmdb
    spec:
      serviceName: "dmscs"
      replicas: 1
      selector:
        matchLabels:
          app: dmscs-1
      template:
        metadata:
          labels:
            app: dmscs-1
        spec:
          containers:
          - name: dmscs-1
            image: dameng/dm8:latest
            command: ["/opt/dmdbms/bin/dmserver", "/opt/dmdbms/data/DAMENG/dm.ini", "dsc", "1"]
            volumeMounts:
            - name: dm-shared
              mountPath: /opt/dmdbms/data
          volumes:
          - name: dm-shared
            persistentVolumeClaim:
              claimName: dm-shared-pvc
  5. 创建服务

    yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: dmscs-service
      namespace: dmdb
    spec:
      selector:
        app: dmscs
      ports:
      - name: dm8-port
        port: 5236
        targetPort: 5236
      type: ClusterIP

StatefulSet 部署

对于需要稳定网络标识符和持久存储的应用,建议使用 StatefulSet 部署。

StatefulSet 配置示例

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: dm8-statefulset
  namespace: dmdb
spec:
  serviceName: "dm8"
  replicas: 2
  selector:
    matchLabels:
      app: dm8
  template:
    metadata:
      labels:
        app: dm8
    spec:
      containers:
      - name: dm8
        image: dameng/dm8:latest
        ports:
        - containerPort: 5236
        env:
        - name: DB_NAME
          value: "DAMENG"
        - name: INSTANCE_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: PORT_NUM
          value: "5236"
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "8Gi"
        volumeMounts:
        - name: dm8-data
          mountPath: /opt/dmdbms/data
        - name: dm8-log
          mountPath: /opt/dmdbms/log
  volumeClaimTemplates:
  - metadata:
      name: dm8-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "ceph-rbd"
      resources:
        requests:
          storage: 50Gi
  - metadata:
      name: dm8-log
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "ceph-rbd"
      resources:
        requests:
          storage: 20Gi
---
apiVersion: v1
kind: Service
metadata:
  name: dm8
  namespace: dmdb
spec:
  selector:
    app: dm8
  clusterIP: None
  ports:
  - name: dm8-port
    port: 5236
    targetPort: 5236

K8s 管理与监控

配置管理

ConfigMap 管理配置文件

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: dm8-config
  namespace: dmdb
data:
  dm.ini: |
    DB_NAME = DAMENG
    INSTANCE_NAME = DMSERVER
    PORT_NUM = 5236
    BUFFER = 2048
    MAX_SESSIONS = 200
  dmarch.ini: |
    [ARCHIVE_LOCAL1]
    ARCH_TYPE = LOCAL
    ARCH_DEST = /opt/dmdbms/log/arch
    ARCH_FILE_SIZE = 128
    ARCH_SPACE_LIMIT = 0

使用 ConfigMap

yaml
volumeMounts:
- name: dm8-config
  mountPath: /opt/dmdbms/data/DAMENG/dm.ini
  subPath: dm.ini
- name: dm8-config
  mountPath: /opt/dmdbms/data/DAMENG/dmarch.ini
  subPath: dmarch.ini
volumes:
- name: dm8-config
  configMap:
    name: dm8-config

Secret 管理敏感信息

yaml
apiVersion: v1
kind: Secret
metadata:
  name: dm8-secret
  namespace: dmdb
type: Opaque
data:
  sys_password: YWRtaW4xMjM=  # base64 编码的 "admin123"
  user_password: dXNlcjEyMw==  # base64 编码的 "user123"

使用 Secret

yaml
env:
- name: SYS_PASSWORD
  valueFrom:
    secretKeyRef:
      name: dm8-secret
      key: sys_password

监控与告警

Prometheus 监控

DM 数据库支持 Prometheus 监控,可通过 Exporter 暴露监控指标。

部署 Exporter

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dm8-exporter
  namespace: dmdb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dm8-exporter
  template:
    metadata:
      labels:
        app: dm8-exporter
    spec:
      containers:
      - name: dm8-exporter
        image: dmdbms/dm8-exporter:latest
        ports:
        - containerPort: 9161
        env:
        - name: DM_HOST
          value: "dm8-single-service"
        - name: DM_PORT
          value: "5236"
        - name: DM_USER
          value: "SYSDBA"
        - name: DM_PASSWORD
          valueFrom:
            secretKeyRef:
              name: dm8-secret
              key: sys_password
---
apiVersion: v1
kind: Service
metadata:
  name: dm8-exporter-service
  namespace: dmdb
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9161"
    prometheus.io/path: "/metrics"
spec:
  selector:
    app: dm8-exporter
  ports:
  - name: metrics
    port: 9161
    targetPort: 9161
  type: ClusterIP

Grafana 可视化

配置 Grafana 数据源指向 Prometheus,导入 DM 数据库监控面板,实现监控数据可视化。

备份与恢复

容器内备份

bash
# 进入容器
docker exec -it dm8 /bin/bash

# 执行备份
cd /opt/dmdbms/bin
./dmrman CTLSTMT="BACKUP DATABASE '/opt/dmdbms/data/DAMENG/dm.ini' FULL TO backup1 BACKUPSET '/opt/dmdbms/backup/backup1'"

K8s 中备份

使用 CronJob 定期执行备份:

yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: dm8-backup
  namespace: dmdb
spec:
  schedule: "0 2 * * *"  # 每天凌晨 2 点执行
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: dm8-backup
            image: dameng/dm8:latest
            command: ["/bin/bash", "-c"]
            args: ["cd /opt/dmdbms/bin && ./dmrman CTLSTMT=\"BACKUP DATABASE '/opt/dmdbms/data/DAMENG/dm.ini' FULL TO backup_$(date +\\%Y\\%m\\%d) BACKUPSET '/opt/dmdbms/backup/backup_$(date +\\%Y\\%m\\%d)'\""]
            volumeMounts:
            - name: dm8-data
              mountPath: /opt/dmdbms/data
            - name: dm8-backup
              mountPath: /opt/dmdbms/backup
          restartPolicy: OnFailure
          volumes:
          - name: dm8-data
            persistentVolumeClaim:
              claimName: dm8-data-pvc
          - name: dm8-backup
            persistentVolumeClaim:
              claimName: dm8-backup-pvc

升级与回滚

Docker 升级

bash
# 停止旧容器
docker stop dm8

# 备份数据
docker cp dm8:/opt/dmdbms/data /data/backup/

# 拉取新镜像
docker pull dameng/dm8:new-version

# 启动新容器
docker run -d \
  --name dm8-new \
  -p 5236:5236 \
  -v /data/dm8/data:/opt/dmdbms/data \
  dameng/dm8:new-version

# 验证新容器正常运行后删除旧容器
docker rm dm8

K8s 升级

滚动升级

bash
# 更新镜像版本
kubectl set image deployment/dm8-single dm8=dameng/dm8:new-version -n dmdb

# 查看升级状态
kubectl rollout status deployment/dm8-single -n dmdb

回滚

bash
# 查看历史版本
kubectl rollout history deployment/dm8-single -n dmdb

# 回滚到上一版本
kubectl rollout undo deployment/dm8-single -n dmdb

# 回滚到指定版本
kubectl rollout undo deployment/dm8-single --to-revision=2 -n dmdb

最佳实践

资源配置

  • CPU:根据实例规模和负载设置,建议每个实例分配 2-8 核
  • 内存:建议设置为物理内存的 40%-60%,至少 4GB
  • 存储:使用 SSD 存储提高 I/O 性能,数据文件和日志文件分开存储

高可用性

  • 使用 StatefulSet 部署有状态应用
  • 配置 Pod 反亲和性,避免实例集中在同一节点
  • 结合 DMDataWatch 实现数据同步和自动故障切换
  • 配置合适的 livenessProbe 和 readinessProbe

安全性

  • 使用 Secret 管理敏感信息
  • 配置网络策略,限制 Pod 间通信
  • 启用数据库审计和日志功能
  • 定期更新镜像,修复安全漏洞

性能优化

  • 调整容器资源限制,避免资源争用
  • 配置合适的存储类,提高 I/O 性能
  • 优化数据库参数,如缓冲区大小、工作线程数等
  • 使用本地存储提高性能,如 K8s 的 local PV

监控与告警

  • 部署 Prometheus 和 Grafana 监控体系
  • 配置关键指标告警,如 CPU 使用率、内存使用率、I/O 等待时间等
  • 定期分析监控数据,优化配置和性能

版本差异

DM 7 vs DM 8 容器化支持

差异点DM 7DM 8
官方镜像支持有限完整
Dockerfile 示例简单完善
K8s 部署支持基础全面,包括 StatefulSet、DMDSC 等
监控集成有限支持 Prometheus 等监控工具
自动化部署脚本丰富

DM 8.1 新特性

  • 增强了容器化支持,提供更完善的 Dockerfile 和 K8s 配置示例
  • 支持更多云平台,如阿里云、腾讯云、华为云等
  • 优化了镜像大小,提高了启动速度
  • 增强了与 K8s 生态的集成,如 Operator 支持

常见问题(FAQ)

Q1: Docker 容器中如何访问 DM 数据库?

A1: 可以通过以下方式访问:

  1. 本地访问:docker exec -it dm8 /opt/dmdbms/bin/disql SYSDBA/SYSDBA@localhost:5236
  2. 外部访问:disql SYSDBA/SYSDBA@主机IP:映射端口

Q2: K8s 中如何配置持久化存储?

A2: 可以使用以下存储方案:

  1. 云平台提供的存储服务,如 EBS、EFS、云硬盘等
  2. 分布式存储,如 Ceph、GlusterFS 等
  3. NFS 存储,适合测试环境
  4. 本地存储,适合对性能要求高的场景

Q3: 如何在 K8s 中实现 DM 数据库的高可用?

A3: 可以通过以下方式实现:

  1. 使用 StatefulSet 部署,确保稳定的网络标识符和持久存储
  2. 配置 Pod 反亲和性,避免实例集中在同一节点
  3. 结合 DMDataWatch 或 DMDSC 实现数据同步和故障切换
  4. 配置合适的 livenessProbe 和 readinessProbe,及时发现和恢复故障

Q4: 如何监控 K8s 中的 DM 数据库?

A4: 可以通过以下方式监控:

  1. 使用 DM 数据库 Exporter 暴露监控指标
  2. 结合 Prometheus 收集监控数据
  3. 使用 Grafana 可视化监控数据
  4. 配置 Alertmanager 实现告警功能

Q5: 如何备份 K8s 中的 DM 数据库?

A5: 可以使用以下备份方式:

  1. 使用 CronJob 定期执行备份任务
  2. 使用 K8s 备份工具,如 Velero
  3. 结合云平台的存储快照功能
  4. 手动执行备份命令

Q6: 如何升级 K8s 中的 DM 数据库?

A6: 可以通过以下方式升级:

  1. 滚动升级:更新 Deployment 的镜像版本,K8s 会自动滚动更新 Pod
  2. 蓝绿部署:部署新版本,验证后切换流量
  3. 金丝雀发布:逐步将流量切换到新版本

Q7: 如何解决 DM 数据库容器启动失败?

A7: 可以通过以下方式排查:

  1. 查看容器日志:docker logs dm8kubectl logs pod/dm8-pod -n dmdb
  2. 检查配置文件是否正确
  3. 检查数据目录权限
  4. 检查资源是否充足
  5. 检查端口是否被占用

Q8: DM 数据库支持 K8s Operator 吗?

A8: DM 8.1 开始支持 K8s Operator,可以通过 Operator 实现自动化部署、管理和监控。

Q9: 如何优化 DM 数据库容器的性能?

A9: 可以通过以下方式优化:

  1. 调整容器资源限制,避免资源争用
  2. 使用 SSD 存储提高 I/O 性能
  3. 优化数据库参数,如缓冲区大小、工作线程数等
  4. 配置合适的存储类和卷类型
  5. 启用容器运行时优化,如 CRI-O、containerd 等

Q10: 如何在 Docker 中配置 DM 数据库的归档模式?

A10: 可以通过以下方式配置:

  1. 编写自定义 dmarch.ini 配置文件
  2. 使用 Dockerfile 将配置文件复制到容器中
  3. 启动容器时挂载配置文件
  4. 或使用环境变量配置归档参数