写点什么

YashanDB Docker 镜像制作

作者:YashanDB
  • 2024-09-30
    广东
  • 本文字数:5083 字

    阅读完需:约 17 分钟

本文作者:YashanDB 中级服务工程师鲍健昕

为什么需要 Docker 部署数据库

常规使用 yasboot 部署数据库的方法,操作流程复杂,需要配置许多配置文件以及环境变量,不同用户使用的环境不同,那么环境配置也会存在差异,每当更换机器或者有新系统开发时都要就要重复不熟⼀次。


使用 Docker 后,只需要⼀次配置好环境,换到别的机器上就可以一键部署好,能够大大简化操作。Docker 容器与虚拟机不同,不需要捆绑⼀整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。


什么是数据库镜像与容器

数据库镜像(image)是一种轻量级、可执行的独立软件包,它包含运行数据库所需的所有内容,把操作系统、数据库打包好形成⼀个可交付的运行环境,这个打包好的运行环境就是 image 镜像文件。只有通过这个镜像文件才能生成 Docker 容器实例,类似 Java 中 new 出来一个对象。数据库镜像是分层的,以 MySQL 镜像为例,在下载镜像的过程中是一层层下载的:


Docker File 是什么

Dockerfile 是⼀个用来构建镜像的文本文件,文本内容包含了⼀条条构建镜像所需的指令和说明。• FROM:定制的镜像都是基于 FROM 的镜像,FROM centos:8.1.1911 表示后续的操作都是基于 centos:8.1.1911。• COPY:从上宿主机中复制文件或者目录到镜像中。• RUN:构建镜像的过程中,在基础镜像命令行中执行的命令。• CMD:创建容器时的默认命令,与 RUN 的区别在于,CMD 是创建容器时执行,而 RUN 是在构建镜像时执行,程序运行结束,容器也就结束。• ENV:在容器内设置环境变量,设置环境变量,可以在后续的指令中使用这个环境变量。

怎么用 Docker File 构建 YashanDB 镜像


<details><summary>点击查看代码</summary>


