WSL上的centOS7中安装Docker并拉取opengauss镜像
声明:我的CentOS是在windows的WSL上安装的子系统,如果不是WSL安装的CentOS建议不要用我方法搞,可能会有问题。
建议:如果不是有要求,建议不要直接在WSL上的CentOS安装docker,一堆坑,WSL虽然是虚拟环境,但它就是会windows主机的配置起冲突。可以在windows上安装docker desktop,然后在CentOS上用。如果是有要求要在CentOS上使用docker的朋友,可以选择VMware、Oracle VM VirtualBox,或者干脆云服务器。
1. 安装或重装docker
1.1 卸载docker(没安装过的朋友可以跳到下一步)
卸载docker很重要,因为你不知道整个过程要重装多少次。
官方文档给的卸载命令是:
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
而实际上我们安装的时候可能是安装了docker-ce docker-ce-cli containerd.io docker-compose-plugin之类的,这些命令就不适用了。如果安装过docker,但运行上面命令之后显示没有删除任何包,可以先用
yum list installed | grep docker
看看有哪些docker的包,然后用yum rm命令删掉。
然后下面这几个清除容器、镜像之类的指令可以自己选择要不要用,不过会出现这个问题的同学应该都卡在启动docker上,估计也没有多少不能删除的配置和镜像吧。
# 容器/镜像存储目录(如果提示被占用,关掉centos,windows命令行执行wsl --shutdown关闭wsl重启)
sudo rm -rf /var/lib/docker
# containerd运行时数据
sudo rm -rf /var/lib/containerd
# Docker配置文件
sudo rm -rf /etc/docker
# 删除 systemd 服务文件(如果存在)
sudo rm -f /usr/lib/systemd/system/docker.service
sudo rm -f /etc/systemd/system/docker.service.d/*
# 清理YUM元数据
sudo yum clean all
接下来的这个操作我不知道需不需要,但我是做了,如果出了错误搞不定要重装的话,建议还是做一下这个步骤,把所有可能的配置都清了,好重新搞。
首先用sudo find / -name "*docker*" -type d 2>/dev/null查看与docker有关的目录,然后用
sudo rm -rf 路径删除掉。不过要注意,/mnt开头的路径不要动,这个开头的路径是指向windows上的硬盘的。
1.2 安装docker
首先让systemd作为init系统运行。WSL 默认使用 /init 作为 PID 1 进程,而非 systemd,导致以下问题:
systemd 服务无法自动加载
传统服务管理命令(如 systemctl)失效
使用ps -p 1 -o comm=,如果输出是"init" ,而不是 "systemd",就用以下命令启用 WSL 的 systemd 支持
# 1. 修改 WSL 配置文件
sudo tee /etc/wsl.conf <<EOF
[boot]
systemd = true
EOF
# 2. 关闭当前 WSL 实例(可以在windows命令行用wsl.exe --list --verbose查看自己的centos发行版名称)
wsl.exe --terminate 你的centos名称
#3. 重新启动 WSL
#4. 验证 systemd 是否生效
ps -p 1 -o comm= # 应输出 "systemd"
安装依赖,下载docker
#1.安装基础依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
#2.配置阿里云镜像源
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's@https://download.docker.com@https://mirrors.aliyun.com/docker-ce@' /etc/yum.repos.d/docker-ce.repo
#3.强制刷新元数据
sudo yum clean all
#4.安装最新可用版本(这是我们要求的包,大家按自己需要的装)
sudo yum install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
# 5. 搞一些配置
sudo mkdir -p /mnt/wsl/docker
sudo tee /etc/docker/daemon.json <<'EOF'
{
"data-root": "/home/user/data",#这是docker放数据的地方,想换的话千万不要放到/mnt开头的路径。
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
#6.查看docker版本,看是不是有docker
docker --version
#7.开启docker的命令
systemctl start docker
#8.查看docker状态,如果 Active那一栏是active(running),说明成功启动了
systemctl status docker
#9.docker开机自启动的命令,不想要可以不设(建议不要,有坑)
sudo systemctl enable docker
建议每次启动后都用systemctl status docker查看一下状态,因为有时候启动失败它是不会说的,甚至一些功能都还能用,但就是会出现这样那样的问题,搞了半天才发现原来docker都没有启动,所以启动后先用这个命令查一下状态,如果Active那一栏是failed(启动失败的状态),就开始找问题吧。
2.3 启动失败看这里
首先推荐一个命令:systemctl logs dail -f docker,用这个命令可以实时看到docker的日志,如果启动后发现状态是failed,可以用这个命令实时显示日志,然后再开一个窗口重跑docker,再回来看启动失败的原因。
接下来说一些遇到比较多的错误:
- 可能问题1:启动时遇到 Failed to get D-Bus connection: Operation not permitted
解决方法:
#备份文件
mv /usr/bin/systemctl /usr/bin/systemctl.old
#下载systemctl文件
curl https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl.py > /usr/bin/systemctl
#赋予权限
chmod +x /usr/bin/systemctl
- 可能问题2:Failed to start docker.service: Unit not found.
明明/usr/lib/systemd/system目录里有docker.service,它就硬说找不到,网上攻略有说把docker.service里的docker.socket删掉的,有说修改读写权限的,都没用,最后找到一个比较靠谱的方法,直接覆盖docker.server。
sudo mkdir -p /etc/systemd/system/docker.service.d创建覆盖目录
vi /etc/systemd/system/docker.service.d/override.conf创建文件,把下面的内容写进去,保存。
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3
# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
OOMScoreAdjust=-500
[Install]
WantedBy=multi-user.target
重新加载配置
sudo systemctl daemon-reload
其实我当初找到的方法是用上面的内容重写原本的docker.service,但后来发现一些其它问题要创建覆盖目录,创建之后发现它启动时指定覆盖目录了,不指定原本的目录了,又把上面的内容复制到override.conf,所以这里一次到位把override.conf写全了。
- 可能问题3:启动总是failed的问题
用上面推荐的systemctl logs dail -f docker打开实时日志,重开一个窗口再跑一下systemctl start docker,回实时日志看看是不是找不到/var/run/docker.sock,如果是的话,用ls /var/run/docker.sock看一下是不是真的没有docker.sock:
如果没有,我忘记没有docker.sock怎么弄了,建议问一下ai,不过等你把docker.sock弄出来之后,大概率还是得进下一步。
如果有,那就手动指定docker.sock位置:
首先打开daemon.json:
vi /etc/docker/daemon.json
如果里面没有内容的话,写入:
{
"hosts": ["unix:///var/run/docker.sock"]
}
如果里面有内容了,就插入:
"hosts": ["unix:///var/run/docker.sock"],记得末尾要加英文逗号
然后手动编辑systemd服务文件(如果用过我上一个问题的办法,那就不用了,我里面有写了):
创建配置覆盖目录
sudo mkdir -p /etc/systemd/system/docker.service.d
再创建自定义配置文件
sudo vi /etc/systemd/system/docker.service.d/override.conf
写入:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
最后执行重新加载配置并重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
- 可能问题4:能启动docker,状态也是active,但是使用docker命令一直卡着
可能会有这种情况:启动docker能启动,看一下状态也是active,但是用docker ps等命令一直卡着,等几分钟再看状态变成failed了。
我查看了docker日志,发现是找不到/var/run/containerd/containerd.sock,因为docker依赖containerd(容器生命周期是containerd在管理的),找不到containerd它就进入启动失败的状态。一开始我以为是containerd不会自启动,但后来我发现它是在打开CentOS 5分钟后才启动,导致在这之前docker找不到/var/run/containcerd/containerd.sock。而且还有个问题,等它自启动之后,用systemctl status containerd,会发现状态还是未启动,而你这时候手动启动,又会被卡在那。
试了很多办法,都不行,目前的解决办法是在开启CentOS之后手动启动containerd。
#手动启动containerd
systemctl start containerd
2.1 拉取opengauss镜像
2.1.1 拉取镜像
在docker中拉取云和恩墨提供的最新的opengauss镜像,不过建议大家也拉取3.0.0的,最新版可能会闪退。
拉取最新版本:
docker pull enmotech/opengauss:latest
拉取3.0.0版本
docker pull enmotech/opengauss:3.0.0
这里会出现一个问题:
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)。
这是因为国内连不上dockerhub,网上说得最多的办法是配置加速镜像,实际上没用,估计是老方案了,现在失效了,最后还是要靠代理。
2.1.2 Mirrored模式和NAT模式及代理设置
因为我的CentOS是在WSL2上的,所以我配代理也是基于WSL2的,不过WS1的可以试一下第一种模式的代理。
要看是WSL1还是2,可以在windows的cmd执行wsl -l -v,如图:

配代理之前先看看你的WSL是什么网络模式,在windows上打开WSL Settings,选择“网络”,这里可以看到你是什么网络模式,也可以改网络模式

WSL2有好几种网络模式,不过常用的是Mirrored和NAT。
像我这里是Mirrored,据说默认是NAT,但我的好像默认就是Mirrored。
更改网络模式后要重启wsl才会生效,单纯把命令窗口关掉是没用的,要在windows的cmd上用wsl --shutdown关闭wsl。
接下来介绍这两种模式的代理配置
-
Mirrored模式
Mirrored模式直接在Windows上开代理就好
Mirrored模式共享Windows的ip,也就是说Mirrored模式下WSL上的子系统的ip地址和Windows本机的地址是一样的,所以Mirrored模式直接在Windows上开代理软件就可以,CentOS能连得到。而且Mirrored模式下,在CentOS上设置代理配置反而连不上网(亲自踩过的坑)。据说WSL1也是直接用Windows的ip,所以WSL1的同学可以试试能不能用。 -
NAT模式
NAT模式会单独给子系统分配一个ip,NAT模式要用代理的话,要设置代理配置:
#1.在 /etc/systemd/system 目录下创建 docker.service.d 目录(如果没有的话)
mkdir -p /etc/systemd/system/docker.service.d
#2.编辑并保存/etc/systemd/system/docker.service.d/http-proxy.conf
vi /etc/systemd/system/docker.service.d/http-proxy.conf
#内容如下:
[Service]
Environment="HTTP_PROXY=http://你的WSL与Winodws通信的ip:你的代理端口/"
Environment="HTTPS_PROXY=http://你的WSL与Winodws通信的ip:你的代理端口/"
#3.windows上打开代理
#4.刷新更改并重新启动 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
这里用的ip不是CentOS的ip,也不是Windows的ip,而是WSL跟Windows通信的ip。可以在Windows的cmd中ipconfig,找到vEthernet(WSL)或者括号里带有WSL的网络适配器,如:

这个ip就是NAT模式下wsl和Windows通信的ip,代理端口就填你在代理软件上指定的端口。
有些教程会教你用cat /etc/resolv.conf找ip,但是现在这个方法不能用了,用这个命令只能找到10.255.255.254,据说是在Windows11某次更新后变成这样的。
用*** for windows代理的可以看看这个文章:
https://blog.csdn.net/2301_79849395/article/details/142829852
-
注意
(1)代理软件要开支持局域网模式
(2)用NAT模式写了代理配置文件之后,如果后面换成Mirrored模式了,要把这个文件删掉,不然CentOS连不上网
(3)有一些教程会教人修改C:\Users\用户名.wslconfig,让wsl可以直接用windows的代理,其实基本上也是把网络模式改成Mirrored。里面通常会有networkingMode=mirrored,这一行就是把网络模式设置成Mirrored。如果电脑上没有WSL Settings的话也可以用这种方式设置网络模式。
(4)如果有需要把CentOS当成服务器,使用ssh等远程连接的,要注意以下网络模式,这两种是不一样的。这也是我在第二点提醒大家注意网络模式的原因。
(5)开代理时WSL子系统下载会比较慢,特别是NAT。 -
补充一个笨办法
如果在windows上可以用代理,而CentOS上一直不成功的话,也可以在windows上拉取镜像,导出成tar之后,再在CentOS上导入。(或者让成功拉取了镜像的同学导出给你)
不过这种方式会有个问题,也是我以前踩过的坑。Windows上也下载docker之后,WSL上的CentOS会发疯,它不连自己的docker了,它会连到Windows上的docker,那我能怎么办,我就只能把Windows上的docker卸载了,然后它就开始找不到docker配置文件了,然后我就在CentOS上重装docker了(所以我说上面的重装命令很有用)。
Windows上拉取镜像再导出过程如下:
在windows上下载docker desktop,然后cmddocker pull enmotech/opengauss:latest拉取镜像,再docker save -o opengauss.tar enmotech/opengauss:latest把镜像导出成opengauss.tar,默认的话导出后的opengauss.tar应该在C:\Users\你的用户名 目录下。
然后在CentOS中cd进入opengauss.tar所在的目录,比如:opengauss.tar在C:\Users\xxx下的话,就cd /mnt/c/Users/xxx(mnt开头的路径就是指向你Windows本机的路径),然后docker load -i opengauss.tar导入镜像。
然后先别急着卸载Windows上的docker,可以把enmotech/opengauss:3.0.0也拉取下来,因为enmotech/opengauss:latest可能是会出问题的,后面可能还是要用回3.0.0版本,省的到时候再搞一次。
2.2 创建opengauss容器并跑起来
docker run --name opengauss --privileged=true -d -e GS_PASSWORD=openGauss@123 -p5432:5432 enmotech/opengauss:latest
当然,这是我们实验指导书上给的命令,大家可以按自己的需要设置参数(或者把需求扔给ai让它给你设计)
然后再给大家介绍几个命令:
启动容器docker start 容器名,如docker start opengauss(opengauss是我们上面 --name给容器起的名字)
关闭正在运行的容器docker stop 容器名
查看正在运行中的容器docker ps
查看所有容器,不管是不是在运行中docker ps -a
这里又会有一个坑:
可能会出现容器启动后,过几秒就掉了,大家可以启动容器后,过几秒用docker ps看看容器有没有在线,如果出现这种情况,可能有这两种原因:
(1)云和恩墨opengauss镜像最新版本的问题。我在网上发现有其他人也出现这个问题,他们建议用回3.0.0版本,我试了一下,确实解决了(所以我上面建议把enmotech/opengauss:3.0.0也拉取了)
(2)挂载路径问题。/etc/docker/daemon.json里的"data-root"是docker放数据的路径,如果给它配的是/mnt开头的路径,就相当于让docker把数据放到Windows里面了,这就会导致i/o出现问题,我上面配daemon.json的时候也有建议别用/mnt开头的路径。大家可以vi /etc/docker/daemon.json看看"data-root"后面的路径是不是/mnt开头的,如果是,就给它换成wsl原生路径,比如/home/user/data。
docker start opengauss跑起启动opengauss并且不会再掉之后,就可以来试一试能不能连接。
docker exec -it opengauss bash进入容器
su - omm切换omm用户,注意,'-'和'omm'之间有空格
gsql -d postgres -U gaussdb -W 'openGauss@123' -h 192.168.56.107 -p 5432连接数据库,'openGauss@123'是上面run命令的时候设置的密码,如果设置了其它密码的用其它密码,'192.168.56.107'换成你自己的ip,或者换成容器的ip,docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' opengauss可以查看opengauss容器内部的ip。
连接上数据库之后就能用了,但还有一个关于使用体验问题:用gsql连上数据库之后,是没有办法使用方向键的,删除键也要ctrl+Backspace才能用,用方向键和单纯的删除键会显示一些符号,要优化体验的话可以在容器内安装rlwarp
2.3 体验优化之rlwarp
我用的3.0.0的镜像是默认没有安装rlwarp的,不知道其它版本的有没有,可以在gsql启动数据库时在前面加个rlwarp试试,如rlwrap gsql -d postgres -U gaussdb -W 'openGauss@123' -h 172.17.0.1 -p 5432,如果提示找不到rlwarp,那就来安装。
这个rlwarp是在容器内装的,在CentOS上装没有用,所以要到进入容器之后再来执行命令。
不知道docker镜像是不是基于ubuntu的,我用yum装rlwarp跟我说找不到命令,反倒是apt-get可以。
上面一路启动docker,启动容器,然后到docker exec -it opengauss bash进入容器之后,就可以来执行安装命令
#更新仓库
apt-get update
#安装
apt-get install -y rlwrap
这里如果docker无法联网的话,先退出exit退出容器,回到CentOS,打开/etc/docker/daemon.json看看是不是有 "iptables": false,有的话就删除掉,重启docker服务。
安装完后,继续su - omm切换用户,然后连接数据库时在gsql前面加rlwrap,比如:rlwrap gsql -d postgres -U gaussdb -W 'openGauss@123' -h 172.17.0.1 -p 5432
连接上就可以正常使用方向键和删除键了。
在容器里安装rlwrap是暂时的,容器关闭之后就没了,再打开要重新安装,要持久化保存rlwrap的话,可以在安装完rlwrap之后,把带有rlwrap的容器提交为新镜像:
#回到CentOS的命令行执行这一命令,把当前容器提交成新镜像
#docker commit 你的容器名 保存成什么镜像名,如:
docker commit opengauss opengauss_with_rlwrap
然后用导出来的镜像重新创建一个新容器就可以了。
如果原来的容器不想保留的话,就docker rm 容器名 删掉,如果想保留的话就不删。不删的话,创建新容器时就换个名字,避免重名。
创建新容器还是用2.2开头提到的docker run命令,注意一下要创建的容器名,把最后的镜像名换成刚才导出的镜像就可以,比如我导出的镜像名是opengauss_with_rlwrap,又把旧容器删了,新容器还是用opengauss命名,那我的命令就是:
docker run -itd --name opengauss --privileged=true -d -e GS_PASSWORD=openGauss@123 -p5432:5432 opengauss_with_rlwrap
3 总结
整个过程其实还有一些其它问题的,但我不记得具体是哪些问题了,不过都是一些网上或者ai找得到答案的问题,容易解决的。
在CentOS上安装docker,拉取opengauss镜像,再跑起来,几乎一步一个坑,很多坑我都在配置的命令里避免了,网上大部分教程是基于VM和VirtualBox的,基于WSL的太少了。安装WSL和CentOS我用了两天,其中一天还是在等下载,而安装docker开始到现在陆陆续续半个月,每次打开都有新问题,真心建议WSL部署CentOS的朋友不要直接在CentOS上安装docker。

浙公网安备 33010602011771号