附录¶
1.附录A 常见问题总结¶
1.镜像相关¶
1.1 如何备份系统中的所有镜像¶
backup_image.sh
#!/usr/bin/env bash
#usage:xxx
#scripts_name:${NAME}.sh
# author:xiaojian
# 备份镜像列表
docker images |awk 'NR>1{print $1":"$2}'|sort > images.list
# 导出所有镜像为当前目录下文件
while read img; do
echo $img
file="${img//\//-}"
sudo docker save $img > $file.tar
done < images.list
将本地镜像导入为docker镜像
#!/usr/bin/env bash
#usage:xxx
#scripts_name:${NAME}.sh
# author:xiaojian
while read img; do
echo $img
file="${img//\//-}"
sudo docker load < $file.tar
done < images.list
1.2 如何批量清理临时镜像文件?¶
使用如下命令
$ docker rmi $(docker images -q -f dangling=true)
# 查看状态是关闭的镜像
docker ps -a --filter status=exited
1.3 如何删除所有本地的镜像?¶
使用如下命令,删除所有未运行 Docker 容器
$ docker rm $(docker ps -a -q)
# 删除none的镜像,要先删除镜像中的容器。要删除镜像中的容器,必须先停止容器
docker stop $(docker ps -a | grep "Exited" | awk '{print $1 }') //停止容器
docker rm $(docker ps -a | grep "Exited" | awk '{print $1 }') //删除容器
docker rmi $(docker images | grep "none" | awk '{print $3}') //删除镜像
# docker 删除所有none的镜像
docker images|grep none|awk '{print $3}'|xargs docker rmi
# ~/.bash_aliases
# 杀死所有正在运行的容器.
alias dockerkill='docker kill $(docker ps -a -q)'
# 删除所有已经停止的容器.
alias dockercleanc='docker rm $(docker ps -a -q)'
# 删除所有未打标签的镜像.
alias dockercleani=$(docker rmi $(docker images -q -f dangling=true))
# 删除所有未打 tag 的镜像
docker rmi $(docker images -q | awk '/^<none>/ { print $3 }')
# 删除所有已经停止的容器和未打标签的镜像.
alias dockerclean='dockercleanc || true && dockercleani'
# Docker清理数据卷volumes
参考文献:
https://blog.csdn.net/songxi_bo/article/details/119910471
1.4 如何清理Docker系统中的无用数据¶
如下命令会自动清理处于停止状态的容器、无用的网络和挂载卷、临时镜像和创建镜像缓存。
docker system prune --volumes -f
1.5 如何查看镜像内的环境变量?¶
使用如下命令
docker run IMAGE env
1.6 本地的镜像文件都存放在哪里?¶
与Docker相关的本地资源(包括镜像、容器)默认存放在/var/lib/docker/ 目录下。 以aufs文件系统为例,
container目录存放容器信息
graph目录存放镜像信息
aufs目录下存放具体的镜像层文件。
Docker存储位置修改
https://blog.youqiqi.cn/archives/docker-cun-chu-wei-zhi-xiu-gai
1.7 构建Docker镜像应该遵循哪些原则?¶
整体原则上,尽量保持镜像功能的明确和内容的精简,避免添加额外文件和操作步骤,要点包括:
尽量选取满足需求但较小的基础系统镜像,例如大部分时候可以选择debian:wheezy 或debian:jessie 镜像,仅有不足百兆大小
清理编译生成文件、安装包的缓存等临时文件;
安装各个软件时候要指定准确的版本号,并避免引人不需要的依赖;
从安全角度考虑,应用要尽量使用系统的库和依赖;
如果安装应用时候需要配置一些特殊的环境变量,在安装后要还原不需要保持的变量值;
使用Dockerfile创建镜像时候要添加.dockerignore 文件或使用干净的工作目录;
区分编译环境容器和运行时环境容器,使用多阶段镜像创建。
1.8 碰到网络问题,无法pull镜像,命令行指定http_proxy无效,如何处理?¶
在Docker配置文件中添加export http_proxy="http://<PROXY_HOST>:<PROXY_PORT>",之后重启Docker服务即可。
1.9 批量将本地所有kubernetes镜像上传到阿里云¶
pull_all.sh
[root@k8s-master push_images_k8s]# cat pull_all.sh
#!/usr/bin/env bash
#usage:xxx
#scripts_name:${NAME}.sh
# author:xiaojian
PWD=$(pwd)
for image in `docker images|grep -v "REPOSITORY"|grep -v "<none>"|awk '{print $1":"$2}'` ; do
img=${image##*/}
bash ${PWD}/push_image.sh $image
#echo "${PWD}/push_image.sh $image"
done
push_image.sh
[root@k8s-master push_images_k8s]# cat push_image.sh
#!/usr/bin/env bash
#usage:xxx
#scripts_name:${NAME}.sh
# author:xiaojian
#This script is used to upload many images to local or private repositories
# Usage: push_images image1 [image2...]
# 这里是阿里云镜像仓库地址
registry=registry.cn-hangzhou.aliyuncs.com/hu_k8s
echo_r() {
[ $# -ne 1 ] && return 0
echo -e "\033[31m$1\033[0m"
}
echo_g() {
[ $# -ne 1 ] && return 0
echo -e "\033[32m$1\033[0m"
}
echo_y() {
[ $# -ne 1 ] && return 0
echo -e "\033[33m$1\033[0m"
}
echo_b() {
[ $# -ne 1 ] && return 0
echo -e "\033[34m$1\033[0m"
}
usage() {
docker images
echo "Usage: $0 registry:tag1 [registry2:tag2...]"
}
[ $# -lt 1 ] && usage && exit
echo_b "The registry server is $registry"
for image in "$@" ; do
img=${image##*/}
echo_b "Uploading $img"
docker tag $image $registry/$img
docker push $registry/$img
docker rmi $registry/$img
sleep 1
echo_g "Done"
done
1.10 批量导入导出Docker镜像¶
docker导出
$ docker save -o centos-binary-neutron-server-2.0.0.5.tar.gz kollaglue/centos-binary-neutron-server:2.0.0.5
docker导入
$ docker load < centos-binary-neutron-server-2.0.0.5.tar.gz
docker导出镜像
#!/bin/bash
IMAGES_LIST=($(docker images|sed '1d'|awk '{print $1}'))
IMAGES_NM_LIST=($(docker images|sed '1d'|awk '{print $1"-"$2}'|awk -F/ '{print $NF}'))
IMAGES_NUM=${#IMAGES_LIST[*]}
for((i=0;i<$IMAGES_NUM;i++))
do
docker save "${IMAGES_LIST[$i]}" -o "${IMAGES_NM_LIST[$i]}".tar.gz
echo $i ${IMAGES_NM_LIST[$i]} is ok
done
docker导入镜像
#!/bin/bash
for image_name in $(ls ./*.tar.gz)
do
docker load < ${image_name}
done
1.11 批量删除指定 repository 所有镜像工具¶
#!/bin/sh
# Writed by yijian on 2020/8/31
# 批量删除指定 repository 所有镜像工具
# 运行时需要指定一个参数:
# 1)参数1:必选参数,repository 名,即“docker images”的第一列值
function usage()
{
echo "Remove all images with the given repository."
echo "Usage: `basename $0` repository"
echo "Example1: `basename $0` \"<none>\""
echo "Example2: `basename $0` \"redis\""
}
# 参数检查
if test $# -ne 1; then
usage
exit 1
fi
repository="$1"
images=(`docker images|awk -v repository=$repository '{ if ($1==repository) print $3 }'`)
for ((i=0; i<${#images[@]}; ++i))
do
image="${images[$i]}"
echo "[$i] docker rmi \"$image\""
docker rmi "$image"
done
1.12 Docker清理数据卷¶
Docker 查看数据卷及磁盘使用情况
Docker 在长时间使用的情况下,经常需要删除旧的容器并创建新的容器,长此以往,Docker 的数据卷 volumes 会产生了非常多的僵尸文件,这些将是稳健大都是未绑定容器的目录
查询僵尸文件
在 Docker 1.9 以上的版本中,官方提供用于查询僵尸文件的命令:
docker volume ls -qf dangling=true
Docker 1.13 引入了类似于 Linux 上 df 的命令,用于查看 Docker 的磁盘使用情况
> docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 2 1 306.6MB 233.7MB (76%)
Containers 1 1 12.62GB 0B (0%)
Local Volumes 20 0 16GB 16GB (100%)
Build Cache 0 0 0B 0B
上述信息可以看出
Docker 镜像占用了 306.6MB 磁盘,
Docker 容器占用了 12.62GB 磁盘,
Docker 数据卷占用了 16GB 磁盘。
Docker 删除无用数据卷
手动删除命令
# 删除所有dangling数据卷(即无用的Volume,僵尸文件)
docker volume rm $(docker volume ls -qf dangling=true)
# 删除所有dangling镜像(即无tag的镜像)
docker rmi $(docker images | grep "^<none>" | awk "{print $3}")
# 删除所有关闭的容器
docker ps -a | grep Exit | cut -d ' ' -f 1 | xargs docker rm
删除关闭的容器、无用的数据卷和网络,以及dangling镜像(即无tag的镜像)
注意,所有关闭的容器都会被删除,请核查是否存在关闭运行但是需要保留的容器
# 删除关闭的容器、无用的数据卷和网络
docker system prune
# 删除更彻底,可以将没有容器使用Docker镜像都删掉
docker system prune -a
重启 Docker
使用上面几个方法的命令可以有效清理 Docker 运行所产生的无用文件,且无需重启 Docker 即可生效。
但是 Docker 也许存在某些 bug(内核 3.13 版本的 Docker 确诊),导致 Docker 无法清理一些无用目录,不过重启 Docker 可以解决这个问题
参考文献:
https://www.cnblogs.com/zhuminghui/p/14566178.html
https://blog.csdn.net/truelove12358/article/details/102949386
1.13 Docker垃圾处理¶
1 查找docker文件夹
find / -name docker
2 列举文件夹大小
du -h --time --max-depth=1 .
df -h
df -TH
3 Docker占用磁盘空间查看
docker system df
4 删除所有未运行的容器(也可以使用docker-gc)
docker rm $(docker ps -a|grep Exited |awk '{print $1}')
docker rm $(docker ps -qf status=exited )
5 删除所有未打标签的 镜像
docker rmi $(docker images -q -f dangling=true)
6 删除所有无用的volume
docker volume rm $(docker volume ls -qf dangling=true)
7 清理磁盘,删除关闭的容器,无用的数据卷和网络
docker system prune
8 停止所有运行的容器
docker stop $(docker ps -q)
9 停止所有容器
docker stop $(docker ps -a -q)
10 删除所有容器
docker rm $(docker ps -aq)
11 删除所有镜像
docker rmi $(docker images -q)
2.容器相关¶
2.1 容器退出后,通过docker ps 命令查看不到,数据会丢失么?¶
容器退出后会处于终止(exited)状态,此时可以通过docker ps
-a查看。其中的数据也不会丢失,还可以通过
docker [container] start命令来启动它。
只有删除掉容器才会清除所有数据。
2.2 如何停止所有正在运行的容器¶
可以使用 docker [container] stop $(docker ps -q) 命令
2.3 如何批量清理所有的容器,包括处于运行状态和停止状态的¶
可以使用 docker [container] rm -f $(docker ps -qa) 命令
2.4 如何获取某个容器的PID信息¶
可以使用 docker [container] inspect --format '{{ .State.Pid }}' <CONTAINER ID or NAME> 命令。
2.5 如何获取某个容器的IP地址?¶
可以使用 docker [container] inspect --format '{{ .NetworkSettings.IPAddress }}' <CONTAINER ID or NAME> 命令。
2.6 如何清理 Docker 占用的磁盘空间¶
https://zhuanlan.zhihu.com/p/100793598
迁移/var/lib/docker目录
https://blog.csdn.net/weixin_32820767/article/details/81196250
https://www.lemonlzy.cn/2020/05/24/Docker%E6%96%87%E4%BB%B6%E6%B8%85%E7%90%86/
2.7 给运行中的docker容器添加端口映射¶
1.获取容器IP
$ docker inspect <container_id> | grep IPAddress
2.通过iptable转发端口,并做映射
$ iptables -t nat -A DOCKER -p tcp --dport 50000 -j DNAT --to-destination 172.17.0.3:50000
3.重启容器
$ docker restart <container_id>
2.8 如何临时退出一个正在交互的容器的终端,而不终止它?¶
按Ctrl-p Ctrl-q。如果按Ctrl-c往往会让容器内应用进程终止,进而会终止容器。
2.9 可以在一个容器中同时运行多个应用进程么?¶
一般并不推荐在同一个容器内运行多个应用进程。如果有类似需求,可以通过一些额外的进程管理机制,比如supervisord,来管理所运行的进程。可以参考https://docs.docker.com/articles/using_supervisord/。
2.10 如何控制容器占用系统资源(CPU、内存)的份额?¶
在使用docker[container]create命令创建容器或使用docker[con-tainer]run创建并启动容器的时候,
可以使用-c|-cpu-shares[=0]参数来调整容器使用CPU的权重;
使用-m|-memory[=MEMORY]参数来调整容器使用内存的大小。
3.配置相关¶
3.1 Docker的配置文件放在哪里,如何修改配置?¶
使用upstart的系统(如Ubuntu 16.04)的配置文件在/etc/default/docker,
使用systemd的系统(如Ubuntu 16.04、Centos等)的配置文件在/etc/systemd/system/docker.service.d/docker.conf。
3.2 如何更改Docker的默认存储位置?¶
Docker的默认存储位置是/var/lib/docker,如果希望将Docker的本地文件存储到其他分区,可以使用Linux软连接的方式来完成,或者在启动daemon时通过-g参数指定。
例如,如下操作将默认存储位置迁移到/storage/docker:
[root@s26 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 50G 5.3G 42G 12% /
tmpfs 48G 228K 48G 1% /dev/shm
/dev/mapper/VolGroup-lv_home 222G 188M 210G 1% /home
/dev/sdb2 2.7T 323G 2.3T 13% /storage
[root@s26 ~]# service docker stop
[root@s26 ~]# cd /var/lib/
[root@s26 lib]# mv docker /storage/
[root@s26 lib]# ln -s /storage/docker/ docker
[root@s26 lib]# ls -la docker
lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
[root@s26 lib]# service docker start
3.3 开发环境中Docker和Vagrant该如何选择?¶
Docker不是虚拟机,而是进程隔离,对于资源的消耗很少。Vagrant是虚拟机上做的封装,虚拟机本身会消耗更多资源。如果本地使用的Linux环境或macOS,推荐都使用Docker;
如果本地使用的是Windows环境,可以考虑用虚拟机获取一致的体验。
4. 其他¶
4.1 如何将一台宿主主机的Docker环境迁移到另外一台宿主主机?¶
停止Docker服务。将整个Docker存储文件夹(如默认的/var/lib/docker)复制到另外一台宿主主机,然后调整另外一台宿主主机的配置即可。
2. 参考资源链接¶
官方网站
Docker官方主页:https://www.docker.com
Docker官方博客:https://blog.docker.com/
Docker官方文档:https://docs.docker.com/
Docker Hub:https://hub.docker.com
Docker公司的开源代码仓库:https://github.com/docker
Docker的开源项目Moby仓库:https://github.com/moby/moby
Docker发布版本历史:https://docs.docker.com/release-notes/
Docker常见问题:https://docs.docker.com/engine/faq/
Docker SDK和API:https://docs.docker.com/develop/sdk/
开发容器组织OCI:https://www.opencontainers.org/
实践参考
Dockerfile参考:https://docs.docker.com/engine/reference/builder/
Dockerfile最佳实践:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/