用Docker制作YMP容器
1. 前言
崖山迁移平台(YashanDB Migration Platform,YMP)是YashanDB提供的数据库迁移产品,提供异构RDBMS与YashanDB之间进行迁移评估、离线迁移、数据校验的能力。 YMP提供可视化服务,用户只需通过简单的界面操作,即可完成从评估到迁移整个流程的执行与监控,实现低门槛、低成本、高效率的异构数据库迁移。
总之,使用YMP可以快速地将mysql等数据库直接升级为yashandb。升级过程包括:(1)根据源库的数据结构自动创建yashandb的数据结构(表,字段,存储过程等)。(2)自动将源库的数据导入到yashandb库中。(3)自动对导入后的目标库进行数据校验,确保迁移后没有数据遗漏或数据错误。
本文在安装YashanDB容器的同一宿主机环境中进行。YashanDB的搭建参见上一篇文章【YashanDB认证】之二:Docker部署一体YashanDB(YDC,YCM)。
此章节主要解决ymp的docker容器问题。原因是这样:
(1)官网并没有提供ymp的docker镜像。
(2)实际使用场景可能无网,要一个docker容器来解决无网问题。
(3)ymp安装环境和步骤复杂,要一个docker镜像方便环境复用。
(4)ymp往往是一次性使用,升级完一个系统后就可以不用了。docker容器免去系统参数恢复等麻烦。
想要参加【YashanDB认证】的同学,请移步官网https://www.yashandb.com/YCA_courses了解更多详情。
系统与网络
本文演练环境说明如下:
因本机资源有限,在局域网中另一台windows电脑(实验电脑)上用virtualbox安装龙蜥操作系统8.9 64位。然后在龙蜥系统中安装Docker,再用Docker加载YashanDB镜像安装容器。因此,整个网络的IP整理如下:
| 电脑名称 | IP及说明 |
|---|---|
| 开发者电脑 | 192.168.1.46 |
| 实验电脑 | 192.168.1.58(办公局域网IP) 192.168.56.1(Virtualbox的HostOnly虚拟网关) |
| 龙蜥系统 | 10.0.2.15(NAT网卡)用于访问互联网 192.168.56.112(HostOnly网卡)给宿主访问 172.17.0.1(docker的网关) |
| Ymp容器 | 172.17.0.2(容器内部的IP地址,docker run后动态分配,可能会与我的不同) |
其中端口映射关系如下:
| 映射方式 | 宿主 | 子系统 | 用途 |
|---|---|---|---|
| nginx | 192.168.1.58:8290 | 192.168.56.112:8290 | Ymp-Web端口 |
| nginx | 192.168.1.58:8291 | 192.168.56.112:8291 | YashanDB端口 |
| nginx | 192.168.1.58:8292 | 192.168.56.112:8292 | 主机间通信端口 |
| nginx | 192.168.1.58:8293 | 192.168.56.112:8293 | Yasom端口 |
| nginx | 192.168.1.58:8294 | 192.168.56.112:8294 | Yasagent端口 |
| docker | 172.17.0.1:8290 | 172.17.0.2:8090 | Ympp-Web端口 |
| docker | 172.17.0.1:8291 | 172.17.0.2:8091 | YashanDB端口 |
| docker | 172.17.0.1:8292 | 172.17.0.2:8092 | 主机间通信端口 |
| docker | 172.17.0.1:8293 | 172.17.0.2:8093 | Yasom端口 |
| docker | 172.17.0.1:8294 | 172.17.0.2:8094 | Yasagent端口 |
如上所述192.168.56.112和172.17.0.1都是龙蜥系统上的IP地址,因此搭建完成后,从开发者电脑可以直接访问到YashanDB容器中的三个应用。
为了从开发者电脑能够访问到龙蜥系统,需要在实验电脑上安装一个nginx,然后在{nginx目录}/conf/nginx.conf中添加与http平级的配置。如下:
stream {
upstream ympWeb{
server 192.168.56.112:8290 weight=1;
}
server {
listen 8290;
proxy_pass ympWeb;
}
upstream ympYashan{
server 192.168.56.112:8291 weight=1;
}
server {
listen 8291;
proxy_pass ympYashan;
}
upstream ympHost{
server 192.168.56.112:8292 weight=1;
}
server {
listen 8292;
proxy_pass ympHost;
}
upstream ympYasom{
server 192.168.56.112:8293 weight=1;
}
server {
listen 8293;
proxy_pass ympYasom;
}
upstream ympYasagent{
server 192.168.56.112:8294 weight=1;
}
server {
listen 8294;
proxy_pass ympYasagent;
}
}
2. 软件包准备
进入官网下载页https://download.yashandb.com/download


