Docker中commit镜像后无法启动

老头憨憨 -
Docker中commit镜像后无法启动

因官方提供的postgresql镜像对linux精简的太厉害,基础的yum、telnet、ping 都没有了,很多操作不方便,所以这几天在尝试自己制作一个镜像,当前思路是在基础镜像centos上自定义安装了postgresql库,然后commit

1.问题现象

commit提交镜像后,通过镜像中的shell脚本启动数据库后,镜像状态未启动成功,报错内容:

Unable to find image 'mypg_02:latest' locally
Trying to pull repository docker.io/library/mypg_02 ... 
/usr/bin/docker-current: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on ip:53: server misbehaving.
See '/usr/bin/docker-current run --help'.

启动脚本:

docker run -d --name mypg01 -p 5201:5432 --network network-bridge mypg_02 /root/dockerStart/start.sh 

其中start脚本内容:

#!/bin/bash
su - postgres -c "/opt/pgdata/pg5432/scripts/startServer5432.sh"
2.问题原因

先回顾下操作,宿主机操作:

docker pull centos:7.4.1708  # 拉取镜像
docker run -d  -v /root/docker_dirs/centos01:/opt/centos  centos:7.4.1708 /bin/sh -c "while true; do echo hello world; sleep 60; done" # 运行centos镜像,centos镜像如果命令是/bin/bash,运行后会自动退出,因为容器没有检测到正在运行的进程

下载PG库的安装文件,并上传到宿主机的/root/docker_dirs/centos01
容器内操作,安装pg库,root用户执行如下命令:

cp /opt/centos/yum.repos.d/* . #配置yum源
yum install -y readline-devel gcc zlib-devel gcc automake autoconf libtool make bzip2 # 安装依赖包
cd /opt/
cp centos/postgresql-12.2.tar.bz2 .
tar -xvf postgresql-12.2.tar.bz2  #  解压文件
ln -s postgresql-12.2 postgresql
mkdir -p pgdata/pg5432
cd pgdata/pg5432
mkdir -p {data,backups,scripts,archive_wals}
cd /opt/postgresql
/opt/postgresql/configure --prefix=/opt/postgresql #编译、安装
make
make install
useradd postgres
cd /opt
chown -R postgres:postgres p*

postgres用户用户执行如下命令
/opt/postgresql/bin/initdb -D /opt/pgdata/pg5432/data #初始化数据库
mkdir /opt/pgdata/pg5432/logs
/opt/postgresql/bin/pg_ctl -D /opt/pgdata/pg5432/data -l /opt/pgdata/pg5432/logs/startlogs.log start & #启动数据库验证
more /opt/pgdata/pg5432/scripts/startServer5432.sh  # 新建启动文件
/opt/postgresql/bin/pg_ctl -D /opt/pgdata/pg5432/data -l /opt/pgdata/pg5432/logs/startlogs.log start &

root用户用户执行如下命令
/root/dockerStart/start.sh  # 创建启动脚本
#!/bin/bash
su - postgres -c "/opt/pgdata/pg5432/scripts/startServer5432.sh"

退出容器后在宿主机执行如下命令:

docker commit centos01 mypg_01  # 提交镜像
docker run -d --name mypg02 -p 5300:5432 --network network-bridge mypg_01 /root/dockerStart/start.sh  #使用新的镜像启动容器,启动失败,且容器提留在created状态
报错如下:
/usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint mypg02 (f14f29f8eb010fc128873d022e5caa4abe59becca234588f682942acba4ad4a4): Bind for 0.0.0.0:5300 failed: port is already allocated.
容器状态:
CONTAINER ID        IMAGE                                         COMMAND                  CREATED              STATUS                    PORTS                    NAMES
cb9f683c1307        mypg_01                                       "/root/dockerStart..."   About a minute ago   Created                                            mypg02

个人理解是 自定义的命令是通过 后台执行命令的方式启动PG库,在容器检测不到这个命令是否还在继续,所以容器并不会继续启动。commit方式只是在基础镜像上安装了一些应用,所以启动还是需要用基础镜像的方式启动:

docker run -d --name mypg02 -p 5200:5432 --network network-bridge mypg_01 /bin/sh -c "while true; do echo hello world; sleep 60; done"
4、总结

commit方式一般用于提交用户修改的内容,比如新发布的jar包,不适合用于构建镜像。

特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

Tags 标签

dockerlinux运维

扩展阅读

加个好友,技术交流

1628738909466805.jpg