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/ 目錄結構:

  1. docker/build
  2. ├── checkpoint.sh
  3. ├── conf
  4.    └── dolphinscheduler
  5.    ├── alert.properties.tpl
  6.    ├── application-api.properties.tpl
  7.    ├── common.properties.tpl
  8.    ├── datasource.properties.tpl
  9.    ├── env
  10.       └── dolphinscheduler_env.sh.tpl
  11.    ├── logback
  12.       ├── logback-alert.xml
  13.       ├── logback-api.xml
  14.       ├── logback-master.xml
  15.       └── logback-worker.xml
  16.    ├── master.properties.tpl
  17.    ├── quartz.properties.tpl
  18.    ├── supervisor
  19.       └── supervisor.ini
  20.    ├── worker.properties.tpl
  21.    └── zookeeper.properties.tpl
  22. ├── Dockerfile
  23. ├── hooks
  24.    ├── build
  25.    ├── build.bat
  26.    ├── push
  27.    └── push.bat
  28. ├── startup-init-conf.sh
  29. └── startup.sh

Dockerfile 流程:

  1. 引用基礎映象,設定環境變數
  2. 安裝所需的軟體依賴,設定時區
  3. 新增 DS 的專案檔案到容器中,設定工作目錄
  4. 將所需的指令碼和配置檔案拷貝到容器內指定目錄,並進行預先的處理
  5. 暴露網路埠
  6. 使用 Tini 程序管理器啟動 startup.sh