下载后得到文件
| 文件名 | 说明 |
|---|---|
| yashan-migrate-platform-23.4.3.2-linux-x86-64.zip | YashanDB安装企业版安装包 |
| yashan-migrate-platform-23.4.3.2-linux-x86-64.zip | YMP安装包 |
另外有两个文件可以从我的百度网盘下载
| 文件名 | 网盘链接 |
|---|---|
| jdk-21.0.2_linux-x64_bin.tar.gz | 链接: https://pan.baidu.com/s/1EpoDr_U-A3_DWERwP2_y9Q?pwd=tqvu 提取码: tqvu |
| openssl-dir-x86-usr.local.tar.gz | 链接: https://pan.baidu.com/s/1qEivz-7MheRqDFtyQA9QQA?pwd=he3q 提取码: he3q |
3. 执行安装(手工)
在github上用离线工作流下载一个centos8的容器镜像,得到:centos_8-amd64.tar.gz
有其他办法可以得到centos8镜像的同学,请用自己的办法。
为方便读者复现操作,我已将文件上传到百度网盘:
https://pan.baidu.com/s/11RAT_esH2_dXM5q0oFK3Zw?pwd=s2tf 提取码: s2tf
#创建目录并开放权限
mkdir -p /data/docker-images
chmod -R 777 /data/docker-images
上传到/data/docker-images目录。在宿主机上用root执行以下命令:
#进入目录并加载镜像
cd /data/docker-images
docker load < centos_8-amd64.tar.gz
#创建镜像目录并开放权限
mkdir -p /data/docker-data/centos8_ymp_23_4_3_2/scripts
mkdir -p /data/docker-data/centos8_ymp_23_4_3_2/tmp/
chmod -R 777 /data/docker-data/centos8_ymp_23_4_3_2/
将yashan-migrate-platform-23.4.3.2-linux-x86-64.zip、yashandb-23.4.1.102-linux-x86_64.tar.gz、jdk-17.0.12_linux-x64_bin.tar.gz、openssl-dir-x86-usr.local.tar.gz上传到宿主的/data/docker-data/centos8_ymp_23_4_3_2/tmp/目录
执行容器安装
docker run -d \
-it \
-p 8090:8090 \
-p 8091:8091 \
-p 8092:8092 \
-p 8093:8093 \
-p 8094:8094 \
--dns 8.8.8.8 \
--dns 114.114.114.114 \
--name centos8_ymp_23_4_3_2 \
centos:8
以上命令返回后,继续执行
#设置容器自启并拉起
docker update centos8_ymp_23_4_3_2 --restart=always
docker start centos8_ymp_23_4_3_2
#复制需要到文件到容器内部的/tmp目录
docker cp /data/docker-data/centos8_ymp_23_4_3_2/tmp/yashan-migrate-platform-23.4.3.2-linux-x86-64.zip centos8_ymp_23_4_3_2:/tmp/
docker cp /data/docker-data/centos8_ymp_23_4_3_2/tmp/yashandb-23.4.1.102-linux-x86_64.tar.gz centos8_ymp_23_4_3_2:/tmp/
docker cp /data/docker-data/centos8_ymp_23_4_3_2/tmp/jdk-17.0.12_linux-x64_bin.tar.gz centos8_ymp_23_4_3_2:/tmp/
docker cp /data/docker-data/centos8_ymp_23_4_3_2/tmp/openssl-dir-x86-usr.local.tar.gz centos8_ymp_23_4_3_2:/tmp/
#进入容器shell
docker exec -it centos8_ymp_23_4_3_2 /bin/bash
#解压jdk并设置环境变量
tar -xzf /tmp/jdk-17.0.12_linux-x64_bin.tar.gz -C /usr/local ; ln -s /usr/local/jdk-17.0.12/bin/java /usr/bin/java ;ln -s /usr/local/jdk-17.0.12/bin/javac /usr/bin/javac ;
#修改镜像源appstream
echo '[appstream]' > /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'name=CentOS-$releasever - AppStream' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'baseurl=https://mirrors.aliyun.com/centos/$releasever/AppStream/$basearch/os/' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'gpgcheck=1' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'enabled=1' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'sslverify=1' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo
#修改镜像源baseos
echo '[baseos]' > /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'name=CentOS-8 - BaseOS' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'baseurl=https://mirrors.aliyun.com/centos/8/BaseOS/$basearch/os/' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'gpgcheck=1' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'enabled=1' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'sslverify=1' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
#修改镜像源extrass
echo '[extras]' > /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'name=CentOS-8 - Extras' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'baseurl=https://mirrors.aliyun.com/centos/8/extras/x86_64/os/' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'gpgcheck=1' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'enabled=1' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'sslverify=1' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo
#更新软件索引
dnf -y update && dnf -y upgrade && dnf -y clean all ; dnf -y makecache
#设置编码
ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && dnf -y install --setopt=tsflags=nodocs glibc-locale-source && localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8
printf '%s\n' \
'export LANG=zh_CN.UTF-8' \
'export LC_ALL=zh_CN.UTF-8' > /etc/profile.d/locale.sh
printf '%s\n' 'export LANG=zh_CN.UTF-8' >> /etc/bashrc
#安装常用运维程序
dnf -y install vim net-tools nmap lsof curl wget rpm cmake zip unzip passwd sudo libaio --nogpgcheck
dnf -y install perl perl-devel gcc make zlib zlib-devel glibc-devel glibc-headers --nogpgcheck
rpm -e --nodeps shadow-utils || true && dnf -y install shadow-utils --nogpgcheck && dnf makecache || true && rm -rf /var/cache/yum /var/cache/dnf
#设置ymp免密登录shell
mkdir -p /etc/sudoers.d && echo 'ymp ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/ymp && chmod 0440 /etc/sudoers.d/ymp
#设置最大进程数量
echo "* soft nproc 65536" >> /etc/security/limits.conf && echo "* hard nproc 65536" >> /etc/security/limits.conf && echo "ymp soft nproc 65536" >> /etc/security/limits.d/20-nproc.conf && echo "ymp hard nproc 65536" >> /etc/security/limits.d/20-nproc.conf
#解压崖山谢工提供的openssl编译好的包,代替操作系统默认的包
mv /usr/bin/openssl /usr/bin/openssl_bak
mv /usr/share/doc/openssl /usr/share/doc/openssl_bak
mv /usr/share/licenses/openssl /usr/share/licenses/openssl_bak
tar -xzf /tmp/openssl-dir-x86-usr.local.tar.gz -C /usr/local
#创建ymp用户并设置密码
useradd -m -s /bin/bash ymp && echo 'ymp:AnoUser,.()' | chpasswd
#切换到ymp用户
sudo su - ymp
#解压并进入ymp程序目录
unzip /tmp/yashan-migrate-platform-23.4.3.2-linux-x86-64.zip -d /home/ymp/
cd /home/ymp/yashan-migrate-platform
#配置openssl环境变量并使其生效
echo "export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH" >> /home/ymp/.bashrc
echo "export PATH=/usr/local/openssl/bin:$PATH" >> /home/ymp/.bashrc
source ~/.bashrc
#经验证,首次执行sh bin/ymp.sh install --db /tmp/yashandb-23.4.1.102-linux-x86_64.tar.gz会返回含YMP install failed!这个串,此时要自动执行sh bin/ymp.sh uninstall -f后再次执行sh bin/ymp.sh install
#执行ymp安装
bash -c 'output=$(sh bin/ymp.sh install --db /tmp/yashandb-23.4.1.102-linux-x86_64.tar.gz 2>&1); if echo "$output" | grep -q "YMP install failed!"; then sh bin/ymp.sh uninstall -f >/dev/null 2>&1; sh bin/ymp.sh install --db /tmp/yashandb-23.4.1.102-linux-x86_64.tar.gz; else echo "Install success"; fi'
返回的信息有**YMP install successfully!**表示安装成功,如下:
14:44:32.224 [main] INFO com.yashandb.tool.ymp.command.util.CommandUtil - +--------------------------------------------------------------------------------------------------------+
14:44:32.224 [main] INFO com.yashandb.tool.ymp.command.util.CommandUtil - | task | 21ddc65c918fecc6 | StartYasdbCluster | - | ymp | SUCCESS | 0 | 100 | 17 |
14:44:32.224 [main] INFO com.yashandb.tool.ymp.command.util.CommandUtil - +------+------------------+-------------------+--------+-------+---------+-------------+----------+------+
14:44:32.224 [main] INFO com.yashandb.tool.ymp.command.util.CommandUtil - task completed, status: SUCCESS
YMP install successfully!
如果安装失败,会返回YMP install failed!
若安装失败,请重头开始完整流程做一次,或者在技术群中反馈找技术人员协助解决问题。以上脚 本在我的演练环境是成功运行的。
4. 镜像制作
由于ymp在迁移过程中,需要从源数据库中提取sql语句然后执行到内置的崖山数据库中进行测试。因此在安装ymp的最后一步需要指定目标数据库(YashanDB)相同版本的安装包。ymp与yashandb的关系是一对一的关系。也正因此本文构建的Dockerfile不将ymp或yashandb的包进行内置,而是通过参数的方式提供动态软件包,这样一来想要安装其他版本的ymp或yashandb只要在docker run的时候修改相关参数,本文构建的就是这样一个通用的镜像。
花这么多的时间用docker容器来准备环境,只是为了解决离网环境复用镜像的问题。因此在执行最后一步之前,我要先把容器镜像导出。然后重新run一个容器实例,并且在run的时候指定目标数据库的YashanDB版本程序包,需要给不同版本的YashanDB做同步时,只需要重新run一个环境即可。
在开发者电脑上用shell工具连接远程用户anolis到 龙蜥系统中。在宿主中执行以下命令:
#编辑docker的配置文件
sudo vim /etc/docker/daemon.json
编辑后我的文件内容是这样:
{
"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"]
"dns": ["8.8.8.8", "114.114.114.114", "223.5.5.5"]
}
从字面意思看daemon.json是 Docker 守护进程(dockerd)的全局配置文件,用来覆盖和定制守护进程的行为。这里我用的是杭州阿里云镜像路径,如果你在北京、上海等地区,可以替换为相应区域的域名,例如:
北京:https://registry.cn-beijing.aliyuncs.com
上海: https://registry.cn-shanghai.aliyuncs.com
深圳: https://registry.cn-shenzhen.aliyuncs.com
具体可用的镜像域名以阿里云“镜像加速”页面为准。
用dockerfile构建自定义的镜像
#进入目录
sudo mkdir -p /data/docker-build/centos8-with-deps
#编写.dockerignore
sudo vi /data/docker-build/centos8-with-deps/.dockerignore
输入以下内容并保存
.git
build
node_modules
dist
*.log
*.tmp
out
target
venv
pycache
编写Dockerfile文件
sudo vi /data/docker-build/centos8-with-deps/Dockerfile
输入以下内容并保存:
FROM centos:8
# 设置UTF-8编码
ENV LANG=zh_CN.UTF-8
ENV LC_ALL=zh_CN.UTF-8
# 复制并安装JDK17
COPY jdk-17.0.12_linux-x64_bin.tar.gz /tmp/jdk-17.0.12_linux-x64_bin.tar.gz
RUN set -e; \
mkdir -p /usr/local && \
tar -xzf /tmp/jdk-17.0.12_linux-x64_bin.tar.gz -C /usr/local && \
ln -s /usr/local/jdk-17.0.12/bin/java /usr/bin/java && \
ln -s /usr/local/jdk-17.0.12/bin/javac /usr/bin/javac && \
rm -f /tmp/jdk-17.0.12_linux-x64_bin.tar.gz
# 设置JDK环境变量(JDK17已移除dt.jar和tools.jar,删除无效CLASSPATH)
ENV JAVA_HOME=/usr/local/jdk-17.0.12
ENV PATH=$JAVA_HOME/bin:$PATH
# 写入环境变量到profile.d
RUN mkdir -p /etc/profile.d && \
printf '%s\n' \
'export JAVA_HOME=/usr/local/jdk-17.0.12' \
'export PATH=$JAVA_HOME/bin:$PATH' \
> /etc/profile.d/java.sh
# 验证JDK版本
RUN java -version
# 更新镜像源为阿里云
RUN set -e; \
echo '[appstream]' > /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'name=CentOS-$releasever - AppStream' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'baseurl=https://mirrors.aliyun.com/centos/$releasever/AppStream/$basearch/os/' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'gpgcheck=1' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'enabled=1' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'sslverify=1' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo && \
echo 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt' >> /etc/yum.repos.d/CentOS-Linux-AppStream.repo
RUN set -e; \
echo '[baseos]' > /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'name=CentOS-8 - BaseOS' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'baseurl=https://mirrors.aliyun.com/centos/8/BaseOS/$basearch/os/' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'gpgcheck=1' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'enabled=1' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'sslverify=1' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo && \
echo 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt' >> /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
RUN set -e; \
echo '[extras]' > /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'name=CentOS-8 - Extras' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'baseurl=https://mirrors.aliyun.com/centos/8/extras/x86_64/os/' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'gpgcheck=1' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'enabled=1' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'sslverify=1' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo && \
echo 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt' >> /etc/yum.repos.d/CentOS-Linux-Extras.repo
# 清理并重建缓存
RUN dnf -y update && dnf -y upgrade && dnf -y clean all ; dnf -y makecache
# 设置时区与编码
RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && dnf -y install --setopt=tsflags=nodocs glibc-locale-source && localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8
# 统一编码为zh_CN.UTF-8(删除冲突的en_US配置)
RUN printf '%s\n' \
'export LANG=zh_CN.UTF-8' \
'export LC_ALL=zh_CN.UTF-8' > /etc/profile.d/locale.sh && \
printf '%s\n' 'export LANG=zh_CN.UTF-8' >> /etc/bashrc
# 安装常用工具(包含openssh-server、openssh-clients)
RUN set -e; \
if command -v dnf >/dev/null 2>&1; then \
PKG_INSTALL="dnf -y install"; \
PKG_MAKECACHE="dnf makecache"; \
PKG_GPG="--nogpgcheck"; \
else \
PKG_INSTALL="yum -y install"; \
PKG_MAKECACHE="yum makecache"; \
PKG_GPG="--nogpgcheck"; \
fi; \
$PKG_INSTALL vim net-tools nmap lsof curl wget rpm cmake zip unzip passwd sudo libaio openssh-server openssh-clients perl perl-devel gcc make zlib zlib-devel glibc-devel glibc-headers $PKG_GPG >/dev/null 2>&1 || true; \
if rpm -q shadow-utils >/dev/null 2>&1; then \
rpm -e --nodeps shadow-utils || true; \
fi; \
$PKG_INSTALL shadow-utils $PKG_GPG || true; \
$PKG_MAKECACHE || true; \
rm -rf /var/cache/yum /var/cache/dnf || true
# 配置sudo权限(提前配置,确保后续用户有sudo权限)
RUN mkdir -p /etc/sudoers.d && \
echo 'ymp ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/ymp && \
chmod 0440 /etc/sudoers.d/ymp
# 配置最大用户线程数
RUN echo "* soft nproc 65536" >> /etc/security/limits.conf && \
echo "* hard nproc 65536" >> /etc/security/limits.conf && \
echo "ymp soft nproc 65536" >> /etc/security/limits.d/20-nproc.conf && \
echo "ymp hard nproc 65536" >> /etc/security/limits.d/20-nproc.conf
#写入entrypoint.sh
# 用echo写入entrypoint.sh到/usr/local/bin/,处理所有引号和特殊字符转义
RUN echo '#!/bin/bash' > /usr/local/bin/entrypoint.sh && \
echo 'set -e # Exit immediately if any command exits with a non-zero status' >> /usr/local/bin/entrypoint.sh && \
echo '' >> /usr/local/bin/entrypoint.sh && \
echo 'echo ""' >> /usr/local/bin/entrypoint.sh && \
echo 'echo "=== entrypoint.sh run by user:\$(whoami) , uid:\$(id -u) ==="' >> /usr/local/bin/entrypoint.sh && \
echo 'echo ""' >> /usr/local/bin/entrypoint.sh && \
echo '' >> /usr/local/bin/entrypoint.sh && \
echo '# Log function: standardize log format for easier troubleshooting (added)' >> /usr/local/bin/entrypoint.sh && \
echo '' >> /usr/local/bin/entrypoint.sh && \
echo 'log() {' >> /usr/local/bin/entrypoint.sh && \
echo ' echo "[$(date '\''+%Y-%m-%d %H:%M:%S'\'')] \$1"' >> /usr/local/bin/entrypoint.sh && \
echo '}' >> /usr/local/bin/entrypoint.sh && \
echo '# -------------------------- Keep container running --------------------------' >> /usr/local/bin/entrypoint.sh && \
echo 'log "All processes completed, keeping container running in background (PID 1 blocking). With nothing installed!"' >> /usr/local/bin/entrypoint.sh && \
echo 'while true;' >> /usr/local/bin/entrypoint.sh && \
echo 'do' >> /usr/local/bin/entrypoint.sh && \
echo ' sleep 3600' >> /usr/local/bin/entrypoint.sh && \
echo 'done' >> /usr/local/bin/entrypoint.sh && \
chown root:root /usr/local/bin/entrypoint.sh && \
chmod 755 /usr/local/bin/entrypoint.sh
# 创建用户并设置密码(关键:移到vimrc/SSH配置之前,确保用户存在)
RUN useradd -m -s /bin/bash ymp && echo 'ymp:AnoUser,.()' | chpasswd
# 【核心修复】vimrc、SSH配置逻辑(用户已创建,可正常执行)
RUN set -e; \
# 1. 创建.vimrc文件(root直接创建后修改权限,无需sudo -u)
echo '\" Vim' > /home/ymp/.vimrc; \
echo 'set encoding=utf-8' >> /home/ymp/.vimrc; \
echo '\" unicode encoding list . first left to right' >> /home/ymp/.vimrc; \
echo 'set fileencodings=utf-8,gbk,gb2312,cp936' >> /home/ymp/.vimrc; \
echo '\" terminal'\''s encoding' >> /home/ymp/.vimrc; \
echo 'set termencoding=utf-8' >> /home/ymp/.vimrc; \
echo '\" line end char' >> /home/ymp/.vimrc; \
echo 'set fileformats=unix,dos' >> /home/ymp/.vimrc; \
echo '\" menu'\''s encoding' >> /home/ymp/.vimrc; \
echo 'set langmenu=zh_CN.UTF-8' >> /home/ymp/.vimrc; \
\
# 2. 修正权限(确保ymp用户拥有所有权)
echo "Setting permissions and applying vimrc..."; \
chown -R ymp:ymp /home/ymp/; \
sudo -u ymp bash -c "source /home/ymp/.vimrc" 2>/dev/null || true; \
\
# 3. 生成SSH主机密钥
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" > /dev/null; \
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" > /dev/null; \
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" > /dev/null; \
\
# 4. 设置SSH密钥权限
chmod 600 /etc/ssh/ssh_host_*_key; \
chmod 644 /etc/ssh/ssh_host_*_key.pub; \
\
# 5. 创建sshd运行目录
mkdir /var/run/sshd; \
chmod 0755 /var/run/sshd; \
\
# 6. 配置sshd_config
sh -c "echo 'PermitRootLogin no' >> /etc/ssh/sshd_config"; \
sh -c "echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config"; \
sh -c "echo 'AllowUsers ymp' >> /etc/ssh/sshd_config"; \
\
# 7. 设置ymp用户登录默认目录
echo 'cd /home/ymp' >> /home/ymp/.bashrc
# 切换到普通用户
USER ymp
WORKDIR /home/ymp
# 定义入口脚本和默认参数
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["--default-arg"]
执行以下命令开始构建新容器
#修改目录权限,确保不会有权限问题
sudo chmod -R 777 /data/docker-build/centos8-with-deps
#进入Dockerfile所在目录
cd /data/docker-build/centos8-with-deps
#执行容器构建
sudo docker build -t centos8-with-deps:v1 .
构建成功的界面大概长这样:

查看docker中的镜像
sudo docker images | grep centos8-with-deps
返回以下内容表示成功
centos8-with-deps v1 96828d45aec5 29 minutes ago 1.37GB
导出压缩包并保存到指定路径
mkdir -p /data/docker-images && docker save centos8-with-deps:v1 | gzip > /data/docker-images/centos8-with-deps_v1.tar.gz
这条命令是将docker save得到的文件内容当作参数传给gzip程序,gzip执行完成后把内容写入到压缩文件中。压缩后体积约小了一半。如下图示:

5. 执行安装(新镜像)
如果读者执行了前面所有步骤,现在docker中应该已经有一个centos8-with-deps:v1这样的镜像。也可以从百度网盘下载得到。centos8-with-deps_v1.tar.gz 链接: https://pan.baidu.com/s/1WIck_Bz9u0DOVhkLOFIMGw?pwd=pj8u 提取码: pj8u
下载后上传到宿主的/data/docker-images目录,然后root用户进入目录进行挂载:
cd /data/docker-images
docker load < centos8-with-deps_v1.tar.gz
在宿主机上切换到root用户并执行以下命令:
#创建容器目录并开放权限
mkdir -p /data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/scripts
mkdir -p /data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/tmp/
chmod -R 777 /data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/
将yashan-migrate-platform-23.4.3.2-linux-x86-64.zip、yashandb-23.4.1.102-linux-x86_64.tar.gz、openssl-dir-x86-usr.local.tar.gz上传到宿主的/data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/tmp/目录。如下图:

