YashanDB Docker鏡像製作

来源:https://www.cnblogs.com/YashanDB/p/18442176
-Advertisement-
Play Games

本文作者:YashanDB中級服務工程師鮑健昕 為什麼需要Docker部署資料庫 常規使用 yasboot 部署資料庫的方法,操作流程複雜,需要配置許多配置文件以及環境變數,不同用戶使用的環境不同,那麼環境配置也會存在差異,每當更換機器或者有新系統開發時都要就要重覆不熟⼀次。 使用 Docker 後 ...


本文作者: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鏡像

點擊查看代碼
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/yashan
COPY initYashanDB.sh /home/yashan/
RUN chown yashan:yashan /home/yashan/*

USER yashan
WORKDIR /home/yashan/

ENV YASDB_HOME /home/yashan/
ENV YASDB_DATA /home/yashan/yashandb/yasdb_data/db-1-1
ENV PATH $PATH:${YASDB_HOME}/bin
ENV 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"]
點擊查看代碼
#!/bin/bash
cd /home/yashan/bin
yasboot package se gen --cluster yashandb -L --data-path $YASDB_DATA --begin-port 1688 --node 1
yasboot package install -t hosts.toml -i /home/yashan/yashandb-23.2.1.100-linux-x86_64.tar.gz
yasboot cluster deploy -t yashandb.toml
yasboot cluster password set -n yasdb_123 -c yashandb


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

註意點:

  • 容器掛載宿主機目錄的時候,是覆蓋操作,如果宿主機目錄是空的,會清空容器內的目錄,所以將initYashanDB放在了CMD中,而不是RUN中

  • CMD運行結束,容器也就會退出,所以在./initYashanDB.sh中最後添加了迴圈,避免CMD中的腳本執行完

點擊查看代碼
docker build -t registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:X . --no-cache
docker run -itd  -p 1688:1688  -u 1000:1000 registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:X
docker exec -it b bash

YashanDB Docker鏡像的發佈

在阿裡雲登錄後,可以在阿裡雲容器鏡像服務ACR中創建一個個人實例,然後將資料庫鏡像按照下麵的操作發佈到阿裡雲上:

執行下麵的命令將本地構建的鏡像發佈推送至遠程:

點擊查看代碼
[root@localhost YLab]# docker push registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:X
The push refers to repository [registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb]
c781b4b05ce5: Pushing [=>                                                 ]  15.93MB/518MB
5f70bf18a086: Layer already exists 
2e8a116c1b21: Pushing [>                                                  ]  3.869MB/198.7MB
c499bfff3090: Pushed 
6326c26c34ad: Pushing [>                                                  ]  2.754MB/198.7MB
5f69ac739040: Pushing [===>                                               ]  4.385MB/64.98MB
825123261bfe: Waiting 
3e0aca5b6ad0: Waiting 
0683de282177: Waiting 

鏡像發佈成功後可以在鏡像倉庫中找到這個鏡像:

YashanDB容器啟動添加初始化腳本

在Docker中,可以使用綁定掛載來實現容器內部文件與宿主機文件系統中文件的映射。以數聯網一體機項目的應用場景為例,客戶希望容器在資料庫啟動之後,能夠自動執行指定文件夾中的SQL文件初始化資料庫環境,這個SQL文件可能會發生變更,如果沒有文件系統映射的話,那麼就需要為每套SQL文件單獨構建一個鏡像,有了文件系統映射之後,可以將SQL文件放在宿主機的指定文件夾中,將這個文件夾與容器內的文件夾映射。

點擊查看代碼
#!/bin/bash

cd /home/yashan/bin
yasboot package se gen --cluster yashandb -L --data-path $YASDB_DATA --begin-port 1688 --node 1
yasboot package install -t hosts.toml -i /home/yashan/yashandb-23.2.1.100-linux-x86_64.tar.gz
yasboot cluster deploy -t yashandb.toml
yasboot 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 1
fi

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  
容器啟動的時候需要增加-v參數,這樣可以在容器中訪問宿主機中的文件或目錄,將docker容器內的數據保存進宿主機的磁碟中,實現數據的共用和持久化。
點擊查看代碼
docker run -itd  -p 1688:1688  -v /home/yashan/sql:/home/yashan/sql:rw registry.cn-shenzhen.aliyuncs.com/jesseatyashan/yashandb:X

YashanDB容器資料庫數據文件的復用

數聯網一體機項目的應用場景中,客戶希望在容器啟動時復用以往容器的yasdb_data,此時不能再用yasboot的方式部署資料庫,而應該使用以往的腳本部署方式:

點擊查看代碼
#!/bin/bash
cd ~/scripts
bash /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  
點擊查看代碼
#!/bin/bash
#initDB.sh

if [ -f "$YASDB_DATA"/config/yasdb.ini ]; then
    yashan_exists=1
else
    yashan_exists=0
fi

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=SC1090
source "${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=SC1090
source "${YASDB_ENV_FILE}"

if [ ! -d "$YASDB_HOME" ] || [ ! -d "$YASDB_DATA" ]; then
    echo -e "Software installation \"./install.sh\" is not performed."
    exit 1
fi

if [ $yashan_exists -eq 0 ]; then
e_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"
fi
cp "$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,"
    fi
done

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=0
while ((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 1
fi

if [ $yashan_exists -eq 0 ]; then
"${YASQL_BIN}" sys/$YASDB_PASSWORD >>"$START_LOG_FILE" <<EOF
create database yasdb CHARACTER SET $NLS_CHARACTERSET logfile $REDOFILE;
exit;
EOF
fi


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


i=0
while ((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 1
fi

if [ $yashan_exists -eq 0 ]; then
##創建樣例數據:sales
if [ "$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"
fi
fi
exit 0

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文介紹在Windows電腦中,下載、配置MobaXterm軟體,從而連接、操作遠程伺服器的方法。 因為是在Windows操作系統的電腦中連接伺服器,所以建議使用MobaXterm、PuTTY等可視化的遠程電腦管理軟體,來實現對伺服器的連接與後續相關操作。在本文中,我們就選擇基於MobaXterm ...
  • scanf標準函數可以從鍵盤得到數字並記錄到存儲區里,為了使用這個標準函數需要包含stdio.h這個頭文件 在scanf函數調用語句里應該使用存儲區的地址表示存儲區;雙引號里使用占位符表示存儲區的類型, 在scanf函數調用語句里儘量不要寫不是占位符的內容,如果用戶輸入的格式和程式要求的格式不同 程 ...
  • C語言里提供了一組工具,他們叫做標準函數;每個標準函數用來解決一個常見問題 不同標準函數名字不同,可以在程式里編寫函數調用語句使用標準函數 printf標準函數可以用來把程式里的數字顯示在終端視窗里 為了使用這個標準函數需要包含stdio.h頭文件 可以在雙引號里使用占位符(%+類型)把數字轉移到雙 ...
  • 一、簡介 zabbix是一個基於[WEB]界面的提供分散式[系統監視]以及網路監視功能的企業級的開源解決方案。zabbix能監視各種網路參數,保證[伺服器系統]的安全運營;並提供靈活的通知機制以讓[系統管理員]快速定位/解決存在的各種問題。 二、安裝配置 1. 關閉防火牆和selinux syste ...
  • 此文檔的作用為:提供一個學習方法、例舉出一些有學習意義的學習視頻和文檔,供0基礎的你參考和學習。此處的學習可能有助於提升對於嵌入式整體的興趣和概念的瞭解。 ...
  • 執行 `arch -x86_64 zsh`報`arch: posix_spawnp: zsh: Bad CPU type in executable` 原因: 未安裝rosetta 執行`softwareupdate --install-rosetta`安裝rosetta報 ``` Package... ...
  • 正點原子《ESP32物聯網項目實戰》全新培訓課程上線啦!正點原子工程師手把手教你學!通過多個項目實戰,掌握ESP32物聯網項目的開發! 一、課程介紹 本課程圍繞物聯網實戰項目展開教學,內容循序漸進,涵蓋了環境搭建、編程軟體使用、模塊基礎驅動、物聯網基礎知識和多個實戰項目等等。在物聯網項目的選擇上,我 ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是恩智浦i.MX RTxxx系列MCU的新品i.MXRT700。 四年前恩智浦官宣了面向下一代智能穿戴設備的 i.MXRT500 系列,這個系列在智能手錶領域大獲成功,無數大小品牌智能手錶製造商(谷歌、佳明Garmin、華米Amazfit ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...