StarRocks 容器映象構建

小得盈满發表於2024-07-07

StarRocks 官方只提供了單節點執行的映象,如果是構建可以分散式執行的 StarRocks 的容器映象,那麼基於基礎映象可以有兩種選擇,分別是:starrocks/artifacts-ubuntu 和 starrocks/allin1-ubuntu,這兩個都是基於 Ubuntu 22.04 的基礎映象。其中前者是其中只包含 StarRocks 編譯好的安裝檔案,並不包含任何可執行的環境,需要摳出來放到 Ubuntu 22.04 環境上才可以執行,而且需要安裝 JDK 等基礎映象。而後者是編寫了具體的啟動指令碼,可以單機執行所有的服務,作為快速開始使用的,所以裡面很多必要的環境都存在,我們可以基於 allin1-ubuntu 做一些修改即可和標準執行方式一樣。

artifacts-ubuntu Docker Hub 地址:https://hub.docker.com/r/starrocks/artifacts-ubuntu/tags

allin1-ubuntu Docker Hub 地址:https://hub.docker.com/r/starrocks/allin1-ubuntu/tags

如果基於 artifacts-ubuntu 構建需要我們將映象裡面的安裝檔案複製出來,然後自己編寫 Dockerfile 實現,例如:

FROM ubuntu:22.04

RUN sed -i "s@http://.*archive.ubuntu.com@http://mirrors.huaweicloud.com@g" /etc/apt/sources.list && sed -i "s@http://.*security.ubuntu.com@http://mirrors.huaweicloud.com@g" /etc/apt/sources.list
RUN apt update && apt install -y openjdk-11-jdk libbinutils

WORKDIR /opt/StarRocks-3.2.3

ADD starrocks-artifacts/ .

CMD ["/bin/bash", "-c", "echo \"StarRocks.\""]

而且這樣 FE 和 BE 必須單獨啟動,也就是啟動兩個容器。另外這個映象體積比較大,有 8 個多 GB,原因是 BE 包含了 debuginfo 符號表,這個是方便開發人員 GDB 除錯的,正常執行不需要,所以我們最好刪除 be/lib/starrocks_be.debuginfo 這個檔案。

另外是使用 allin1-ubuntu 映象,裡面使用 Supervisor 來管理 FE 和 BE 等程序,這樣比較合理,所以我們可以直接基於這個映象做一些修改,首先執行映象並進入容器:

docker run -it starrocks/allin1-ubuntu:3.2.3 /bin/bash

然後我們修改 Supervisor 配置檔案 /etc/supervisor/supervisord.conf 在其中調大檔案數限制:

[supervisord]
# 新增配置
minfds=1048576

然後檢視指令碼 entrypoint.sh 預設如下:

#!/bin/bash
# Copyright 2021-present StarRocks, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

get_fe_http_port()
{
    source $SR_HOME/fe/bin/common.sh
    export_env_from_conf $SR_HOME/fe/conf/fe.conf
    echo ${http_port:-8030}
}

update_feproxy_config()
{
    # process fe http_port from a sub shell to avoid env var escalation
    fehttpport=`get_fe_http_port`
    cat $SR_HOME/feproxy/feproxy.conf.template | sed -e "s|{{feproxyhome}}|$SR_HOME/feproxy|g" -e "s|{{fewebport}}|${fehttpport}|g" > $SR_HOME/feproxy/feproxy.conf
}

setup_priority_networks()
{
    echo "priority_networks = 127.0.0.1/32" >> $SR_HOME/fe/conf/fe.conf
    echo "priority_networks = 127.0.0.1/32" >> $SR_HOME/be/conf/be.conf
}

# print banner
if [ -f $SR_HOME/../banner.txt ] ; then
    cat $SR_HOME/../banner.txt
fi

# setup log directories
mkdir -p $SR_HOME/{supervisor,fe,be,apache_hdfs_broker,feproxy}/log

update_feproxy_config
# use 127.0.0.1 for all the services, include fe/be/broker
setup_priority_networks

# setup supervisor and start
SUPERVISORD_HOME=$SR_HOME/supervisor
# allow supervisorctl to find the correct supervisord.conf
ln -sfT $SUPERVISORD_HOME/supervisord.conf /etc/supervisord.conf

cd $SUPERVISORD_HOME
exec supervisord -n -c $SUPERVISORD_HOME/supervisord.conf

這其中執行了 setup_priority_networks 函式,會將配置追加到 fe.confbe.conf ,但是我們需要將這個配置檔案複製出來再對映進去,所以不需要每次都執行,我們將這行函式註釋掉。

然後我們把容器內的配置檔案複製到容器外面:

docker cp dddddbc9232a:/data/deploy/starrocks/fe/conf/fe.conf .
docker cp dddddbc9232a:/data/deploy/starrocks/be/conf/be.conf .

最後我們再編輯 /data/deploy/starrocks/supervisor/supervisord.conf,預設內容如下:

[unix_http_server]
file=%(ENV_SR_HOME)s/supervisor/supervisor.sock


[supervisord]
logfile=%(ENV_SR_HOME)s/supervisor/log/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=%(ENV_SR_HOME)s/supervisor/supervisord.pid
user=root
nodaemon=true


