1 目录挂载和单个文件挂载
例如下面一个挂载实例, /var/run/license_unix_sock
是个文件,docker 容器通过该 socket 文件和主机上的进程进行通信, /var/www/html/
是目录。
- "/var/run/license_unix_sock:/var/run/license_unix_sock"
- "/var/www/html/:/var/www/html/"
- "/etc/localtime:/etc/localtime"
现象:当运行在主机上的程序重启时候, /var/run/license_unix_sock
发生变化,但是在 docker 容器中挂载的文件并没有发生改变,仍然是旧文件。
原因:对bind mount
这种挂载方式来说,文件的改变会改变它的inode
,但是容器内inode
保持不变。
解决方案:修改为挂载目录。
相关案例:
https://serversforhackers.com/c/mounting-files-vs-directories
https://github.com/docker/docker/issues/15793#issuecomment-135411504
2 使用 docker swarm,容器莫名其妙重启
某些情况下,docker 容器全部重启,经过查看 docker 运行日志,发现下面报错:
Feb 26 11:43:16 sz-drip dockerd[5065]: time="2020-02-26T11:43:16.124650220+08:00" level=error msg="heartbeat to manager { } failed" error="rpc error: code = NotFound desc = node not register
Feb 26 11:43:16 sz-drip dockerd[5065]: time="2020-02-26T11:43:16.124764380+08:00" level=error msg="agent: session failed" backoff=100ms error="node not registered" module=node/agent node.id=
Feb 26 11:43:16 sz-drip dockerd[5065]: time="2020-02-26T11:43:16.124803737+08:00" level=info msg="manager selected by agent for new session: { }" module=node/agent node.id=a5drrk7eo59x4m6itl
Feb 26 11:43:16 sz-drip dockerd[5065]: time="2020-02-26T11:43:16.124835689+08:00" level=info msg="waiting 47.652971ms before registering session" module=node/agent node.id=a5drrk7eo59x4m6itl
Feb 26 11:43:16 sz-drip dockerd[5065]: time="2020-02-26T11:43:16.278198549+08:00" level=info msg="worker a5drrk7eo59x4m6itlbsf28pq was successfully registered" method="(*Dispatcher).register
原因:docker swarm 节点间通信默认超时时间为 5s,在虚拟化环境下有时候会超时,导致节点重启。
解决方案:使用以下命令将心跳超时时间更改为 30s。
docker swarm update --dispatcher-heartbeat 30s
centos 上查看日志方法:journalctl -u docker.service
相关案例:
https://github.com/moby/moby/issues/38107
备注:使用 docker-compose 有时候也会出现启动失败的情况,可以使用下面两个环境变量进行设置:
export DOCKER_CLIENT_TIMEOUT=500
export COMPOSE_HTTP_TIMEOUT=500
3 docker 容器访问宿主机服务
需要在 docker 容器中访问部署在宿主机上的服务,可以采用下面一些方法。
-
采用 host 网络模式
在启动容器时,使用 --net="host" 参数。
-
使用宿主机对外的IP,需要防火墙端口开放。
-
使用 docker0 访问
ip route show | awk '/default/ {print $3}'
注意:这种方式只能访问监听到 0.0.0.0 或者 docker0 上服务。
4 给 docker 指定 IP
首先需要创建自己的网络。
docker network create --subnet=10.12.0.0/16 testnet
然后可以通过运行参数指定 IP
docker run -d --net testnet --ip 10.12.1.32 ubuntu
5 宿主机与容器间文件拷贝
常用的有如下两种方法:
第一种,将目录挂载到容器,然后可以通过 ${PWD}/data 目录将文件拷贝到容器中,或在容器中将文件拷贝至 /data
目录。
docker run -i -v ${PWD}/data:/data ubuntu:latest
第二种,较第一种更为方便快捷。
从容器中拷贝数据到宿主机:
docker cp <containerId>:/file/path/within/container /host/path/target
拷贝文件到容器:
docker cp /host/path/target <containerId>:/file/path/within/container
6 如何启动 docker-compose.yml 文件中的某个服务
在一个 docker-compose.yml 文件中我们经常会定义多个服务,使用 docker-compose up -d
可以将服务全部启动,当我们修改某个服务配置后,再次运行该命令就可以直接重启更改后的服务。
有时候,我们只需要启动其中的某一个服务,而不需要全部启动,可以使用以下命令:
docker-compose up --detach --build xxxx
更新配置或代码后,使用以上命令就可以重新生成容器。
或者
docker-compose up -d xxxx
7 如何清除无用镜像
docker rmi $(docker images | grep -w "keyword" | awk -F " " '{print $3}') -f
或者删除所有镜像:
docker rmi -f $(docker images -q)
8 如何删除磁盘空间
docker volume rm $(docker volume ls -q)
9 如何查看 docker daemon 日志的位置
在不同的系统,查看方式也不同,参考下表:
系统 | 查看方式 |
---|---|
RHEL, Oracle Linux | /var/log/messages |
Debian | /var/log/daemon.log |
Ubuntu 16.04+, CentOS | journalctl -u docker.service 或者查看 /var/log/syslog |
Ubuntu 14.10- | /var/log/upstart/docker.log |
macOS (Docker 18.01+) | ~/Library/Containers/com.docker.docker/Data/vms/0/console-ring |
macOS (Docker <18.01) | ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/console-ring |
Windows | AppData\Local |
参考链接如下:https://docs.docker.com/config/daemon/#read-the-logs
10 如何导入/导出镜像文件
例如将镜像文件 mongodb:4.0.11-xenial 导出至 mongodb.tar 文件中,可以使用以下命令:
docker save mongodb:4.0.11-xenial > mongodb.tar
使用以下命令导入镜像:
docker load < mongodb.tar
11 执行 docker 容器中的命令
例如 mongodb 运行在 docker 容器中,需要使用 mongoimport 导入数据,可以采用以下命令:
docker exec $(docker ps | grep "ms_mongodb" | awk -F " " '{print $1}') mongoimport -u ${MONGOUSER} -p ${MONGOPASSWORD} -d ${MONGODB} -c ${name} --file ${DOCKER_RESOURCE}/${name}.json
其中 ms_mongodb 是容器名。
未完待续
网友评论