暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

docker容器中编译安装postgresql

原创 孙文龙 2020-06-22
3068

1、开头

为什么要使用docker容器

  • 这只是在自己的测试环境下使用
  • 方便以后测试PG的高可用。只需要安装1次PG,以后的容器只需要挂载安装PG的目录
  • 利用docker的资源隔离,每个容器就相当于一个独立的操作系统。相对于一台虚机直接安装多个PG,显得更加简洁
  • 相对于安装多个虚机,使用docker更加节省资源

2、dockerfile文件

FROM centos:7.5
MAINTAINER sunwld
RUN yum install -y initscripts openssh-server which lsof &&\
    yum clean all  && rm -rf /var/cache/yum/* && \
    ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N '' &&\
    ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' && \
    ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key -N '' && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
    echo "root:123456"|chpasswd &&\
    useradd -u 1001 postgres &&\
    mkdir -p /pgsql/{data,install} &&\
    echo "export PGDATA=/pgsql/data" >> /home/postgres/.bash_profile &&\
    echo "export PGHOME=/pgsql/install" >> /home/postgres/.bash_profile &&\
    echo "export PATH=\$PGHOME/bin:\$PATH" >> /home/postgres/.bash_profile &&\
    echo "export LD_LIBRARY_PATH=\$PGHOME/lib" >> /home/postgres/.bash_profile &&\
    chown postgres:postgres /pgsql/data


COPY run.sh /usr/local/sbin/run.sh
EXPOSE 22
ENTRYPOINT ["sh","/usr/local/sbin/run.sh"]

  • 基于centos7.5版本镜像。
  • 为了能够远程连接,安装了ssh,并为root用户设置了密码。
  • 提前创建了postgres用户,创建了PG先关目录和环境变量
  • 容器启动时会运行/usr/local/sbin/run.sh脚本

3、run.sh 脚本

#!/bin/bash

start_pg(){
  su - postgres -c 'pg_ctl start -D ${PGDATA}'
  DATA_DIR=`su - postgres -c 'echo ${PGDATA}'`
  tail -f ${DATA_DIR}/log/postgresql*.log & wait ${!}
}

stop_pg(){
  ProcNumber=`ps -ef |grep -w postgres|grep -v grep|wc -l`
  if [ $ProcNumber -gt 0 ];then
    su - postgres -c 'pg_ctl stop -m fast'
  fi
}

trap "stop_pg" SIGTERM


if id -u postgres >/dev/null 2>&1; then
  DATA_DIR=`su - postgres -c 'echo ${PGDATA}'`
  FILE_COUNT=`ls -A $DATA_DIR`
  if [ -d "${DATA_DIR}" ] && [ -d "${DATA_DIR}/log" ];then
    start_pg;
  else
    /usr/sbin/sshd -D;
  fi
else
  /usr/sbin/sshd -D;
fi

容器启动时执行的脚本

  • 如果PG 还没有实例化, 则启动SSH ,前台启动sshd
  • 如果PG已经实例化,则直接启动PG,并设置一个监听系统关机信号
  • 获取系统关机信号之后,等待PG关闭之后,再进行系统关机

4、启动容器

  • 构建镜像
docker build -t centos/pg:11.7 -f pg11-centos75_dockerfile .
  • 启动容器
docker run -itd -v /docker/container_mnts/pg11_install:/pgsql/install \ -v /docker/container_mnts/pg11_data1:/pgsql/data --net mynet \ --ip 172.100.0.100 -p 15432:5432 -p 5022:22 --cap-add=NET_ADMIN \ --name pg11 -h pg11 centos/pg:11.7

将安装目录挂载到宿主机是为了在启动其它 pg容器时,直接挂载这个目录,不需要再重新安装PG 了
将容器的5432 端口映射到了宿主机的15432端口

使用以上命令启动容器之后, 使用一下命令可以进入容器

docker exec -it pg11 "bash"

5、安装准备

  • 从官网下载PostgreSQL源代码 https://www.postgresql.org/download/,选择source选项,下载对应版本的源码压缩包即可,根据自己的喜爱,可以选择下载tar.gz格式或者tar.bz2格式的压缩包。
  • 安装gcc 和make
yum install -y gcc make
  • 安装zlib-devel readline-devel
yum -y install zlib-devel readline-devel
  • 在宿主机执行命令,将源码拷贝到容器内
docker cp postgresql-11.8.tar.gz pg11:/tmp

6、安装PG

6.1 进入解压后的源码目录下执行

[13:24:53][root@pg11 postgresql-11.8]# ./configure --prefix=/pgsql/install/ [13:24:53]checking build system type... x86_64-pc-linux-gnu [13:24:53]checking host system type... x86_64-pc-linux-gnu [13:24:53]checking which template to use... linux [13:24:53]checking whether NLS is wanted... no [13:24:53]checking for default port number... 5432 [13:24:53]checking for block size... 8kB [13:24:53]checking for segment size... 1GB [13:24:53]checking for WAL block size... 8kB [13:24:53]checking for gcc... gcc ... ... [13:25:57]config.status: creating GNUmakefile [13:25:57]config.status: creating src/Makefile.global [13:25:57]config.status: creating src/include/pg_config.h [13:25:57]config.status: creating src/include/pg_config_ext.h [13:25:57]config.status: creating src/interfaces/ecpg/include/ecpg_config.h [13:25:57]config.status: linking src/backend/port/tas/dummy.s to src/backend/port/tas.s [13:25:57]config.status: linking src/backend/port/dynloader/linux.c to src/backend/port/dynloader.c [13:25:57]config.status: linking src/backend/port/posix_sema.c to src/backend/port/pg_sema.c [13:25:57]config.status: linking src/backend/port/sysv_shmem.c to src/backend/port/pg_shmem.c [13:25:57]config.status: linking src/backend/port/dynloader/linux.h to src/include/dynloader.h [13:25:57]config.status: linking src/include/port/linux.h to src/include/pg_config_os.h [13:25:57]config.status: linking src/makefiles/Makefile.linux to src/Makefile.port

6.2 编译并安装

[13:27:48][root@pg11 postgresql-11.8]# make && make install
[13:27:48]make -C ./src/backend generated-headers
[13:27:48]make[1]: Entering directory `/tmp/123/postgresql-11.8/src/backend'
[13:27:48]make -C catalog distprep generated-header-symlinks
[13:27:48]make[2]: Entering directory `/tmp/123/postgresql-11.8/src/backend/catalog'
[13:27:48]make[2]: Nothing to be done for `distprep'.
[13:27:48]prereqdir=`cd './' >/dev/null && pwd` && \
[13:27:48]cd '../../../src/include/catalog/' && for file in pg_proc_d.h pg_type_d.h pg_attribute_d.h pg_class_d.h pg_attrdef_d.h pg_constraint_d.h pg_inherits_d.h pg_index_d.h pg_operator_d.h pg_opfamily_d.h pg_opclass_d.h pg_am_d.h pg_amop_d.h pg_amproc_d.h pg_language_d.h pg_largeobject_metadata_d.h pg_largeobject_d.h pg_aggregate_d.h pg_statistic_ext_d.h pg_statistic_d.h pg_rewrite_d.h pg_trigger_d.h pg_event_trigger_d.h pg_description_d.h pg_cast_d.h pg_enum_d.h pg_namespace_d.h pg_conversion_d.h pg_depend_d.h pg_database_d.h pg_db_role_setting_d.h pg_tablespace_d.h pg_pltemplate_d.h pg_authid_d.h pg_auth_members_d.h pg_shdepend_d.h pg_shdescription_d.h pg_ts_config_d.h pg_ts_config_map_d.h pg_ts_dict_d.h pg_ts_parser_d.h pg_ts_template_d.h pg_extension_d.h pg_foreign_data_wrapper_d.h pg_foreign_server_d.h pg_user_mapping_d.h pg_foreign_table_d.h pg_policy_d.h pg_replication_origin_d.h pg_default_acl_d.h pg_init_privs_d.h pg_seclabel_d.h pg_shseclabel_d.h pg_collation_d.h pg_partitioned_table_d.h pg_range_d.h pg_transform_d.h pg_sequence_d.h pg_publication_d.h pg_publication_rel_d.h pg_subscription_d.h pg_subscription_rel_d.h schemapg.h; do \
[13:27:48]  rm -f $file && ln -s "$prereqdir/$file" . ; \
[13:27:48]done
...
...
[13:31:45]make[1]: Entering directory `/tmp/123/postgresql-11.8/config'
[13:31:45]/usr/bin/mkdir -p '/pgsql/install/lib/pgxs/config'
[13:31:45]/usr/bin/install -c -m 755 ./install-sh '/pgsql/install/lib/pgxs/config/install-sh'
[13:31:45]/usr/bin/install -c -m 755 ./missing '/pgsql/install/lib/pgxs/config/missing'
[13:31:45]make[1]: Leaving directory `/tmp/123/postgresql-11.8/config'
[13:31:45]PostgreSQL installation complete.

6.3 初始化数据库

[13:32:55][root@pg11 tmp]# su - postgres
[13:32:55]Last login: Fri May 22 13:08:26 CST 2020 on pts/0
[13:32:59][postgres@pg11 ~]$ initdb --help
initdb initializes a PostgreSQL database cluster.

Usage:
  initdb [OPTION]... [DATADIR]

Options:
  -A, --auth=METHOD         default authentication method for local connections
      --auth-host=METHOD    default authentication method for local TCP/IP connections
      --auth-local=METHOD   default authentication method for local-socket connections
 [-D, --pgdata=]DATADIR     location for this database cluster
  -E, --encoding=ENCODING   set default encoding for new databases
      --locale=LOCALE       set default locale for new databases
      --lc-collate=, --lc-ctype=, --lc-messages=LOCALE
      --lc-monetary=, --lc-numeric=, --lc-time=LOCALE
                            set default locale in the respective category for
                            new databases (default taken from environment)
      --no-locale           equivalent to --locale=C
      --pwfile=FILE         read password for the new superuser from file
  -T, --text-search-config=CFG
                            default text search configuration
  -U, --username=NAME       database superuser name
  -W, --pwprompt            prompt for a password for the new superuser
  -X, --xlogdir=XLOGDIR     location for the transaction log directory

Less commonly used options:
  -d, --debug               generate lots of debugging output
  -k, --data-checksums      use data page checksums
  -L DIRECTORY              where to find the input files
  -n, --noclean             do not clean up after errors
  -N, --nosync              do not wait for changes to be written safely to disk
  -s, --show                show internal settings
  -S, --sync-only           only sync data directory

Other options:
  -V, --version             output version information, then exit
  -?, --help                show this help, then exit

通过这些参数后面的介绍,我们可以在数据库初始化的时候指定数据目录、编码和日志等信息。
#初始化时指定了数据库的编码和数据目录

[13:41:55][postgres@pg11 ~]$ initdb -D /pgsql/data/ -E utf8
[13:41:55]The files belonging to this database system will be owned by user "postgres".
[13:41:55]This user must also own the server process.
[13:41:55]
[13:41:55]The database cluster will be initialized with locale "en_US.UTF-8".
[13:41:55]The default text search configuration will be set to "english".
[13:41:55]
[13:41:55]Data page checksums are disabled.
[13:41:55]
[13:41:55]fixing permissions on existing directory /pgsql/data ... ok
[13:41:55]creating subdirectories ... ok
[13:41:55]selecting default max_connections ... 100
[13:41:55]selecting default shared_buffers ... 128MB
[13:41:56]selecting default timezone ... PRC
[13:41:56]selecting dynamic shared memory implementation ... posix
[13:41:56]creating configuration files ... ok
[13:41:56]running bootstrap script ... ok
[13:41:56]performing post-bootstrap initialization ... ok
[13:41:56]syncing data to disk ... ok
[13:41:56]
[13:41:56]WARNING: enabling "trust" authentication for local connections
[13:41:56]You can change this by editing pg_hba.conf or using the option -A, or
[13:41:56]--auth-local and --auth-host, the next time you run initdb.
[13:41:56]
[13:41:56]Success. You can now start the database server using:
[13:41:56]
[13:41:56]    pg_ctl -D /pgsql/data/ -l logfile start
[13:41:56]

6.4 修改配置

修改postgresql.conf配置文件, 打开日志记录、

logging_collector = on

在 $PGDATA目录下创建log目录

[postgres@pg11 ~]$ mkdir -p $PGDATA/log

7、测试

重新启动docker容器。如果可以在宿主机看到 PG 进程说明PG 进程可以正常随容器启动

[root@centos7 pg11_data1]# docker restart pg11
pg11
[root@centos7 pg11_data1]# ps -ef|grep post
1001      3264  3156  0 11:14 ?        00:00:00 /pgsql/install/bin/postgres -D /pgsql/data
1001      3265  3264  0 11:14 ?        00:00:00 postgres: logger   
1001      3267  3264  0 11:14 ?        00:00:00 postgres: checkpointer   
1001      3268  3264  0 11:14 ?        00:00:00 postgres: background writer   
1001      3269  3264  0 11:14 ?        00:00:00 postgres: walwriter   
1001      3270  3264  0 11:14 ?        00:00:00 postgres: autovacuum launcher   
1001      3271  3264  0 11:14 ?        00:00:00 postgres: stats collector   
1001      3272  3264  0 11:14 ?        00:00:00 postgres: logical replication launcher  

关闭容器,如果在PG 的data目录下,不存在PID 文件,则说明 PG可以随容器关闭而正常关闭

[root@centos7 pg11_data1]# docker stop pg11
pg11
[root@centos7 pg11_data1]# ls 
base              global  pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts
current_logfiles  log     pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf
[root@centos7 pg11_data1]# 

最后修改时间:2020-06-23 11:54:52
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论