创建enrypoint.sh文件。不理解为什么在这里创建entrypoint.sh的读者,请先看前一篇文章 【YashanDB认证】之二:Docker部署一体YashanDB(YDC,YCM)
vi /data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/scripts/entrypoint.sh
输入以下内容并保存:
#!/bin/bash
set -e # Exit immediately if any command exits with a non-zero status
echo ""
echo "=== entrypoint.sh run by user:$(whoami) , uid:$(id -u) ==="
echo ""
# Log function: standardize log format for easier troubleshooting (added)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
is_init() {
# Check if initialization is needed (first run)
[ ! -d "$TARGET_YMP_PATH" ]
}
# 创建目录并设置权限,忽略所有错误
log "HOME=$HOME"
#这是ymp程序解压后的目录
TARGET_YMP_PATH=$HOME/yashan-migrate-platform
start_sshd() {
#------------------------------------------------------
#auto start sshd
#------------------------------------------------------
if [ ! -f "/usr/sbin/sshd" ]; then
log "/usr/sbin/sshd not found,sshd not started"
return 0
fi
#以后台进程方式拉起sshd
sudo /usr/sbin/sshd
log "SSHD START SUCCESS"
#------------------------------------------------------
}
install_ssl(){
#解压崖山谢工提供的openssl编译好的包,代替操作系统默认的包
if [ -f /usr/bin/openssl ]; then
sudo mv /usr/bin/openssl /usr/bin/openssl_bak
fi
if [ -d /usr/share/doc/openssl ]; then
sudo mv /usr/share/doc/openssl /usr/share/doc/openssl_bak
fi
if [ -d /usr/share/licenses/openssl ]; then
sudo mv /usr/share/licenses/openssl /usr/share/licenses/openssl_bak
fi
if [ ! -n "$SSL_PACKAGE_PATH" ]; then
log "WARNING:SSL_PACKAGE_PATH is not set,skip openssl installation"
return 0
fi
if [ ! -f "$SSL_PACKAGE_PATH" ]; then
log "ERROR:SSL package $SSL_PACKAGE_PATH not found"
return 1
fi
sudo tar -xzf "$SSL_PACKAGE_PATH" -C /usr/local
#创建快捷方式 ln -s {程序} {快捷方式}
sudo ln -sf /usr/local/openssl/bin/openssl /usr/bin/openssl
sudo chmod -R a+rx /usr/local/openssl/lib/
echo "export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH" >> /home/ymp/.bashrc
echo "export PATH=/usr/local/openssl/bin:$PATH" >> /home/ymp/.bashrc
source ~/.bashrc
cat ~/.bashrc | grep export
log "OpenSSL installed successfully: $(openssl version)"
}
install_ymp(){
#复制文件到/home/ymp目录
#install ymp auto
#------------------------------------------------------
log "installing ymp ..."
#检测ymp的安装包路径变量是否非空,在docker run时传入
if [ ! -n "$YMP_PACKAGE_PATH" ]; then
log "argument YMP_PACKAGE_PATH not set. ymp not installed!"
return 0
fi
#检测ymp的安装包路径变量是否非空,在docker run时传入
if [ ! -n "$DB_PACKAGE_PATH" ]; then
log "argument DB_PACKAGE_PATH not set. ymp not installed!"
return 0
fi
log " get YMP_PACKAGE_PATH $YMP_PACKAGE_PATH "
log " get DB_PACKAGE_PATH $DB_PACKAGE_PATH "
#检测路径变量值指向的文件是否存在。
if [ ! -f "$YMP_PACKAGE_PATH" ]; then
log "path $YMP_PACKAGE_PATH not exists!"
return 0
fi
if [ ! -f "$DB_PACKAGE_PATH" ]; then
log "path $DB_PACKAGE_PATH not exists!"
return 0
fi
log " YMP_PACKAGE_PATH and DB_PACKAGE_PATH exists !"
#-C指向/home/ymp 解压后得到/home/ymp
log "Unzipping $YMP_PACKAGE_PATH to $HOME/"
unzip "$YMP_PACKAGE_PATH" -d "$HOME/" > /dev/null
log "cd $TARGET_YMP_PATH"
cd "$TARGET_YMP_PATH"
log "OpenSSL environment configured: LD_LIBRARY_PATH=$LD_LIBRARY_PATH, PATH=$PATH"
#经验证,首次执行可能失败,需卸载后重试
#bash -c "output=\$(sh bin/ymp.sh install --db $DB_PACKAGE_PATH); if echo \"\$output\" | grep -q \"YMP install failed!\"; then sh bin/ymp.sh uninstall -f; sh bin/ymp.sh install --db $DB_PACKAGE_PATH; fi"
log "Start installing ymp: sh bin/ymp.sh install --db $DB_PACKAGE_PATH"
# 核心修复:用tee /dev/tty分流输出,既捕获又实时打印
output=$(sh bin/ymp.sh install --db "$DB_PACKAGE_PATH" 2>&1 | tee /dev/tty)
# 检查输出中是否包含失败标志
if echo "$output" | grep -q "YMP install failed!"; then
echo "YMP install failed! uninstall and reinstall again!"
# 执行强制卸载
log "sh bin/ymp.sh uninstall -f"
sh bin/ymp.sh uninstall -f
# 重新执行安装
log "=== Reinstalling ymp: sh bin/ymp.sh install --db $DB_PACKAGE_PATH"
sh bin/ymp.sh install --db "$DB_PACKAGE_PATH" 2>&1 | tee /dev/tty
else
log "=== YMP install success! ==="
fi
}
start_ymp(){
log "cd $TARGET_YMP_PATH"
# 修复:cd命令添加错误处理
cd "$TARGET_YMP_PATH"
log "sh bin/ymp.sh start"
sh bin/ymp.sh start 2>&1 | tee /dev/tty # 让启动日志也实时输出
}
if is_init; then
install_ssl
install_ymp
start_sshd
else
start_sshd
start_ymp
fi
# -------------------------- Keep container running --------------------------
log "All processes completed, keeping container running in background (PID 1 blocking)"
while true; do
sleep 3600
done
再次授权,确保在安装容器过程中不会出现权限问题
sudo chmod -R 777 /data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/
先检查一下剩余内存是否充足

