## 背景
> 在开发过程中经常会遇到批量创建容器,拉取镜像等一系列的操作,如果手动一个一个的操作,那将浪费很多时间,而且毫无技术含量,因此要提高工作效率,必须让这些动作能够实现自动化,最不济也要实现半自动化,下面介绍一些我最常用的一些脚本工具。


##场景分析
- 批量停止并删除容器(filter为需要处理的容器共同标识符)
>通常我们在测试某个服务时,可能会涉及多个工具,比如web服务,我们需要启动tomcat服务器、数据库,nginx等(存在一种情况,在启动容器时需要给每个容器设定一个名字,设定名字有一个好处,我们可以把一组相互协作的容器设定为相同的前缀,一方面方便管理,另一方面,易于实现自动化),如果web服务启动失败了或者需要停止容器,则需要重启,重启时就会发生容器名字冲突,一种较好的方式就是清掉启动失败的容器,再重启。


停止容器(适用于具有相同的容器名前缀或者各个镜像的名字类似)


```
docker ps | grep filter | awk '{print $1}' | xargs docker stop  


#该条命令分为四部分,docker ps, grep filter, awk '{print $1}', xargs docker stop
 docker ps 用于列出所有正常运行的容器
|grep filter 将上一命令的结果通过管道传给过滤器,过滤条件为包含filter关键字
|awk '{print $1}' 将上一命令的结果通过管道传给awk,  awk '{print $1}' 打印第一列的数据,也就是容器ID
| xargs docker stop 将上一命令的结果通过管道传给xargs, xargs 将参数传给docker stop,然后停止这些容器。
```


删除容器(方法一)
```
docker ps -a | grep filter | awk '{print $1}' | xargs docker rm -f 


#在这里重点说明下docker ps -a 和 xargs docker rm -f
docker ps -a 列出所有的容器,包括运行的和未运行的,各种状态全部列出来
| xargs docker rm -f将上一命令的结果通过管道传给xargs, xargs 将参数传给docker rm -f ,然后删除这些容器。
```
- 删除所有退出的容器(以下几种方式均可)
>除了前面介绍的批量删除容器,下面几种方式也可以很好的使用,只是它们的使用场景不一样,上面介绍的方式适用于具有相同的容器名前缀或者各个镜像的名字类似,并采用了管道方式,此处介绍的这几种则是根据容器的状态则为过滤的条件,未采用管道。


方法二
```
docker rm -f $(docker ps -qf status=exited )
#docker ps -qf status=exited 列出所有退出状态的容器
docker ps -qf 列出所有的容器Id
option: -q 只展示容器ID
option: -f 过滤器
status=exited过滤条件为退出状态
```
方法三
```
docker rm -f $(docker ps -a | grep Exited | awk '{print $1}')
#这种方式是第一种方式的变体,只是未使用xargs工具


```
方法四
```
docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm
#这种方法是方法一的特例,grep Exited,抓取Exited关键字,通常在容器的状态栏会出现该字样
```


- 清理容器所在的主机的存储空间
>通常,过一段时间,容器运行就会存在垃圾,除了上面介绍的容器,还会有一些volume需要清理,同时,还有一些无用的镜像需要删除,这样才是比较全面的清楚容器运行空间。按照创建容器的反序清理,应该是先清理掉退出的容器,然后再删除volume,最后是镜像,因为启动一个容器是先准备镜像,然后创建一些volume,然后容器才能创建成功。


```
#step1.删除已经退出的容器


docker rm $(docker ps -qf status=exited)


#step2.删除volume


docker volume rm $(docker volume ls -qf dangling=true)


#step3.删除未使用的镜像


docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
# 解释一下两个option
--filter "dangling=true" 过滤条件未所有伟大标签的镜像
--no-trunc 输出字段全部打印出来


```


## docker容器启动option
>在这里根据自己的经验,给大家一个建议,我们在创建一个容器时,最好将启动命令脚本化,这样有两个好处:
>- 方便管理 ,容器启动失败或者修改启动参数时,只需要修改启动脚本中的参数即可,不需要每次都敲一大堆参数,命令。
>- 轻松实现自动化,在重启容器时,只需要简单的执行一个脚本即可,尤其是在批量处理时。


下面介绍一些常用的启动参数


