Apache DolphinScheduler 是一個分散式去中心化,易擴充套件的視覺化 DAG 工作流任務排程系統。簡稱 DS,包括 Web 及若干服務,它依賴 PostgreSQL 和 Zookeeper,自身的服務模組包括:api, alert, master, worker(有一個 logger 服務,執行在 worker 中)等。詳細部署可以參考:Docker 部署 Dolphin Scheduler
官方提供了構建 Docker 映象的 Dockerfile,位於專案的 docker/build/ 目錄下,本文以 v1.3.8 版本為例,講解 Dockerfile 內的具體內容
Dockerfile 流程
v1.3.8 docker/build/ 目錄結構:
docker/build
├── checkpoint.sh
├── conf
│ └── dolphinscheduler
│ ├── alert.properties.tpl
│ ├── application-api.properties.tpl
│ ├── common.properties.tpl
│ ├── datasource.properties.tpl
│ ├── env
│ │ └── dolphinscheduler_env.sh.tpl
│ ├── logback
│ │ ├── logback-alert.xml
│ │ ├── logback-api.xml
│ │ ├── logback-master.xml
│ │ └── logback-worker.xml
│ ├── master.properties.tpl
│ ├── quartz.properties.tpl
│ ├── supervisor
│ │ └── supervisor.ini
│ ├── worker.properties.tpl
│ └── zookeeper.properties.tpl
├── Dockerfile
├── hooks
│ ├── build
│ ├── build.bat
│ ├── push
│ └── push.bat
├── startup-init-conf.sh
└── startup.sh
Dockerfile 流程:
- 引用基礎映象,設定環境變數
- 安裝所需的軟體依賴,設定時區
- 新增 DS 的專案檔案到容器中,設定工作目錄
- 將所需的指令碼和配置檔案拷貝到容器內指定目錄,並進行預先的處理
- 暴露網路埠
- 使用 Tini 程式管理器啟動 startup.sh
Dockerfile:
FROM openjdk:8-jre-slim-buster
# 需要在執行時使用 --build-arg <引數名>=<值> 覆蓋 VERSION 變數
ARG VERSION
# 使得 apt-get 在安裝過程不詢問問題
ARG DEBIAN_FRONTEND=noninteractive
# 時區選擇上海
ENV TZ Asia/Shanghai
# 修改編碼集,解決 Docker 容器亂碼
ENV LANG C.UTF-8
# 自定義環境變數,用於標識當前是 Docker 環境,在 dolphinscheduler-daemon.sh 中會引用該變數
ENV DOCKER true
ENV DOLPHINSCHEDULER_HOME /opt/dolphinscheduler
# 設定 Debian 的源,這段程式碼預設是註釋的,為了順利下載依賴,需要放開註釋
RUN { \
echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free"; \
echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free"; \
echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free"; \
echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free"; \
} > /etc/apt/sources.list
# 使用 apt-get update 更新軟體列表
# 使用 --no-install-recommends 來避免安裝非必須的檔案,以減小映象的體積
RUN apt-get update && \
apt-get install -y --no-install-recommends tzdata dos2unix python supervisor procps psmisc netcat sudo tini && \
echo "Asia/Shanghai" > /etc/timezone && \
rm -f /etc/localtime && \
dpkg-reconfigure tzdata && \
rm -rf /var/lib/apt/lists/* /tmp/*
# 需要將 Maven 構建的壓縮包 放在 Dockerfile 同級目錄,使用 ADD 命令會將 tar 壓縮包解壓到容器內
ADD ./apache-dolphinscheduler-${VERSION}-bin.tar.gz /opt/
# 使用軟連結將解壓後的資料夾連結到 /opt/dolphinscheduler
RUN ln -s -r /opt/apache-dolphinscheduler-${VERSION}-bin /opt/dolphinscheduler
# 設定工作目錄
WORKDIR /opt/apache-dolphinscheduler-${VERSION}-bin
# 拷貝配置檔案到容器內指定位置
COPY ./checkpoint.sh /root/checkpoint.sh
COPY ./startup-init-conf.sh /root/startup-init-conf.sh
COPY ./startup.sh /root/startup.sh
COPY ./conf/dolphinscheduler/*.tpl /opt/dolphinscheduler/conf/
COPY ./conf/dolphinscheduler/logback/* /opt/dolphinscheduler/conf/
COPY ./conf/dolphinscheduler/supervisor/supervisor.ini /etc/supervisor/conf.d/
COPY ./conf/dolphinscheduler/env/dolphinscheduler_env.sh.tpl /opt/dolphinscheduler/conf/env/
# 使用 sed 替換配置中的檔案字尾
# 使用 dos2unix 將指令碼中 \r\n 轉換為\n,避免指令碼執行錯誤
# 刪除 /bin/sh 使用 bash
# echo PS1=\"\\w \\$ \" >> ~/.bashrc:修改命令提示符設定(PS1) 格式
# Set disable_coredump false:重新啟用核心轉儲,以解決容器內使用 sudo 導致的 Operation not permitted 問題
RUN sed -i 's/*.conf$/*.ini/' /etc/supervisor/supervisord.conf && \
dos2unix /root/checkpoint.sh && \
dos2unix /root/startup-init-conf.sh && \
dos2unix /root/startup.sh && \
dos2unix /opt/dolphinscheduler/script/*.sh && \
dos2unix /opt/dolphinscheduler/bin/*.sh && \
rm -f /bin/sh && \
ln -s /bin/bash /bin/sh && \
mkdir -p /tmp/xls && \
echo PS1=\"\\w \\$ \" >> ~/.bashrc && \
echo "Set disable_coredump false" >> /etc/sudo.conf
# 暴露埠
EXPOSE 5678 1234 12345 50051
# 使用 Tini 啟動 /root/startup.sh
ENTRYPOINT ["/usr/bin/tini", "--", "/root/startup.sh"]
使用的基礎映象是:openjdk:8-jre-slim-buster
使用到了 ARG 和 ENV 設定環境變數:ARG 設定的環境變數僅在構建期間可用,在將來容器執行時是不會存在的
ENV DOCKER true
是為了標識當前是 Docker 環境,在dolphinscheduler-daemon.sh 中會引用該變數,新增 JVM 引數:-XX:-UseContainerSupport,這允許JVM 從主機讀取 cgroup 限制,例如可用的 CPU 和 RAM,並進行相應的配置。這樣當容器超過記憶體限制時,會丟擲 OOM 異常,而不是殺死容器
主要安裝了這些依賴:tzdata dos2unix python supervisor procps psmisc netcat sudo tini
使用 echo "Asia/Shanghai" > /etc/timezone && rm -f /etc/localtime && dpkg-reconfigure tzdata &&
設定容器時區
因為已經完成依賴安裝了所以可以使用 rm -rf /var/lib/apt/lists/* /tmp/*
刪除軟體列表和臨時目錄,減小壓映象體積
Supervisor 是用Python開發的一套通用的程式管理程式,能將一個普通的命令列程式變為後臺 daemon,並監控程式狀態,它的配置檔案是:/etc/supervisor/supervisord.conf,配置中包含下面的配置,預設引入 /etc/supervisor/conf.d/ 下的所有 .conf 檔案
[include]
files = /etc/supervisor/conf.d/*.conf
Dockerfile 將自定義的配置檔案拷貝到容器內指定的目錄,其中:將conf/dolphinscheduler/supervisor/supervisor.ini 拷貝到 /etc/supervisor/conf.d/目錄下,supervisor.ini 是 .ini
而 Supervisor 預設配置是 .conf
,為了使 Supervisor 能夠讀取到自定義的配置,使用命令 sed -i 's/*.conf$/*.ini/' /etc/supervisor/supervisord.conf
將 *.conf
替換為 *.ini
,就變成了下面的樣子
[include]
files = /etc/supervisor/conf.d/*.ini
Windows格式檔案的換行符為 \r\n ,而Unix&Linux檔案的換行符為 \n ,dos2unix命令其實就是將檔案中的 \r\n 轉換為 \n
使用 Tini 程式管理器,它是一個最小化到 init 系統,執行在容器內部,用於啟動一個子程式,並等待程式退出時清理殭屍和執行訊號轉發,它是一個替代龐大複雜的 systemd 體系的解決方案
startup.sh 主要做了這些事:
- 檢查資料庫連線
- 初始化資料庫,執行
script/create-dolphinscheduler.sh
,最終執行org.apache.dolphinscheduler.dao.upgrade.shell.CreateDolphinScheduler
Java 程式 - 檢查 zookeeper 連線
- 初始化配置檔案:執行
startup-init-conf.sh
,這個指令碼定義了各個引數的預設配置,遍歷所有 的 tpl 檔案,填充配置的值,輸出填充後的配置檔案 - 讀取執行 Shell 時傳入的第一個引數 ($1),根據這個判斷需要啟動哪些服務
- 建立 logs 目錄
- 啟動 supervisord,supervisord 會間接讀取
supervisor.ini
的配置,這裡定義了每個服務啟動的方式,通過呼叫dolphinscheduler-daemon.sh
執行具體的啟動邏輯
構建映象
使用 打包 apache-dolphinscheduler-${VERSION}-bin.tar.gz 這裡的 VERSION 為 1.3.8-SNAPSHOT
mvn -U clean package -Prelease -Dmaven.test.skip=true
將壓縮包拷貝到 docker/build/ 下,使用 --build-arg 傳入版本,構建 Docker 映象
docker build --build-arg VERSION=1.3.8-SNAPSHOT -t apache/dolphinscheduler:1.3.8-SNAPSHOT .
參考資料
When building from Dockerfile, Debian/Ubuntu package install debconf Noninteractive install not allowed
Ubuntu的安裝引數DEBIAN_FRONTEND詳解
容器環境的JVM記憶體設定最佳實踐
apt-get install 的引數(add-apt-repository)
Dockerfile設定時區
Docker 中如何設定 container 的時區
Docker tini程式管理器
Supervisor使用詳解
SED 簡明教程
linux系統終端命令提示符設定(PS1)記錄
sudo: setrlimit(RLIMIT_CORE): Operation not permitted
What does the curly-brace syntax ${var%.*} mean?
linux bash shell之變數替換::=句法、=句法、:-句法、-句法、=?句法、?句法、:+句法、+句法