经过测试验证,执行安装过程约需要7分钟左右,中内存消耗峰值为3.7GB,保险起见应确保空闲6GB内存,否则可能会因内存不足导致安装失败。
方法大概是这样:
(1)另开一个shell窗口,切换到root用户。
(2)在新开的shell进入到/data/目录,执行命令:while true; do echo “[$(date ‘+%Y-%m-%d %H:%M:%S’)]”; free -lh; sleep 1; done >> memory_usage.log 2>&1
此命令会每隔1秒钟,调用一次free -lh并将结果写入到/data/memory_usage.log中。
(3)然后回到原来的窗口执行以下命令:
docker run -d \
-it \
-p 8290:8090 \
-p 8291:8091 \
-p 8292:8092 \
-p 8293:8093 \
-p 8294:8094 \
--dns 8.8.8.8 \
--dns 114.114.114.114 \
--name yashan_23_4_1_102_ymp_23_4_3_2 \
-v /data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/tmp/:/tmp/ \
-v /data/docker-data/yashan_23_4_1_102_ymp_23_4_3_2/scripts/entrypoint.sh:/usr/local/bin/entrypoint.sh \
-e YMP_PACKAGE_PATH=/tmp/yashan-migrate-platform-23.4.3.2-linux-x86-64.zip \
-e DB_PACKAGE_PATH=/tmp/yashandb-23.4.1.102-linux-x86_64.tar.gz \
-e SSL_PACKAGE_PATH=/tmp/openssl-dir-x86-usr.local.tar.gz \
centos8-with-deps:v1
开守护进程监听日志输出
docker logs yashan_23_4_1_102_ymp_23_4_3_2 -f
日志中出现YMP install successfully!表示安装成功,如下图:

打开浏览器访问:
http://192.168.1.58:8290/ 默认帐号密码(admin/admin)
注意:这里的IP是实验电脑的IP
登录后提示修改密码为:AnoYmp!@12



以上就是本次分享的核心内容啦!如果实操中遇到问题,欢迎在评论区留言或给我发邮件~ 也可以点赞收藏,我们一起解锁更多实用技能!

1179

被折叠的 条评论
为什么被折叠?