FROM centos:8.1.1911
RUN rm -rf /etc/yum.repos.d/*
COPY CentOS-Base.repo /etc/yum.repos.d/
RUN yum -y install glibc-locale-source glibc-langpack-en net-tools \ && yum clean all \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && localedef -c -f UTF-8 -i en_US en_US.UTF-8 \ && echo 'export LANG=zh_CN.utf8' > /etc/locale.conf \ && echo 'export LANG=zh_CN.utf8' >> /etc/profile \ && echo 'Asia/Shanghai' > /etc/timezone \ && source /etc/profile \ && echo "root:123456" | chpasswd \ && groupadd -g 1000 YASDBA \ && useradd yashan -G YASDBA \ && echo "yashan:yasdb_123" | chpasswd \ && echo 'yashan ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers
COPY yashandb-23.2.1.100-linux-x86_64.tar.gz /home/yashanCOPY initYashanDB.sh /home/yashan/RUN chown yashan:yashan /home/yashan/*
USER yashanWORKDIR /home/yashan/
ENV YASDB_HOME /home/yashan/ENV YASDB_DATA /home/yashan/yashandb/yasdb_data/db-1-1ENV PATH $PATH:${YASDB_HOME}/binENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:${YASDB_HOME}/lib
RUN cd ~ \ && tar -zxf yashandb-*.tar.gz \ && rm -rf yashandb-* \ && echo "YASDB_HOME=${YASDB_HOME}" >> ~/.bashrc \ && echo "YASDB_DATA=${YASDB_DATA}" >> ~/.bashrc \ && echo "PATH=\$PATH:\${YASDB_HOME}/bin" >> ~/.bashrc \ && echo "LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:\${YASDB_HOME}/lib" >> ~/.bashrc

CMD ["./initYashanDB.sh"]
复制代码


</details><details><summary>点击查看代码</summary>


#!/bin/bashcd /home/yashan/binyasboot package se gen --cluster yashandb -L --data-path $YASDB_DATA --begin-port 1688 --node 1yasboot package install -t hosts.toml -i /home/yashan/yashandb-23.2.1.100-linux-x86_64.tar.gzyasboot cluster deploy -t yashandb.tomlyasboot cluster password set -n yasdb_123 -c yashandb

while pgrep -x "yasdb" >/dev/null; do echo "check pgrep success, goto sleep!" sleep 360000 done
复制代码


</details>


注意点:


  • 容器挂载宿主机目录的时候,是覆盖操作,如果宿主机目录是空的,会清空容器内的目录,所以将 initYashanDB 放在了 CMD 中,而不是 RUN 中

  • CMD 运行结束,容器也就会退出,所以在./initYashanDB.sh 中最后添加了循环,避免 CMD 中的脚本执行完<details><summary>点击查看代码</summary>


docker build -t registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:X . --no-cachedocker run -itd  -p 1688:1688  -u 1000:1000 registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:Xdocker exec -it b bash
复制代码


</details>

YashanDB Docker 镜像的发布

在阿里云登录后,可以在阿里云容器镜像服务 ACR 中创建一个个人实例,然后将数据库镜像按照下面的操作发布到阿里云上:



执行下面的命令将本地构建的镜像发布推送至远程:<details><summary>点击查看代码</summary>


[root@localhost YLab]# docker push registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:XThe push refers to repository [registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb]c781b4b05ce5: Pushing [=>                                                 ]  15.93MB/518MB5f70bf18a086: Layer already exists 2e8a116c1b21: Pushing [>                                                  ]  3.869MB/198.7MBc499bfff3090: Pushed 6326c26c34ad: Pushing [>                                                  ]  2.754MB/198.7MB5f69ac739040: Pushing [===>                                               ]  4.385MB/64.98MB825123261bfe: Waiting 3e0aca5b6ad0: Waiting 0683de282177: Waiting 
复制代码


</details>



镜像发布成功后可以在镜像仓库中找到这个镜像:



YashanDB 容器启动添加初始化脚本

在 Docker 中,可以使用绑定挂载来实现容器内部文件与宿主机文件系统中文件的映射。以数联网一体机项目的应用场景为例,客户希望容器在数据库启动之后,能够自动执行指定文件夹中的 SQL 文件初始化数据库环境,这个 SQL 文件可能会发生变更,如果没有文件系统映射的话,那么就需要为每套 SQL 文件单独构建一个镜像,有了文件系统映射之后,可以将 SQL 文件放在宿主机的指定文件夹中,将这个文件夹与容器内的文件夹映射。<details><summary>点击查看代码</summary>


#!/bin/bash
cd /home/yashan/binyasboot package se gen --cluster yashandb -L --data-path $YASDB_DATA --begin-port 1688 --node 1yasboot package install -t hosts.toml -i /home/yashan/yashandb-23.2.1.100-linux-x86_64.tar.gzyasboot cluster deploy -t yashandb.tomlyasboot cluster password set -n yasdb_123 -c yashandb

while pgrep -x "yasdb" >/dev/null; do echo "check pgrep success, goto sleep!" sleep 360000 done

DIRECTORY="/home/yashan/sql"
if [ ! -d "$DIRECTORY" ]; then echo "Error: SQL directory '$DIRECTORY' does not exist." exit 1fi
if [ -f "${DIRECTORY}/ignoresql.pid" ] ; then echo "Ignore executing sql files"else for sql_file in $(ls -v "$DIRECTORY"/*.sql); do if [ -f "$sql_file" ] ; then echo "Processing ${sql_file}..." ${YASDB_HOME}/bin/yasql sys/yasdb_123 -f $sql_file if [ $? -ne 0 ]; then echo "Error executing yasql on $sql_file" exit 1 fi fi done echo "ignore" > "${DIRECTORY}/ignoresql.pid" echo "All sql files processed."fi
while pgrep -x "yasdb" >/dev/null; do echo "check pgrep success, goto sleep!" sleep 360000 done
复制代码


</details>容器启动的时候需要增加-v 参数,这样可以在容器中访问宿主机中的文件或目录,将 docker 容器内的数据保存进宿主机的磁盘中,实现数据的共享和持久化。<details><summary>点击查看代码</summary>


docker run -itd  -p 1688:1688  -v /home/yashan/sql:/home/yashan/sql:rw registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:X
复制代码


</details>

YashanDB 容器数据库数据文件的复用

数联网一体机项目的应用场景中,客户希望在容器启动时复用以往容器的 yasdb_data,此时不能再用 yasboot 的方式部署数据库,而应该使用以往的脚本部署方式:


<details><summary>点击查看代码</summary>


#!/bin/bashcd ~/scriptsbash /home/yashan/scripts/install.sh bash /home/yashan/scripts/initDB.sh
.....
while pgrep -x "yasdb" >/dev/null; do echo "check pgrep success, goto sleep!" sleep 360000 done
复制代码


</details><details><summary>点击查看代码</summary>


#!/bin/bash#initDB.sh
if [ -f "$YASDB_DATA"/config/yasdb.ini ]; then yashan_exists=1else yashan_exists=0fi
FILE_PATH=$(dirname "$(readlink -f "$0")")YASDB_TEMP_FILE="${FILE_PATH}/.temp.ini"INSTALL_INI_FILE="${FILE_PATH}/install.ini"YASDB_PASSWORD="yasdb_123"
# shellcheck disable=SC1090source "${YASDB_TEMP_FILE}"YASDB_ENV_FILE="${YASDB_HOME}/conf/yasdb.bashrc"YASDB_HOME_BIN_PATH="${YASDB_HOME}/bin"YASDB_BIN="${YASDB_HOME_BIN_PATH}/yasdb"YASQL_BIN="${YASDB_HOME_BIN_PATH}/yasql"YASPWD_BIN="${YASDB_HOME_BIN_PATH}/yaspwd"
# shellcheck disable=SC1090source "${YASDB_ENV_FILE}"
if [ ! -d "$YASDB_HOME" ] || [ ! -d "$YASDB_DATA" ]; then echo -e "Software installation \"./install.sh\" is not performed." exit 1fi
if [ $yashan_exists -eq 0 ]; thene_i=$(sed -n '$=' "$INSTALL_INI_FILE")s_i=$(sed -n -e '/\<instance\>/=' "$INSTALL_INI_FILE")n_i=$((s_i + 1))
sed -n "${n_i},${e_i} p" "$INSTALL_INI_FILE" >>"$YASDB_DATA"/config/yasdb.ini
##创建密码文件if [ ! -f "$YASDB_HOME/admin/yasdb.pwd" ]; then "$YASPWD_BIN" file="$YASDB_HOME"/admin/yasdb.pwd password="$YASDB_PASSWORD"else rm -f "$YASDB_HOME"/admin/yasdb.pwd "$YASPWD_BIN" file="$YASDB_HOME"/admin/yasdb.pwd password="$YASDB_PASSWORD"ficp "$YASDB_HOME"/admin/yasdb.pwd "$YASDB_DATA"/instance/yasdb.pwd

REDOFILE="("for ((i = 0; i < "$REDO_FILE_NUM"; i++)); do if [ $i == $((REDO_FILE_NUM - 1)) ]; then REDOFILE=${REDOFILE}"'redo${i}'"" size $REDO_FILE_SIZE)" else REDOFILE=${REDOFILE}"'redo${i}'"" size $REDO_FILE_SIZE," fidone
fi

##创建数据库START_LOG_FILE="$YASDB_DATA/log/start.log"rm -rf "${START_LOG_FILE}""${YASDB_BIN}" nomount -D "$YASDB_DATA" >"$START_LOG_FILE" 2>&1 &i=0while ((i < 5))do sleep 2 # shellcheck disable=SC2002 disable=SC2126 alive=$(cat "$START_LOG_FILE" | grep "Instance started" | wc -l) if [ "$alive" -ne 0 ]; then echo "process started!" break fi i=$((i+1))done
if [ "$i" -eq "5" ];then echo "start process failed. read $START_LOG_FILE" cat "$START_LOG_FILE" exit 1fi
if [ $yashan_exists -eq 0 ]; then"${YASQL_BIN}" sys/$YASDB_PASSWORD >>"$START_LOG_FILE" <<EOFcreate database yasdb CHARACTER SET $NLS_CHARACTERSET logfile $REDOFILE;exit;EOFfi

if [ $yashan_exists -eq 1 ]; then $YASQL_BIN sys/$YASDB_PASSWORD -c "alter database open"fi

i=0while ((i < 60))do sleep 1 alive=$($YASQL_BIN sys/$YASDB_PASSWORD -c "select open_mode from v\$database" | grep -c READ_WRITE) if [ "$alive" -eq 1 ]; then echo "Database open succeed !" break fi i=$((i+1))done
if [ "$i" -eq "60" ];then echo "Failed ! please check logfile $START_LOG_FILE ." exit 1fi
if [ $yashan_exists -eq 0 ]; then##创建样例数据:salesif [ "$INSTALL_SIMPLE_SCHEMA_SALES" == 'Y' ] || [ "$INSTALL_SIMPLE_SCHEMA_SALES" == 'y' ]; then "${YASQL_BIN}" sys/$YASDB_PASSWORD -f "$YASDB_HOME"/admin/simple_schema/sales.sql >>"$START_LOG_FILE"fifiexit 0
复制代码


</details>

用户头像

YashanDB

关注

全自研国产新型大数据管理系统 2022-02-15 加入

还未添加个人简介

评论

发布
暂无评论
YashanDB Docker镜像制作_数据库_YashanDB_InfoQ写作社区