```
# 容器退出自动重启
docker run --restart=always ...


# 容器异常退出自动重启
docker run --restart=on-failure ...


# 容器异常退出自动重启,最多重启5次
docker run --restart=on-failure:5
```


## 镜像批量处理
- 从dockerhub上批量拉取并保存到本地
>如果从docker hub上拉取单个镜像,一条简单的命令久可以很容易完成,如果时多个镜像,全部依靠手动的方式,一方面浪费时间,另一方面,你得不定时得盯着,等到一个镜像拉取完成后再起执行下一个拉取命令,很明显需要自动化处理。因此在想能否只需要配置下镜像下载的列表,其他的工作让电脑来做,不多说,实现如下
> step1.将要拉取的镜像列表保存到文件中,例如保存文件名为:docker-images.dat
注意格式包括镜像名和版本号,否则将拉取latest版本的镜像
> 数据格式要求如下:
>- 每一行只能包含一个镜像信息
>- 每一行都能完整的表达一个镜像,一个镜像完整的信息应该包含仓库名/镜像名:版本(repository/image:version)
docker-images.dat数据格式举例,例如下面的数据:
```
rancher/server:v1.6.10
rancher/agent:v1.2.6
rancher/network-manager:v0.7.8
rancher/net:v0.11.9
rancher/dns:v0.15.3
rancher/metadata:v0.9.4
rancher/healthcheck:v0.3.3
rancher/lb-service-haproxy:v0.7.9
rancher/scheduler:v0.8.2
rancher/net:holder
```


> step2.编写保存镜像脚本
>文件名为:pull_and_save_images.sh,大致逻辑如下:读取配置文件中每一行,然后docker pull下来,再将其转化为可以保存的的镜像,保存到本地,因为镜像拉取到本机后,无法直接将其保存成文件,因为
>- 文件中不能包含冒号(:),
>- 文件中应该包含一些有用的信息,如版本,镜像名等
>一种简单的处理方式是,在配置文件中直接添加进去,在读取的时候,直接分割,获取第二列的即可,我在这里通过拼接的方式来处理,实现的脚本如下:
```
#!/bin/bash


cat $1 | while read line 
do
  echo "docker images name is :${line}"
  #docker pull ${line}
  sub_name=${line };
  name=($sub_name)
  len=${#name[@]}
  echo "length $len"
  pkg=${name[$len-1]}".tar"
  echo "docker save $line -o $pkg"
  docker save $line -o $pkg
done
```
> step3.修改文件为可执行,再执行脚本
```
chmod a+x  pull_and_save_images.sh
sh pull_and_save_images.sh docker-images.dat
```


- 批量加载docker镜像压缩包
> 镜像默认压缩为tar格式的压缩文件, 脚本名称为:load_images.sh
```
#!/bin/bash


ls | grep $1 | while read line
do
   echo "the docker images tar file is : ${line}"
   docker load -i ${line}
done
```
修改文件执行权限并执行


- 使用举例:
```
chmod a+x load_images.sh && sh load_images.sh tar
```


- 批量保存本地镜像load_local_images.sh
```
#/bin/bash
filter=$1
docker images |grep  $filter | awk '{print $3,$1,$2}' | while read line


do
  echo "docker image is : ${line}"
  arr=(${line})
  id=${arr[0]}
  sub_name=${arr[1] };
  name=($sub_name)
  len=${#name[@]}
  echo "length $len"
  pkg=${name[$len-1]}"~"${arr[2]}".tar"
  echo "docker save $id -o $pkg"
  docker save $id -o $pkg
done
chmod a+x load_local_images.sh
```
- 使用举例:


sh load_local_images.sh rancher


- 从本地主机保存镜像


> 为了处理方便,我们也可以将处于进行状态的容器直接保存下来,get_docker_images.sh
```
#!/bin/bash


docker ps | grep $1 | awk '{print $2}' | while read line


do
  echo "docker image name is : ${line}"
  sub_name=${line };
  name=($sub_name)
  len=${#name[@]}
  echo "length $len"
  pkg=${name[$len-1]}".tar"
  echo "docker save $line -o $pkg"
  docker save $line -o $pkg
done
chmod a+x get_docker_images.sh
sh get_docker_images.sh rancher
```
持续更新中。。。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