【YashanDB认证】之三:用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后动态分配,可能会与我的不同)

        其中端口映射关系如下:

映射方式宿主子系统用途
nginx192.168.1.58:8290192.168.56.112:8290Ymp-Web端口
nginx192.168.1.58:8291192.168.56.112:8291YashanDB端口
nginx192.168.1.58:8292192.168.56.112:8292主机间通信端口
nginx192.168.1.58:8293192.168.56.112:8293Yasom端口
nginx192.168.1.58:8294192.168.56.112:8294Yasagent端口
docker172.17.0.1:8290172.17.0.2:8090Ympp-Web端口
docker172.17.0.1:8291172.17.0.2:8091YashanDB端口
docker172.17.0.1:8292172.17.0.2:8092主机间通信端口
docker172.17.0.1:8293172.17.0.2:8093Yasom端口
docker172.17.0.1:8294172.17.0.2:8094Yasagent端口

        如上所述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.zipYashanDB安装企业版安装包
yashan-migrate-platform-23.4.3.2-linux-x86-64.zipYMP安装包

        另外有两个文件可以从我的百度网盘下载

文件名网盘链接
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
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值