天天看点

制作greenplum docker镜像

作者:土桥浪子

思路

将greenplum(gp)的离线安装包添加到docker镜像中,容器启动的时候判断是否已经完成gp安装,若未安装,则利用shell脚本完成对greenplum的安装;否则,直接启动gp。

各种脚本已上传到gitee仓库,链接地址在文章末尾

准备工作

github下载open-source-greenplum-db-6.23.0-rhel7-x86_64.rpm离线安装文件

使用说明

  • 创建的gp数据库默认用户名: gpadmin 密码为: 1qaz#EDC
  • 默认使用/data作为gp的数据目录
  • 在Dockerfile可自定义用户名、密码、数据目录

将install.sh entrypoint.sh Dockerfile下载到同一个文件夹中

在该文件夹中执行以下命令构建docker镜像,启动数据库

# lzy/greenplum这是我定义的镜像名称,可自行调整
docker build -t lzy/greenplum:6.23.0 .

# 启动数据库(后台模式启动)
docker run -d --name greenplum -p 5432:5432 lzy/greenplum:6.23.0           

install.sh

#!/bin/bash
############################################
# Function :  Greenplum单机版一键安装脚本
# Author : 土桥浪子
# Date : 2023-01-08
#
# Usage: sh install.sh
#
############################################

GP_RPM_PATH=${ENV_GP_RPM_PATH-"/opt/software/greenplum/open-source-greenplum-db-6.23.0-rhel7-x86_64.rpm"}

# 账号密码,未设置环境变量时,默认gpadmin:1qza#EDC作为用户名密码
GP_USERNAME=${ENV_GP_USERNAME-"gpadmin"}
GP_PASSWORD=${ENV_GP_PASSWORD-"1qaz#EDC"}

# 数据根目录
GP_DATA_DIR=${ENV_GP_DATA_DIR-"/data"}

# 日志等级
ERROR_MSG="[ERROR] "
INFO_MSG="[INFO] "

# 安装数据库
function install_greenplum(){
    log "$INFO_MSG Start to install greenplum for single node."

    # 安装数据库
    install_db

    # 创建用户和用户组
    create_user_group

    # 设置ssh免密
    set_ssh_none_pwd

    # 创建数据目录
    create_data_directory

    # 初始化db配置
    init_db_config
    
    log "$INFO_MSG install greenplum for single node finished."
    
}

function init_db_config() {
    log "$INFO_MSG begin config database configuration."
    
    # 添加节点文件
    cat > /home/$GP_USERNAME/seg_hosts << EOF
mdw
EOF
    # 初始化集群并修改配置
    rm -f /home/$GP_USERNAME/gpinitsystem_config

    cat > /home/$GP_USERNAME/gpinitsystem_config << EOF
#数据库代号
ARRAY_NAME="Greenplum Data Platform"
#segment前缀
SEG_PREFIX=gpseg
#primary segment起始的端口号
PORT_BASE=6000
#指定primary segment的数据目录,中间空格隔开,表示一台机器有多个segment
declare -a DATA_DIRECTORY=($GP_DATA_DIR/gpdata/primary)
#master所在机器的host name
MASTER_HOSTNAME=mdw
#master的数据目录
MASTER_DIRECTORY=$GP_DATA_DIR/gpdata/master
#master的端口号
MASTER_PORT=5432
#指定bash的版本
TRUSTED_SHELL=ssh
#将日志写入磁盘的间隔,每个段文件通常 =16MB < 2 * CHECH_POINT_SEGMENTS + 1
CHECK_POINT_SEGMENTS=8
#字符集
ENCODING=UNICODE
#mirror segment 起始的端口号
MIRROR_PORT_BASE=7000
#mirror的数据目录,和主数据一样
declare -a MIRROR_DATA_DIRECTORY=($GP_DATA_DIR/gpdata/mirror)
#数据库名称
DATABASE_NAME=gpdb
MACHINE_LIST_FILE=/home/$GP_USERNAME/seg_hosts
EOF

    cat > /home/$GP_USERNAME/initdb_gpdb.sql << EOF
ALTER ROLE "$GP_USERNAME" WITH PASSWORD '$ENV_GP_PASSWORD';
EOF
    
    log "$INFO_MSG complete config database configuration."
}

function set_ssh_none_pwd() {
    log "$INFO_MSG begin config ssh."
    
    # ssh配置
    sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
    sed -i -r 's/^.*StrictHostKeyChecking\s+\w+/StrictHostKeyChecking no/' /etc/ssh/ssh_config
    sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
    systemctl restart sshd

    # gpadmin账号的免密配置
    su $GP_USERNAME -l -c "ssh-keygen -t rsa -f ~/.ssh/id_rsa -q -P \"\""
    su $GP_USERNAME -l -c "cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys"
    su $GP_USERNAME -l -c "chmod 600 ~/.ssh/authorized_keys" && \
    su $GP_USERNAME -l -c "ssh-keyscan -H mdw 2>/dev/null | grep rsa | awk '{print \"mdw \" \$2 \" \" \$3 }' >> ~/.ssh/known_hosts"
    log "$INFO_MSG complete config ssh."
}

function create_data_directory() {
    log "$INFO_MSG begin create data directory."
    mkdir -p $GP_DATA_DIR/gpdata/master
    mkdir -p $GP_DATA_DIR/gpdata/primary
    mkdir -p $GP_DATA_DIR/gpdata/mirror
    # 给用户授权
    chown -R $GP_USERNAME:$GP_USERNAME $GP_DATA_DIR/gpdata
    log "$INFO_MSG complete create data directory."
}