Dockerfile:

  1. FROM openjdk:8-jre-slim-buster
  2. # 需要在執行時使用 --build-arg <引數名>=<值> 覆蓋 VERSION 變數
  3. ARG VERSION
  4. # 使得 apt-get 在安裝過程不詢問問題
  5. ARG DEBIAN_FRONTEND=noninteractive
  6. # 時區選擇上海
  7. ENV TZ Asia/Shanghai
  8. # 修改編碼集,解決 Docker 容器亂碼
  9. ENV LANG C.UTF-8
  10. # 自定義環境變數,用於標識當前是 Docker 環境,在 dolphinscheduler-daemon.sh 中會引用該變數
  11. ENV DOCKER true
  12. ENV DOLPHINSCHEDULER_HOME /opt/dolphinscheduler
  13. # 設定 Debian 的源,這段程式碼預設是註釋的,為了順利下載依賴,需要放開註釋
  14. RUN { \
  15. echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free"; \
  16. echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free"; \
  17. echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free"; \
  18. echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free"; \
  19. } > /etc/apt/sources.list
  20. # 使用 apt-get update 更新軟體列表
  21. # 使用 --no-install-recommends 來避免安裝非必須的檔案,以減小映象的體積
  22. RUN apt-get update && \
  23. apt-get install -y --no-install-recommends tzdata dos2unix python supervisor procps psmisc netcat sudo tini && \
  24. echo "Asia/Shanghai" > /etc/timezone && \
  25. rm -f /etc/localtime && \
  26. dpkg-reconfigure tzdata && \
  27. rm -rf /var/lib/apt/lists/* /tmp/*
  28. # 需要將 Maven 構建的壓縮包 放在 Dockerfile 同級目錄,使用 ADD 命令會將 tar 壓縮包解壓到容器內
  29. ADD ./apache-dolphinscheduler-${VERSION}-bin.tar.gz /opt/
  30. # 使用軟連結將解壓後的資料夾連結到 /opt/dolphinscheduler
  31. RUN ln -s -r /opt/apache-dolphinscheduler-${VERSION}-bin /opt/dolphinscheduler
  32. # 設定工作目錄
  33. WORKDIR /opt/apache-dolphinscheduler-${VERSION}-bin
  34. # 拷貝配置檔案到容器內指定位置
  35. COPY ./checkpoint.sh /root/checkpoint.sh
  36. COPY ./startup-init-conf.sh /root/startup-init-conf.sh
  37. COPY ./startup.sh /root/startup.sh
  38. COPY ./conf/dolphinscheduler/*.tpl /opt/dolphinscheduler/conf/
  39. COPY ./conf/dolphinscheduler/logback/* /opt/dolphinscheduler/conf/
  40. COPY ./conf/dolphinscheduler/supervisor/supervisor.ini /etc/supervisor/conf.d/
  41. COPY ./conf/dolphinscheduler/env/dolphinscheduler_env.sh.tpl /opt/dolphinscheduler/conf/env/
  42. # 使用 sed 替換配置中的檔案字尾
  43. # 使用 dos2unix 將指令碼中 \r\n 轉換為\n,避免指令碼執行錯誤
  44. # 刪除 /bin/sh 使用 bash
  45. # echo PS1=\"\\w \\$ \" >> ~/.bashrc:修改命令提示符設定(PS1) 格式
  46. # Set disable_coredump false:重新啟用核心轉儲,以解決容器內使用 sudo 導致的 Operation not permitted 問題
  47. RUN sed -i 's/*.conf$/*.ini/' /etc/supervisor/supervisord.conf && \
  48. dos2unix /root/checkpoint.sh && \
  49. dos2unix /root/startup-init-conf.sh && \
  50. dos2unix /root/startup.sh && \
  51. dos2unix /opt/dolphinscheduler/script/*.sh && \
  52. dos2unix /opt/dolphinscheduler/bin/*.sh && \
  53. rm -f /bin/sh && \
  54. ln -s /bin/bash /bin/sh && \
  55. mkdir -p /tmp/xls && \
  56. echo PS1=\"\\w \\$ \" >> ~/.bashrc && \
  57. echo "Set disable_coredump false" >> /etc/sudo.conf
  58. # 暴露埠
  59. EXPOSE 5678 1234 12345 50051
  60. # 使用 Tini 啟動 /root/startup.sh
  61. 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 檔案

  1. [include]
  2. 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,就變成了下面的樣子

  1. [include]
  2. files = /etc/supervisor/conf.d/*.ini

Windows格式檔案的換行符為 \r\n ,而Unix&Linux檔案的換行符為 \n ,dos2unix命令其實就是將檔案中的 \r\n 轉換為 \n

使用 Tini 程序管理器,它是一個最小化到 init 系統,執行在容器內部,用於啟動一個子程序,並等待程序退出時清理殭屍和執行訊號轉發,它是一個替代龐大複雜的 systemd 體系的解決方案

startup.sh 主要做了這些事:

  1. 檢查資料庫連線
  2. 初始化資料庫,執行 script/create-dolphinscheduler.sh,最終執行 org.apache.dolphinscheduler.dao.upgrade.shell.CreateDolphinScheduler Java 程式
  3. 檢查 zookeeper 連線
  4. 初始化配置檔案:執行 startup-init-conf.sh ,這個指令碼定義了各個引數的預設配置,遍歷所有 的 tpl 檔案,填充配置的值,輸出填充後的配置檔案
  5. 讀取執行 Shell 時傳入的第一個引數 ($1),根據這個判斷需要啟動哪些服務
  6. 建立 logs 目錄
  7. 啟動 supervisord,supervisord 會間接讀取 supervisor.ini 的配置,這裡定義了每個服務啟動的方式,通過呼叫 dolphinscheduler-daemon.sh 執行具體的啟動邏輯

構建映象

使用 打包 apache-dolphinscheduler-${VERSION}-bin.tar.gz 這裡的 VERSION 為 1.3.8-SNAPSHOT

  1. mvn -U clean package -Prelease -Dmaven.test.skip=true

將壓縮包拷貝到 docker/build/ 下,使用 --build-arg 傳入版本,構建 Docker 映象

  1. 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之變數替換::=句法、=句法、:-句法、-句法、=?句法、?句法、:+句法、+句法