[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface


[supervisorctl]
serverurl=unix://%(ENV_SR_HOME)s/supervisor/supervisor.sock


[program:feservice]
command=%(ENV_SR_HOME)s/fe/bin/start_fe.sh
numprocs=1
directory=%(ENV_SR_HOME)s/fe
autostart=true
autorestart=true
startsecs=5
startretries=3
stopwaitsecs=15
stopasgroup=true
killasgroup=true
redirect_stderr=true
stdout_logfile=%(ENV_SR_HOME)s/fe/log/fe.out
stdout_logfile_maxbytes=200MB
stdout_logfile_backups=20


[program:beservice]
command=%(ENV_SR_HOME)s/be/bin/start_be.sh
numprocs=1
directory=%(ENV_SR_HOME)s/be
autostart=true
autorestart=true
startsecs=5
startretries=3
# do force kill before BE is good with graceful shutdown
stopsignal=KILL
stopwaitsecs=15
stopasgroup=true
killasgroup=true
redirect_stderr=true
stdout_logfile=%(ENV_SR_HOME)s/be/log/be.out
stdout_logfile_maxbytes=200MB
stdout_logfile_backups=20


[program:broker]
command=%(ENV_SR_HOME)s/apache_hdfs_broker/bin/start_broker.sh
numprocs=1
directory=%(ENV_SR_HOME)s/apache_hdfs_broker
autostart=true
autorestart=true
startsecs=5
startretries=3
stopwaitsecs=15
stopasgroup=true
killasgroup=true
redirect_stderr=true
stdout_logfile=%(ENV_SR_HOME)s/apache_hdfs_broker/log/apache_hdfs_broker.out
stdout_logfile_maxbytes=200MB
stdout_logfile_backups=20


[program:feproxy]
command=nginx -g "daemon off;" -c %(ENV_SR_HOME)s/feproxy/feproxy.conf
numprocs=1
directory=%(ENV_SR_HOME)s/feproxy
autostart=true
autorestart=true
startsecs=5
startretries=3
stopwaitsecs=15
redirect_stderr=true
stdout_logfile=%(ENV_SR_HOME)s/feproxy/log/feproxy.out
stdout_logfile_maxbytes=200MB
stdout_logfile_backups=20


[program:director]
command=%(ENV_SR_HOME)s/director/run.sh
numprocs=1
directory=%(ENV_SR_HOME)s/director
autostart=true
autorestart=true
startsecs=5
startretries=3
stopwaitsecs=15
redirect_stderr=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0

其中 brokerfeproxy 以及 director 的配置我們用不到,如果開啟 director 由於叢集配置了密碼等還會導致報錯重啟,所以這個沒必要開啟,因此將這幾個塊直接刪除掉即可,刪除後儲存配置檔案。

最後我們清理歷史命令:

history -c
# 退出容器
exit

然後我們將容器儲存為映象:

docker commit -m "StarRocks 3.2.3 from allin1-ubuntu:3.2.3" dddddbc9232a starrocks:3.2.3

然後我們使用 Docker Compose 管理 StarRocks 程序,建立 docker-compose.yml 配置如下:

version: '3'
services:
  starrocks:
    image: starrocks:3.2.3
    container_name: starrocks-container
    command: ./entrypoint.sh
    restart: always
    network_mode: "host"
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./conf/fe.conf:/data/deploy/starrocks/fe/conf/fe.conf
      - ./conf/be.conf:/data/deploy/starrocks/be/conf/be.conf
      - /var/log/starrocks/fe:/data/deploy/starrocks/fe/log
      - /var/log/starrocks/be:/data/deploy/starrocks/be/log
      - /data/starrocks/meta:/data/deploy/starrocks/fe/meta
      - /data/starrocks/storage:/data/deploy/starrocks/be/storage

為了保證效能我們直接使用主機網路模式,這樣我們只需要正常配置我們外部的配置檔案即可,所有的埠都是直接在主機上監聽,所以不要忘記修改 priority_networks 配置。另外我們分別對映了 StarRocks 的 FE 和 BE 日誌目錄,這個也無需修改內部的配置。最後就是資料目錄,我們將外部自定義的資料目錄對映到了內部預設位置,所以配置檔案中的資料目錄也無需修改,只需要修改我們對映的外部目錄即可。但是我們要加上 command 指定容器啟動的命令,因為我們後面進入容器的時候用了 /bin/bash 這樣會將原有映象預設的 CMD 覆蓋掉,當我們提交映象後預設就變成容器初次啟動時的命令 /bin/bash 了,這個時候我們也可以用 entrypoint.sh 啟動一次映象再提交,或者是初次啟動容器時用預設命令,我們再用 docker exec 進入容器這樣也不會破壞原有映象預設的入口。

另外注意如果是從之前手動部署的 StarRocks 叢集上升級成容器化叢集,那麼需要設定容器的主機名,如果是 IP 地址訪問那麼需要將主機名設定為 IP:

version: '3'
services:
  starrocks:
    hostname: x.x.x.x

否則如果啟用了主機名訪問,那麼需要設定為本機實際的主機名並且需要對映主機的 hosts 檔案:

version: '3'
services:
  starrocks:
    hostname: host1

預設主機上的 /etc/hosts會自動對映進去可以無需其他配置。

經過上面的調整這樣才可以正常啟動,否則會報錯:

Detect FE service hostname mismatch, FE service won't start.
This is probably caused by persisted fe/meta from outside container, but the container's hostname is not fixed. If running with docker engine, use '-h <hostname>' to assign a fixed hostname and restart.

因為原來的叢集 meta 資訊已經儲存了原來的主機名,啟動的時候 FE 會進行校驗,不符合將會退出。如果是新部署叢集則沒有這個問題。

相關文章