# 创建用户和用户组
function create_user_group() {
    log "$INFO_MSG begin create user and usergroup."
    useradd $GP_USERNAME -d /home/$GP_USERNAME
    # 设置用户密码
    echo "${GP_PASSWORD}" | passwd --stdin $GP_USERNAME

    # 处理指定目录以及其子目录下的所有文件
    chown -R $GP_USERNAME /usr/local/greenplum*
    # 转变文件所属用户组
    chgrp -R $GP_USERNAME /usr/local/greenplum*
    log "$INFO_MSG complete create user and usergroup."
}

# 安装数据库
function install_db() {
    log "$INFO_MSG begin install rpm."
    yum -y install $GP_RPM_PATH
    rm -f $GP_RPM_PATH
    log "$INFO_MSG complete install rpm."
}

# 日志函数
function log() {
    TIME=$(date +"%Y-%m-%d %H:%M:%S")
    echo "$TIME $1"
}

# 安装操作
install_greenplum           

entrypoint.sh

#!/bin/bash
############################################
# Function :  EntryPoint入口
# Author : 土桥浪子
# Date : 2023-01-08
#
# Usage: sh entrypoint.sh
#
############################################

GP_USERNAME=${ENV_GP_USERNAME-"gpadmin"}
GP_DATA_DIR=${ENV_GP_DATA_DIR-"/data"}

/var/run/sshd/sshd_start.sh && sleep 5s

# 设置gpadmin账号的环境变量
su - $GP_USERNAME -l -c "echo -e 'source /usr/local/greenplum-db/greenplum_path.sh' >> ~/.bashrc"
su - $GP_USERNAME -l -c "echo -e 'export MASTER_DATA_DIRECTORY=$GP_DATA_DIR/gpdata/master/gpseg-1' >> ~/.bashrc"
su - $GP_USERNAME -l -c "echo -e 'export PGPORT=5432' >> ~/.bashrc"
su - $GP_USERNAME -l -c "echo -e 'export PGUSER=$GP_USERNAME' >> ~/.bashrc"
su - $GP_USERNAME -l -c "echo -e 'export PGDATABASE=postgres' >> ~/.bashrc"

# 数据库已初始化,则启动
if [ -f "/home/$GP_USERNAME/inited" ]; then
    su - $GP_USERNAME -l -c "source ~/.bashrc && gpstart -a && tail -f gpAdminLogs/*.log"
# 数据库未初始化,则初始化
else
    # 添加mdw到host中
    cat >> /etc/hosts << EOF
127.0.0.1 mdw
EOF
    # 创建数据库存放目录
    echo inited > /home/$GP_USERNAME/inited

    # 启动数据库集群
    su - $GP_USERNAME -l -c "source ~/.bashrc;gpinitsystem -a --ignore-warnings -c /home/$GP_USERNAME/gpinitsystem_config"
    
    sleep 10s
    RET=`netstat -na | grep ':5432 ' | wc -l`
    echo "!!!!!!Check server start:$RET"    
    echo "=======update ${GP_USERNAME} password"
    su - $GP_USERNAME -l -c "source ~/.bashrc;psql -d postgres -U $GP_USERNAME -f /home/$GP_USERNAME/alterRolePwd.sql"
    su - $GP_USERNAME -l -c "source ~/.bashrc;gpconfig -c log_statement -v none"
    su - $GP_USERNAME -l -c "source ~/.bashrc;gpconfig -c gp_enable_global_deadlock_detector -v on"
    echo '======== enable remote connection'
    su - $GP_USERNAME -l -c "echo 'host     all         all         0.0.0.0/0               trust' >> $GP_DATA_DIR/gpdata/master/gpseg-1/pg_hba.conf"
    cat $GP_DATA_DIR/gpdata/master/gpseg-1/pg_hba.conf
    su - $GP_USERNAME -l -c "gpstop -u"
    su - $GP_USERNAME -l -c "source ~/.bashrc && sleep 5s && gpstop -u && tail -f gpAdminLogs/*.log"
fi           

Dockerfile

FROM centos:centos7

# 环境变量
# * gp版本号
ENV ENV_GP_VERSION=6.23.0
# * 安装文件名称(提前去github上下载下来)
ENV ENV_GP_RPM_NAME=open-source-greenplum-db-$ENV_GP_VERSION-rhel7-x86_64.rpm
# * 安装文件在容器内的地址
ENV ENV_GP_RPM_PATH=/opt/software/greenplum/$ENV_GP_RPM_NAME
# * 数据根目录
ENV ENV_GP_DATA_DIR=/data
# * gp账号密码
ENV ENV_GP_USERNAME=gpadmin
ENV ENV_GP_PASSWORD=1qaz#EDC

# 文件准备
COPY install.sh /tmp/install.sh
COPY entrypoint.sh /entrypoint.sh
COPY $ENV_GP_RPM_NAME $ENV_GP_RPM_PATH

# 设置root密码
RUN echo "root:1qaz#EDC" | chpasswd

# 安装openssh
RUN yum -y install passwd openssl openssh-server openssh-clients &&\
    mkdir  /var/run/sshd/ &&\
    ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && \
    echo -e '#!/bin/bash\n/usr/sbin/sshd -D &' > /var/run/sshd/sshd_start.sh && \
    chmod u+x /var/run/sshd/sshd_start.sh && \
    yum clean all && \
    rm -rf /var/cache/yum

RUN /var/run/sshd/sshd_start.sh && \
    sleep 10s && cd /tmp && sh install.sh && \
    rm -rf /tmp/install.sh && rm -rf /tmp/files && \
    yum clean all && \
    rm -rf /var/cache/yum


# 暴露端口
EXPOSE 5432 22

USER  root

CMD  [ "sh" , "/entrypoint.sh"]           

greenplum_docker: Greenplum6 docker镜像制作