docker-desktop所占的空间移动到D盘

Docker Desktop now can use WSL 2 Backend. In this mode, you need to move the wsl data.

In my case (Windows10 with Docker Desktop) none of the above solutions helped me, but I found the solution; run these commands.

This command changes the docker directory to drive D: (don't forget to quit docker desktop first)

wsl --shutdown
wsl --export docker-desktop-data docker-desktop-data.tar
wsl --unregister docker-desktop-data
wsl --import docker-desktop-data D:\docker-new-repo\ docker-desktop-data.tar --version 2

And now you can delete .tar file

There is a very good blog post explaining everything:

https://dev.to/kimcuonthenet/move-docker-desktop-data-distro-out-of-system-drive-4cg2

备份docker中运行的container

备份container涉及到备份container中的image和container使用的data。

备份image可以参考这里。

备份之前需要把运行中的程序停下来docker-compose down

备份数据

命令示例如下:

docker run --rm --mount source=<your_volume_data>,destination=/volume -v ${PWD}/backup:/backup alpine tar -cjf /backup/<your_volume_data>.tar.bz2 -C /volume ./

这个命令里假设你本地存在一个backup的文件夹,备份的数据将会保存在backup中

恢复数据

docker run --rm --mount source=<your_volume_data>,destination=/volume -v ${PWD}/backup:/backup alpine sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/<your_volume_data>.tar.bz

这个命令里假设你本地存在一个backup的文件夹,backup中<your_volume_data>.tar.bz是待恢复的数据

docker-compose无法配置域名服务器的问题

在有些情况下,通过docker-compose配置的服务器无法通过域名访问外部网络,但换成ip之后没有问题。参照官方文档,理论上docker-compose构建的container会继承主机的域名服务器,然而实际上却没有达到此效果。这个问题只在部分主机上运行时会出现,而此问题也在docker-compose的github上讨论了很久。综合判断,这似乎是docker-compose的一个bug。

我们也参照这里,找到一个暂时的workaround。即,在docker-compose.yaml中给每一个服务添加network_mode: bridge字段。至于为何添加此字段后,问题就会消失,原因也不太明确。总之,结果就是添加此字段后阻止了docker-compose新建网络,而是直接用docker0网络,这时候域名服务器就没有问题了。

docker的容器内无法互相访问端口的一种情况

具体案例是发生在新装的fedora32系统上,发现刚刚安装好的docker应用程序运行起来后,无法互相访问端口。在stackoverflow上的相关提问连接可以参考这里

具体原因是firewalld阻止了容器之间互相访问端口的情况。原来在fedora32系统中运行docker 19.03.9版本时,会发生docker网络接口归fedora 的firewalld管理的情况。解决方案是,将docker0,和docker容器运行的网络接口添加到firewalld的trusted zone。然后给trusted zone添加开放相应的端口权限即可。

docker0网络在promiscuous模式下才能使用的问题

有一次我在客户服务器上部署docker容器遇见了个很奇葩的问题。就是容器运行一切正常,但就是无法连接容器的网络。更奇怪的是,一旦你通过tcpflow或者tcpdump监控docker0网络时,那些容器的网络又可以访问了。

原来tcpflow和tcpdump会将虚拟网卡或者网卡至于promiscuous模式,这种模式会让网卡不管网络数据包是不是发给自己的,它都会接受。像目前这种情况,一般是ip地址正确,mac地址错误就会发生。因此,我考虑是不是安装docker时,一不小心创建了两个docker0网络,这两个docker0虚拟网卡ip地址重合了,最后导致网络通信出了问题。

最后,解决方案是把该虚拟网卡删除再重建,问题解决:

sudo ip link delete docker0
sudo systemctl restart docker.service

docker容器访问host端口

docker容器都是运行在虚拟机和自己的虚拟的网络上的,想要访问host端口有两种方案。

配置docker容器使用host网络

这种方案最直接,你只需要docker run --network="host" ... 就可以了。要知道,在默认的情况下--network="bridge",然后容器是通过docker虚拟网络与主机相同的。

查询主机在docker网络下的ip

主机下运行此命令,即可查询主机在docker默认网络(--network="bridge")下的ip地址。

sudo ip addr show docker0

更多信息,参考这里

docker发布django测试服务器端口至host

django测试服务器运行端口为127.0.0.1:8000。在docker中运行时如果采用--publish 8000:8000的映射方法是会出错的。因为这里的映射ip为0.0.0.0。即8000 -> 0.0.0.0:8000。而django运行的ip为127.0.0.1:8000。端口是同一端口,ip却不是同一个ip。理论上解决此问题的方法有二,其一是修改容器的映射ip,但docker文档不支持修改。例如8000:127.0.0.1:8000。但是docker文档不支持这类操作。于是只能采用第二种方法,改变django运行的ip。例如python manage.py runserver 0.0.0.0:8000