ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

达梦数据库在Docker与Kubernetes中开启SSL加密连接配置实践

达梦数据库在Docker与Kubernetes中开启SSL加密连接配置实践 1. 从“裸机直连”到“容器加密连接”的转变先说一个我最近真实遇到的场景业务系统做容器化迁移数据库还是达梦DM8开发环境放在Docker里生产环境跑在Kubernetes上。迁移本来挺顺畅结果安全审计一过要求数据库连接必须走SSL加密——不对业务流量加密就上线这道坎过不去。当时第一反应是达梦开SSL这事在裸机上都得折腾一阵子现在还要分Docker和K8s两套环境来搞是不是会很麻烦真上手之后发现核心套路其实是相通的证书文件准备 达梦服务端开启SSL参数 容器/集群挂载证书并重启实例。区别只在于“证书怎么放进去”“配置怎么传进去”“实例怎么起”。这篇文章我就把这套流程完整拆开讲一遍。适合三类人看正在做达梦容器化改造的运维被安全合规逼着开SSL的开发还有刚接触达梦、想搞清楚“容器里的数据库到底怎么配SSL”的新手。我会把背后的原理、每一步的操作、我踩过的坑一起写清楚。简单交代一下达梦开SSL的基本逻辑达梦支持在服务端启用SSL客户端连过来的时候通过证书做身份认证和传输加密。服务端需要准备好证书和私钥然后在达梦的配置文件dm.ini里把SSL相关开关和路径指过去重启实例生效。Docker和K8s干的事情本质上是把这个过程“容器化”——证书要么打进镜像、要么挂载进容器配置要么改ini文件、要么靠环境变量注入。2. 前置梳理整体配置思路与关键技术决策2.1 为什么证书准备是整条链路的地基先理解一个概念TLS/SSL握手时客户端要验证服务端证书服务端也可以要求客户端提供证书。达梦的SSL连接里常见做法是准备三类材料CA根证书、服务器证书、客户端证书。服务器证书给达梦用CA证书用来签名和校验客户端证书用于客户端侧的身份认证。这一步没有做好后面Docker、K8s配置再熟练也白搭。证书有效期、证书格式、证书的CN/SAN字段都会直接影响连接成败。我在项目里遇到过好几次“服务端配置完全没问题但客户端就是报证书校验失败”最后全是证书签发字段的问题。2.2 容器环境下的配置决策挂载、注入还是打进镜像明确一个核心决策不要把证书和配置文件写死在镜像里。镜像要尽量保持“一份镜像多种环境可跑”的不可变基础设施理念。证书属于敏感信息且有过期天数写死在镜像里意味着每次证书变更都要重新build镜像完全不现实。推荐的做法是环境证书存放方式配置文件处理方式Dockervolume挂载证书目录ini文件通过挂载或环境变量调整修改dm.ini后重启容器K8sSecret保存证书内容挂载到容器内部路径ConfigMap管理dm.ini差异项环境变量控制DB名等非敏感参数这样证书文件只在部署层出现Docker下是宿主机目录K8s下是Secret资源镜像本身无状态。2.3 数据目录的持久化考量这里有个容易被忽略的细节达梦的数据目录和配置目录通常绑定在一起。在裸机上dm.ini放在数据目录里容器里如果把数据目录做成volume那dm.ini天然是被持久化的。这意味着我们修改了ini配置文件后如果容器重建配置还在。但这同时带来一个“副作用”在K8s里如果StatefulSet的PVC没删老的配置会覆盖新的期望状态更新时必须同时在PVC里的ini文件和应用层的ConfigMap上做改动。我更习惯的做法是数据目录只存数据对外暴露为PVC配置目录单独管理用ConfigMap挂载覆盖——这样升级配置与数据隔离便于回滚。3. 环境准备与证书生成十分钟搞定一套测试证书3.1 OpenSSL生成证书的基本流程证书生成这一步建议用OpenSSL操作。生产环境如果用企业CA或第三方CA签发直接拿到证书文件即可测试环境或内网环境自己搭一套CA链是最快的。以最简的三件套为例CA证书、服务器证书、服务器私钥。建议证书信息里CN字段与后续访问数据库的主机名或IP匹配否则很多客户端在验证时会因主机名不匹配直接报错。命令行示例我实际用过的# 1. 生成CA私钥和自签名CA证书 openssl req -new -x509 -days 3650 -nodes \ -keyout ca.key -out ca.pem \ -subj /CNDM-CA # 2. 生成服务器私钥和证书签名请求 openssl req -new -nodes \ -keyout server.key -out server.csr \ -subj /CNdm-server # 3. 用CA签发服务器证书 openssl x509 -req -days 3650 \ -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial \ -out server.pem然后我会把私钥密码处理掉或妥善保管。比如转换成无密码私钥便于容器里自动加载但这仅限于测试环境生产环境务必使用密码保护并配合密钥管理。3.2 达梦服务端需要的证书格式达梦对于证书文件格式有一定要求。不同版本对PEM和DER的支持不完全一致我建议先确认版本支持的格式再决定是否做格式转换。一个常见转换是把PEM转成DERopenssl x509 -in server.pem -outform DER -out server.der也有人直接把.pem后缀文件放到达梦配置指定路径下就能直接用。官方文档里提到的证书目录内通常约定服务端证书和客户端证书各放一个文件文件名有固定要求。我的建议是翻一下对应版本安装包里的示例配置文件一般在/opt/dmdbms/data或示例目录下里面有SSL相关参数模板照着填不会错。3.3 证书文件的安全管理证书文件本质上是敏感资产。私钥泄露等同于连接认证体系崩盘任何环境都不该把私钥提交进Git仓库。Docker环境下我习惯把证书目录权限设为600K8s里则放到Secret并设置严格的RBAC访问。提示Docker挂载时宿主机证书目录的属主和属组要能被容器内达梦进程读取。特别是用了非root启动的镜像时经常遇到“文件存在但打不开”的问题本质就是权限不够。可以先chmod 644公钥证书私钥给400或600同时确保属主正确。4. Docker环境下达梦开启SSL的完整配置流程4.1 先跑一个最简达梦容器Docker部署达梦的常规动作是跑一个DM8容器把数据目录挂出来端口映射出去。假设镜像名为dm8:dm8_2025最基本的启动方式如下docker run -d --name dm8-ssl \ -p 5236:5236 \ -v /data/dm8:/opt/dmdbms/data \ -e DB_NAMEDMDB01 \ dm8:dm8_2025正常跑起来后用disql或数据库客户端连一下能通就说明基础环境没问题。这里的/opt/dmdbms/data是达梦镜像内默认的数据与配置目录实际路径以镜像申明为准。4.2 修改dm.ini开启SSL接下来是关键一步。先进入容器找到配置文件位置docker exec -it dm8-ssl bash find / -name dm.ini 2/dev/null一般路径类似/opt/dmdbms/data/DAMENG/dm.ini。用vi或sed修改把SSL相关参数打开。参考配置如下ENABLE_SSL 1 SSL_PATH /opt/dmdbms/data/ssl SSL_PWD your_password需要注意的是不同达梦版本的参数名和取值范围可能不同。有的版本只需要ENABLE_SSL和SSL_PATH有的还支持SSL_TYPE。SSL_PATH指到证书所在目录如/opt/dmdbms/data/ssl里面放服务器证书和客户端证书。SSL_PWD是私钥口令如果证书私钥没设密码这项可以留空或省略。4.3 证书挂载进容器证书文件不要手动docker cp进容器因为容器一删证书就没了。用挂载才是持久之道。先把证书放到宿主机目录/data/dm8/certs与数据目录同级然后重新启动容器docker stop dm8-ssl docker rm dm8-ssl docker run -d --name dm8-ssl \ -p 5236:5236 \ -v /data/dm8:/opt/dmdbms/data \ -v /data/dm8/certs:/opt/dmdbms/data/ssl \ dm8:dm8_2025这里有个叠加技巧数据目录整个挂载到/opt/dmdbms/data证书目录作为数据目录的子目录再单独挂到/opt/dmdbms/data/ssl。这种做法在Docker里完全可行证书目录与数据目录分离备份和权限控制都方便。4.4 重启实例与连接自检改完dm.ini并挂载好证书后重启容器让配置生效。达梦容器内部重启实例有两种思路重启整个容器或者进入容器用DmServiceDMSERVER restart之类的服务命令。我倾向直接重启容器简单粗暴且与环境隔离。docker restart dm8-ssl docker logs dm8-ssl --tail 50看日志里有没有SSL初始化失败的记录有就说明证书路径或文件格式不对。然后从宿主机用达梦客户端工具试连一次disql SYSDBA/SYSDBAlocalhost:5236如果基础版客户端默认不走SSL需要指定SSL参数如果达梦服务端强制SSL客户端不带SSL会直接连接失败。4.5 Docker Compose方式管理证书与配置如果项目用Compose管理配置更集中。写一个docker-compose.yml核心片段长这样services: dm8: image: dm8:dm8_2025 container_name: dm8-ssl ports: - 5236:5236 volumes: - /data/dm8:/opt/dmdbms/data - /data/dm8/certs:/opt/dmdbms/data/ssl environment: - DB_NAMEDMDB01后续证书更新直接替换/data/dm8/certs里的文件然后docker-compose restart。优点是配置所见即所得团队成员都能看懂缺点是证书和ini的最终状态不完全受Compose控制换机器重建时要记得把证书目录也带去。5. Kubernetes环境下达梦数据库SSL连接配置5.1 达梦在K8s里的部署形态选择到K8s这一步先想清楚达梦以什么形态跑。测试环境用Deployment挂PVC足够生产环境我推荐StatefulSet因为数据库是有状态服务需要稳定的网络标识stable network identity和独立的存储卷。这里要特别说一句达梦官方并没有像某些数据库那样提供完整的K8s Operator因此StatefulSet手动管理证书是目前最常见的原生方式。网上热词里有“k8s operator案例”意思是说如果你完全不想手动管理证书可以考虑在Operator框架里做扩展但对于多数场景SVStatefulSetSecretConfigMap三板斧已经够用。5.2 用Secret保存证书文件证书私钥属于敏感数据在K8s里应放进Secret。可以用kubectl create secret从文件直接生成也可以用YAML管理。kubectl create secret generic dm8-ssl-certs \ --from-fileserver.pem/data/dm8/certs/server.pem \ --from-fileserver.key/data/dm8/certs/server.key \ --from-fileca.pem/data/dm8/certs/ca.pem \ -n dm8Secret底层会做Base64编码保存的是证书文本内容。如果证书文件较大或格式特殊也可以用--from-file直接挂整个目录。但要注意Secret的默认大小限制是1MiB证书文件通常远小于这个值没问题。5.3 用ConfigMap管理dm.ini差异项证书之外dm.ini里还有非敏感配置项比如ENABLE_SSL、SSL_PATH。虽然这些项也可以直接写进Secret但按职责分离原则非敏感配置放ConfigMap更清晰。apiVersion: v1 kind: ConfigMap metadata: name: dm8-config namespace: dm8 data: dm.ini: | ENABLE_SSL 1 SSL_PATH /opt/dmdbms/data/ssl如果不想整个dm.ini都用ConfigMap覆盖也可以把ConfigMap挂载成单独文件再把路径指过去。但达梦读取的是dm.ini里的SSL_PATH所以要么直接改ini要么通过环境变量让启动脚本改ini。实际操作中我更喜欢让ConfigMap保存一个完整的dm.ini模板这样所有配置项一目了然也不容易出现INI中某个参数漏掉导致启动异常。5.4 StatefulSet部署达梦并挂载证书StatefulSet的编排文件核心部分如下apiVersion: apps/v1 kind: StatefulSet metadata: name: dm8 namespace: dm8 spec: serviceName: dm8-headless replicas: 1 selector: matchLabels: app: dm8 template: metadata: labels: app: dm8 spec: containers: - name: dm8 image: dm8:dm8_2025 ports: - containerPort: 5236 volumeMounts: - name: data mountPath: /opt/dmdbms/data - name: ssl-certs mountPath: /opt/dmdbms/data/ssl readOnly: true - name: config mountPath: /opt/dmdbms/data/config env: - name: DB_NAME value: DMDB01 volumes: - name: ssl-certs secret: secretName: dm8-ssl-certs - name: config configMap: name: dm8-config volumeClaimTemplates: - metadata: name: data spec: accessModes: [ReadWriteOnce] resources: requests: storage: 50Gi注意几个关键点证书目录用readOnly: true容器运行期间不应改动私钥文件。ConfigMap挂载的目录不要覆盖达梦原本的数据目录我单独挂到/opt/dmdbms/data/config然后在dm.ini中把配置项的路径指过去——如果全部沿用数据目录里的iniConfigMap就白挂了。如果确实想用ConfigMap整个覆盖dm.ini那mountPath要精确到文件级别如mountPath: /opt/dmdbms/data/DAMENG/dm.ini, subPath: dm.ini。5.5 让应用通过Service访问达梦SSL端口配置好Pod后还需要Service暴露访问入口。注意SSL端口的TCP服务无需额外特殊配置Service正常转发即可。以下是最常规的ServiceapiVersion: v1 kind: Service metadata: name: dm8 namespace: dm8 spec: selector: app: dm8 ports: - port: 5236 targetPort: 5236 name: dm-ssl type: ClusterIP若需集群外部访问再叠加NodePort或Ingress不必对SSL本身做额外处理。唯一要注意达梦连接用的应用在构建数据库URL时要把SSL开关打开并指定信任证书路径。5.6 K8s证书更新流程证书快过期时更新流程要提前设计好。我先说比较笨但稳妥的做法生成新证书文件到本地临时目录。用kubectl create secret ... --dry-runclient -o yaml | kubectl apply -f -滚动更新Secret。删除旧的DaemonSet Pod或StatefulSet滚动更新让Pod重建时挂载到新Secret。验证连接。如果追求不停机更新可以逐步滚动将StatefulSetupdateStrategy设为RollingUpdate依次替换Pod。不过达梦实例重启必然有短暂连接中断所以更推荐在维护窗口做。加一层 readinessProbe 指向一个SSL连接的TCP检查端口有助于滚动时K8s自动摘除不健康的旧Pod。6. 客户端连接验证与常见故障排查6.1 使用disql验证SSL连接服务端开启SSL后客户端如果不上证书可信配置不同客户端的表现不一样。disql一般需要指定SSL相关选项或依赖环境变量。我的速查做法先在容器内部用disql不带SSL试一次再用带SSL参数试一次对比报错。# 不带SSL连接服务端强制SSL时应该报错 disql SYSDBA/SYSDBAlocalhost:5236 # 带SSL连接参数以实际版本帮助为准 disql SYSDBA/SYSDBAlocalhost:5236 ssl_typetcp:ssl如果对参数不熟悉先执行help ssl查看当前版本支持的关键字。这种问题没有统一答案但思路是固定的。6.2 JDBC和Navicat等客户端连接Java应用连接达梦JDBC URL通常长这样jdbc:dm://ip:5236?compatibleModeoraclessltruetrustServerCertificatetrue注意不同驱动的参数名区分大小写且并不一致可能有的驱动认sslEnable有的认ssl。我的建议是查驱动包里的连接参数说明——这是最容易出错也最容易解决的一环。Navicat连达梦时SSL开关一般在连接属性的高级设置里。证书来源要与服务端CA一致如果服务端证书由自建CA签发本地要导入CA根证书否则会报“服务器证书不受信任”。6.3 高频踩坑证书、io、K8s挂载我把自己实际遇到的故障列成一张排查表方便你定位现象可能原因解决思路服务端启动失败日志提到load certificate证书路径或格式不对检查SSL_PATH目录下文件是否存在格式是否与INI规定的格式一致客户端报证书校验失败CN与访问主机名不匹配或CA未受信重新签发CN匹配的证书或导入CA到客户端信任库Linux容器内报permission denied证书文件权限过大或属主不对修改文件权限为600或644容器内用户UID一致K8s挂载Secret后文件是目录结构subPath未使用Secret整体挂载目录确认文件挂载是否用了subPath必要时调整mountPath重启容器后SSL配置丢失修改的ini在临时层未持久化修改数据目录内的dm.ini确认数据目录挂载了PVC/宿主机目录连接时提示“connection reset”服务端SSL配置不完整或证书过期查看dm.ini相关参数检查证书有效期限6.4 上线前必做的三个检查我在所有环境踩过坑后总结出三个上线前必做动作一是证书有效期检查。写个脚本定时查证书到期日或设置监控告警到期前30天提醒。证书过期是最低调的故障——平时一切正常某天凌晨突然连不上。二是做无证书环境连接测试。把客户端证书路径指错确认连接确实失败——如果配置错了还是能连成功说明SSL根本没生效别让这种情况悄悄上线。三是查看达梦日志关键字。达梦日志里SSL相关初始化信息一般会打出ssl字样通过检索dm_DMSERVER_*.log可以确认是否成功加载了证书和加密算法。这点比任何“看起来正常”都靠谱。7. 实操心得从“能连”到“稳定连”的几个细节讲到最后分享几个我在项目中沉淀下来的经验。第一证书目录和初始化脚本要整体纳入运维资产。Docker环境下我习惯在宿主机/opt/dm8/{data,certs,backup}三个目录平铺K8s环境下证书进Secret、配置文件进ConfigMap。任何一键重建流程都要保证证书和配置能自动回来不然宕机恢复时会因为找不到证书而扩大故障时间。第二SSL开启后达梦的连接性能会有一定损耗。内网高并发场景下我用通用型应用做过粗略对比开启SSL后新建连接耗时可能增加但长连接、连接池复用得当的话整体影响可以控制在可接受范围。所以不要“为了SSL而SSL”明确合规或安全需求后再动手。第三尽量在容器化改造的第一步就规划SSL而不是等系统全跑起来再补。很多项目先裸机跑得好好的然后要求迁移到K8s又同时要求开SSL两步叠加排查起来头大。先把SSL在裸机达梦上跑通再容器化把变量拆到最小你会省掉大量调试时间。第四从维护角度看证书的自动化管理值得投入。等Kubernetes环境多了手动人肉更新证书必然出事。可以拿脚本或Pipeline在证书到期前自动重建Secret并滚动重启。这个扩展方向如果你有精力建议尽早做。
返回列表