麒麟V10部署Docker与PolarDB:国产化环境实战指南
1. 项目缘起为什么要在麒麟V10上折腾Docker和PolarDB最近接手了一个内部数据服务平台的迁移项目目标环境是国产化的银河麒麟V10服务器版。团队之前的技术栈是跑在CentOS上的MySQL现在需要迁移到一个性能更强、更适合云原生架构的数据库上。PolarDB作为一款云原生数据库其存储计算分离、一写多读的特性非常吸引我们尤其适合我们这种读多写少的分析型业务场景。但问题来了官方文档和社区里大量的教程都是基于Ubuntu、CentOS这类主流发行版针对麒麟V10这种国产操作系统的实战分享少之又少。更棘手的是生产环境要求所有服务必须容器化部署这意味着我们得在麒麟V10上先把Docker这关过了才能去部署PolarDB。这个过程从环境检查、依赖解决到镜像拉取、容器配置每一步都可能遇到“特色”问题。我把这次从零开始在麒麟V10 SP1服务器版上成功部署Docker版PolarDB的完整过程以及踩过的坑和解决方案详细记录下来。如果你也在类似的国产化环境中进行技术选型与落地这篇内容或许能帮你省下不少排查时间。2. 麒麟V10服务器版基础环境审视与准备在麒麟V10上安装任何软件第一步永远不是直接执行yum install或apt-get而是彻底摸清系统底细。这能避免很多因版本、内核或架构不匹配导致的“玄学”问题。2.1 系统信息深度核查首先我们需要获取精确的系统信息。打开终端执行以下命令# 查看操作系统详细信息 cat /etc/os-release # 查看内核版本Docker对内核有要求 uname -r # 查看系统架构重要涉及软件包和镜像选择 arch以我这次的环境为例输出关键信息如下系统版本Kylin Linux Advanced Server release V10 (Sword)内核版本4.19.90-24.4.v2101.ky10.x86_64系统架构x86_64这里有一个关键点虽然统称“麒麟V10”但实际有桌面版和服务器版Server之分两者软件源和默认配置可能有差异。我们用的是服务器版。内核版本4.19满足Docker CE的最低要求通常需要3.10以上但需要注意一些较新的Docker功能可能需要更高内核。2.2 虚拟化支持检查Docker的基石Docker Desktop在Windows/Mac上安装失败常提示“Virtualization support not detected”在Linux服务器上虽然我们安装的是Docker Engine社区版但同样需要检查CPU虚拟化支持对于运行容器至关重要以及是否已启用。# 检查CPU是否支持虚拟化技术对于KVM等 egrep -c (vmx|svm) /proc/cpuinfo # 输出大于0即表示支持。如果为0可能需要进入BIOS开启虚拟化支持。 # 检查内核是否加载了必要的模块 lsmod | grep kvm # 对于x86架构通常应看到kvm_intel或kvm_amd模块。在标准的麒麟V10服务器版安装中只要不是特别定制的裁剪版这些支持通常是开启的。如果lsmod没有输出可以尝试手动加载sudo modprobe kvmIntel或sudo modprobe kvm_amd。并将其加入开机启动echo kvm | sudo tee /etc/modules-load.d/kvm.conf。2.3 清理旧版本与冲突软件这是一个非常关键但容易被忽略的步骤。系统可能预装了老旧的docker、docker-engine或containerd也可能存在与其他容器工具如podman的冲突。# 卸载旧版本的Docker及相关组件 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine \ podman \ runc -y # 清理残留文件和目录谨慎操作确保是你想删除的 sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd注意/var/lib/docker是Docker默认的数据根目录删除它会清除所有镜像、容器、卷和网络仅在全新安装或确认可清理时执行。如果是从旧版本升级通常不需要删除此目录。3. Docker引擎在麒麟V10上的三种安装路径对比麒麟V10基于CentOS/RHEL生态理论上可以使用yum安装。但实际操作中你会发现直接使用Docker官方源或CentOS的EPEL源可能会遇到依赖包版本冲突或找不到软件包的问题。下面我对比了三种方法并说明为什么最终选择了其中一种。3.1 方法一使用操作系统自带仓库最直接但可能版本旧sudo yum install docker -y优点简单依赖问题最少因为软件包是针对当前系统版本编译和测试的。缺点版本通常非常老旧可能是1.13.x这种古董版本缺少很多现代特性如Docker Compose V2 BuildKit等且安全更新不及时。结论不推荐用于生产环境仅适用于对版本无要求、快速验证的场景。3.2 方法二使用Docker官方CentOS源版本新但依赖是坎这是Docker官方推荐的方式步骤如下# 1. 安装yum工具包 sudo yum install -y yum-utils # 2. 添加Docker官方仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 3. 安装Docker引擎 sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y问题在麒麟V10上执行第3步时极大概率会报错提示containerd.io等包与系统已安装的runc、container-selinux等包存在版本冲突。这是因为官方仓库的包是基于最新版CentOS的库编译的与麒麟V10自带的软件库版本不兼容。解决方案尝试可以尝试先卸载冲突的系统包但可能引发其他系统组件的依赖问题风险较高。结论路径最正统但兼容性挑战最大适合喜欢折腾和解决依赖问题的用户。3.3 方法三下载RPM包手动安装最稳妥的折中方案我最终选择了这个方法。思路是从Docker官方为CentOS 8构建的RPM仓库中下载对应版本的RPM包然后手动解决依赖并安装。CentOS 8与麒麟V10的底层库相对更接近。访问仓库页面打开https://download.docker.com/linux/centos/8/x86_64/stable/Packages/注意如果麒麟V10基于CentOS 7则需将链接中的8改为7这需要根据/etc/os-release中的类似PLATFORM_IDplatform:el8信息判断麒麟V10通常对应el8。下载核心包我们需要下载至少以下三个包版本号请选取当时最新的稳定版以下以24.0.7为例docker-ce-24.0.7-1.el8.x86_64.rpmdocker-ce-cli-24.0.7-1.el8.x86_64.rpmcontainerd.io-1.6.21-3.1.el8.x86_64.rpm你也可以使用wget在终端直接下载wget https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-ce-24.0.7-1.el8.x86_64.rpm wget https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-ce-cli-24.0.7-1.el8.x86_64.rpm wget https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.6.21-3.1.el8.x86_64.rpm手动安装sudo yum localinstall ./*.rpm -y命令yum localinstall会自动处理这些RPM包之间的依赖关系并尝试从系统现有仓库中解决与系统其他组件的依赖。如果遇到缺少的依赖它会提示你你可以根据提示手动从麒麟V10的官方源或EPEL源需先安装epel-release中安装所需依赖包。优点版本较新可控避免了官方源中最新包与系统环境的剧烈冲突通过yum解决依赖相对安全。缺点需要手动寻找和下载包更新时需要重复此过程。结论这是在“版本新”和“系统稳”之间一个很好的平衡点也是我在生产环境采用的方式。安装完成后启动Docker并设置开机自启sudo systemctl start docker sudo systemctl enable docker验证安装sudo docker run hello-world。如果能看到欢迎信息说明Docker引擎已正常运行。4. Docker环境优化与镜像源配置安装成功只是第一步要让Docker在国产化环境下好用还需要进行两项关键配置。4.1 配置国内镜像加速器从Docker Hub拉取镜像速度慢且不稳定必须配置国内镜像加速器。这里以阿里云容器镜像服务为例需免费注册阿里云账号获取专属加速器地址。编辑Docker守护进程配置文件sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [https://your_mirror_id.mirror.aliyuncs.com], exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 }, data-root: /data/docker // 可选修改默认数据目录到更大分区 } EOF将https://your_mirror_id.mirror.aliyuncs.com替换为你从阿里云控制台获取的实际加速器地址。关键配置解析native.cgroupdriversystemd确保Docker使用的cgroup驱动与系统麒麟V10默认使用systemd一致避免资源监控和容器内systemd运行出现问题。log-driver和log-opts配置日志轮转防止容器日志占满磁盘。data-root如果系统根分区空间不大强烈建议将Docker的数据目录存放镜像、容器迁移到挂载的数据盘上。重启Docker使配置生效sudo systemctl daemon-reload sudo systemctl restart docker再次运行docker info在输出底部Registry Mirrors部分应能看到你配置的镜像地址。4.2 非root用户操作Docker为了避免每次命令都加sudo可以将当前用户加入docker用户组。sudo groupadd docker # 如果docker组已存在此命令会提示可忽略 sudo usermod -aG docker $USER重要安全提示docker组权限相当于root权限因为可以通过挂载卷等方式访问主机系统文件。因此仅将可信用户加入此组。操作完成后需要完全退出当前终端会话并重新登录组权限更改才会生效。之后就可以直接使用docker ps等命令了。5. PolarDB for PostgreSQL 容器化部署实战PolarDB有多种形态这里我们选择最易于容器化部署的“PolarDB for PostgreSQL”开源版本。它兼容PostgreSQL具备PolarDB的核心特性。5.1 单节点快速部署开发测试对于开发测试环境我们可以使用一个容器同时运行读写节点和只读节点实际上通过进程模拟。阿里云开源了polardb_pg_local_instance这个工具镜像非常适合快速启动。# 拉取镜像使用配置好的镜像加速器速度很快 docker pull polardb/polardb_pg_local_instance:latest # 创建并运行容器 docker run -d \ --name polardb_pg \ -p 5432:5432 \ -e MODEstandalone \ polardb/polardb_pg_local_instance:latest参数解释-d后台运行。--name指定容器名称。-p 5432:5432将容器内的PostgreSQL默认端口5432映射到主机同端口。如果主机5432端口已被占用可改为-p 65432:5432。-e MODEstandalone设置运行模式为单机模式。容器启动后可以通过docker logs -f polardb_pg查看启动日志等待出现“POLARDB INSTANCE STARTED SUCCESSFULLY”字样。连接信息如下主机localhost或 服务器IP端口5432或你映射的主机端口用户名postgres密码mysecretpassword这是该镜像的默认密码生产环境必须修改数据库postgres你可以使用psql命令行或任何PostgreSQL客户端如pgAdmin, DBeaver进行连接测试。5.2 生产级一写多读集群部署Docker Compose单节点模式无法体现PolarDB的扩展能力。对于更接近生产的模拟我们可以使用Docker Compose部署一个最小集群包含1个读写主节点Primary和1个只读副本节点Replica。安装Docker Compose插件如果你按照方法三安装了docker-compose-plugin那么docker compose命令已可用。否则需单独安装。准备docker-compose.yml文件version: 3.8 services: primary: image: polardb/polardb_pg_local_instance:latest container_name: polardb_primary environment: - MODEprimary - PRIMARY_HOSTprimary - REPLICA_HOSTSreplica ports: - 5432:5432 networks: - polardb_net volumes: - polardb_primary_data:/var/lib/postgresql/data - ./shared:/shared # 共享目录用于同步数据 healthcheck: test: [CMD-SHELL, pg_isready -U postgres] interval: 10s timeout: 5s retries: 5 replica: image: polardb/polardb_pg_local_instance:latest container_name: polardb_replica environment: - MODEreplica - PRIMARY_HOSTprimary - REPLICA_HOSTSreplica depends_on: primary: condition: service_healthy networks: - polardb_net volumes: - polardb_replica_data:/var/lib/postgresql/data - ./shared:/shared # 通常只读节点不直接对外暴露端口通过读写分离中间件访问 networks: polardb_net: driver: bridge volumes: polardb_primary_data: polardb_replica_data:启动集群# 在包含docker-compose.yml的目录下执行 docker compose up -d这个配置定义了一个自定义网络polardb_net方便容器间通过服务名primary,replica通信。主节点暴露5432端口副本节点不暴露。通过共享卷./shared进行数据同步这是该镜像内部约定的机制。healthcheck确保主节点完全启动后才启动副本节点。验证集群状态连接主节点psql -h localhost -p 5432 -U postgres在主节点创建测试表和数据。进入副本容器docker exec -it polardb_replica bash然后连接其数据库psql -U postgres。查询刚才在主节点创建的数据应该能查到说明数据同步正常。6. 部署后的关键配置与安全加固容器跑起来只是开始要让其稳定、安全地运行必须进行后续配置。6.1 修改默认密码与创建专属用户永远不要使用默认密码。首先连接主节点修改postgres用户密码并创建业务专属用户。-- 修改超级用户密码 ALTER USER postgres WITH PASSWORD YourStrongPassword123!; -- 创建新的业务数据库和用户更安全的方式 CREATE DATABASE myapp_db; CREATE USER myapp_user WITH ENCRYPTED PASSWORD MyAppUserPass456!; GRANT ALL PRIVILEGES ON DATABASE myapp_db TO myapp_user;6.2 数据持久化与备份策略Docker容器本身是无状态的数据存储在容器内容器删除数据即丢失。我们之前通过volumes配置了命名卷polardb_primary_data数据会持久化在Docker管理的数据卷中位置通常在/var/lib/docker/volumes/下。这是一种方式。更推荐的方式是绑定挂载Bind Mount将主机上的已知目录挂载到容器内便于直接管理和备份。 修改docker-compose.yml中的volumes部分volumes: - /opt/polardb/primary/data:/var/lib/postgresql/data - /opt/polardb/shared:/shared然后在主机上建立定期备份任务例如使用cron调度pg_dump。6.3 网络与防火墙配置如果数据库需要被其他服务器访问需确保麒麟V10的防火墙放行相应端口。# 查看防火墙状态麒麟V10默认可能使用firewalld sudo systemctl status firewalld # 如果启用放行5432端口 sudo firewall-cmd --zonepublic --add-port5432/tcp --permanent sudo firewall-cmd --reload # 如果使用iptables命令类似 sudo iptables -I INPUT -p tcp --dport 5432 -j ACCEPT # 并保存规则取决于系统配置同时在PolarDB的配置文件容器内位于/var/lib/postgresql/data/pg_hba.conf中需要配置允许远程IP连接。这可以通过在docker run命令中挂载一个自定义的pg_hba.conf文件或者在容器启动后进入容器修改并重启服务来实现。7. 故障排查与性能调优要点在实际运行中你可能会遇到以下问题。7.1 容器启动失败端口冲突与权限问题问题运行docker compose up -d后容器反复重启或立即退出。使用docker logs polardb_primary查看日志。可能原因1端口冲突。日志可能显示5432端口已被占用。使用sudo netstat -tlnp | grep 5432查找占用进程。如果是旧的PostgreSQL实例先停止它。或者修改docker-compose.yml中的端口映射如5433:5432。可能原因2数据目录权限问题。如果使用绑定挂载主机目录如/opt/polardb/primary/data必须对Docker容器内的进程通常以UID 999运行postgres用户可写。确保目录存在并设置正确权限sudo chown -R 999:999 /opt/polardb/primary/data。7.2 从节点同步失败问题只读节点查询不到主节点新写入的数据。排查步骤检查副本容器日志docker logs polardb_replica。查看是否有连接主节点失败或复制错误。进入主节点容器查看复制状态docker exec polardb_primary psql -U postgres -c SELECT client_addr, state, sync_state FROM pg_stat_replication;。应该能看到一条记录指向副本节点且state为streaming。检查共享卷/shared在两个容器中是否内容一致。该目录用于同步元数据。7.3 性能调优初步思路容器化数据库的性能受限于主机资源。在麒麟V10上可以从以下几方面入手资源限制在docker-compose.yml中为每个服务配置deploy.resources.limitsCompose V3或直接使用cpus和mem_limit防止单个容器吃光资源。services: primary: # ... deploy: resources: limits: cpus: 2.0 memory: 4G存储性能确保绑定挂载的目录位于高性能存储如SSD上避免使用网络存储如NFS作为数据库主存储除非经过充分测试。数据库参数调优进入容器调整/var/lib/postgresql/data/postgresql.conf中的关键参数如shared_buffers通常设为系统内存的25%、work_mem、maintenance_work_mem等调整后需重启容器。建议将自定义配置以配置文件的形式挂载进容器便于管理。8. 进阶考量在麒麟环境下的长期维护将PolarDB on Docker投入生产还需要考虑监控、日志收集和高可用。监控部署cAdvisor监控容器资源使用情况搭配Prometheus和Grafana。也可以使用docker stats命令实时查看。日志管理配置Docker的日志驱动为json-file并设置大小限制前面已做同时可以考虑使用Fluentd或Loki收集所有容器的日志统一管理。高可用目前Docker Compose部署的集群主节点是单点。生产环境需要考虑更复杂的高可用方案例如使用Patroni等工具管理PostgreSQL故障切换并结合Docker Swarm或Kubernetes进行容器编排但这已超出单机部署范畴需要更复杂的基础设施支持。在麒麟V10这条路上从Docker安装到PolarDB部署每一步都需要结合系统特性仔细斟酌。官方文档是地图而实际踩出来的路才是你能依赖的导航。这次部署让我深刻体会到在国产化环境中“能用”和“好用”之间隔着一整个配置优化和故障预案的鸿沟。尤其是存储路径、网络配置和权限管理这几个地方多花点时间设计能为后续运维省下无数麻烦。现在这个PolarDB实例已经稳定运行了数周承载了部分内部查询业务后续我们计划将其接入公司的容器云平台实现更自动化的生命周期管理。

相关新闻