附录

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/