Docker是什么

docker是linux容器的一种封装,提供简单易用的容器使用接口。它是最流行的Linux容器解决方案 。

docker将应用程序与程序的依赖,打包在一个文件里面。运行这个文件就会生成一个虚拟容器。

程序运行在虚拟容器里,如同在真实物理机上运行一样,有了docker,就不用担心环境问题了。

image.png

应用场景

web应用的自动化打包和发布 自动化测试和持续集成、发布 在服务型环境中部署和调整数据库或其他应用

镜像和容器

  • 镜像是类class,容器是实例化的类,镜像是文件,容器是进程
  • 先有镜像后有容器,一个镜像可以启动多个容器
  • 一旦容器从镜像被启动,二者编程互相依赖的关系,在镜像上启动的容器没有停止之前,镜像无法被删除
  • 镜像采用分层结构,最底层是base层操作系统层,层层叠加形成完成的镜像,目的是实现层和资源共享

镜像搜索

Docker镜像存储在镜像仓库服务中,默认使用Docker Hub,Docker Hub分为官方仓库和非官方仓库,官方仓库会经过Docker公司的审核并且及时更新,安全质量高,非官方的仓库来自于江湖侠客,其中也不乏优秀的镜像,使用docker search来搜索镜像

image.png

对以上命令和返回结果做几点说明

  • search:会对Docker仓库服务进行检索,检索其中NAMEDESCRIPTION相关含有mysql内容的镜像
  • NAME:仓库名称,如果是官方仓库就直接是仓库名称,如果是非官方仓库,仓库名称带有/,代表机构名或者组织机构名/仓库名
  • DESCRIPTION:镜像描述
  • STARS:用户喜欢程度
  • OFFICIAL:是否是官方仓库,OK的话就是官方仓库,和NAME中是否带有/是一致的
  • AUTOMATED:Dockerfile是否是公开的可供自由查看

docker默认输出25行,使用--limit参数可以指定输出的行数,可以给search命令增加过滤条件,使用--filter获得官方仓库
image.png


镜像下载、查看、删除

从Docker镜像仓库服务中拉取镜像使用命令docker pull,指定仓库名称标签即可找到指定的镜像,命令格式是

  1. docker image pull <repository>:<tag>

如果不指定tag,默认拉取latest标签的镜像,如果要拉取指定tag版本的镜像,需要登录docker hub进行查找
https://hub.docker.com,比如查看docker上支持的MySQL版本,有8.0.25,8.0等

基本概念 - 图4

  • 非官方的镜像镜像仓库需要指定机构组织名/仓库名,比如tiangolo/uvicorn-gunicorn-fastapi

以mysql为例,分别指定tag镜像标签和不指定,使用docker images查看本地仓库存储的镜像

image.png

删除镜像使用docker rmi,指定镜像名称或者镜像ID,当存在此镜像启动的容器正在运行或者此镜像是其他镜像所依赖的镜像时,不能直接删除
image.png


镜像命令整理

  • docker search:去镜像仓库服务搜索镜像
  • docker images:显示本地仓库已有的镜像
  • docker pull:从镜像仓库服务拉取镜像到本地仓库
  • docker rmi:从本地镜像服务删除镜像

Dockerfile基础

Dockerfile是一个Docker镜像的描述文件,包含了若干个命令行,支持以#进行注释,它的结构分为基础镜像层维护者操作指令容器启动后指令,以一个简单的Dockerfile为例

FROM
  基于哪个镜像
MAINTAINER
  用来写备注信息,例如作者、日期等。
COPY
  复制文件进入镜像(只能用相对路径,不能用绝对路径)
ADD
  复制文件进入镜像(可以用绝对路径,假如是压缩文件会解压)
WORKDIR
  指定工作目录,假如路径不存在会创建路径
ENV
  设置环境变量
EXPOSE
  暴露容器端口到宿主机
RUN
  在构建镜像的时候执行一条命令,作用于镜像层面
  shell命令格式:RUN yum install -y net-tools
  exec命令格式:RUN [ "yum","install" ,"-y" ,"net-tools"]
ENTRYPOINT
  在容器启动的时候执行,作用于容器层,dockerfile里有多条时只允许执行最后一条
CMD
  在容器启动的时候执行,作用于容器层,dockerfile里有多条时只允许执行最后一条
  容器启动后执行默认的命令或者参数,允许被修改

基本概念 - 图7

下面对Dockerfile的常用关键字进行总结:

  • FROM:基础镜像,当前新镜像是基于哪个镜像的
  • MAINTAINER:镜像维护者的姓名和邮箱地址
  • RUN:容器构建时需要运行的命令,可以执行多个命令,多个命令用&&隔开
  • EXPOSE:当前容器对外暴露的端口号,实际没什么用
  • WORKDIR:指定在容器创建后,终端默认登录进来工作目录,一个落脚点,可以多次指定,相当于cd命令
  • ENV:用来在构建镜像过程中设置环境变量,在下文中使用${profile}调用
  • ADD:将宿主机目录下的文件拷贝到镜像里面,宿主机路径->镜像路径,在构建镜像的过程中完成的,ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中
  • COPY:将宿主机目录下的文件拷贝到镜像里面,宿主机路径->镜像路径,它只是拷贝,不会自动处理URL和解压tar压缩包,在构建镜像的过程中完成的,满足同等功能的情况下,推荐使用COPY指令
  • CMD:指定一个容器启动时要运行的命令。dockerfile中可以有多个CMD指令,但只有最后一个生效,是容器启动后的命令,如果docker run指定了运行命令会被覆盖,支持Shell和exec模式
  • ENTRYPOINT:指定一个容器启动时要运行的命令,容器启动后的命令,如果docker run指定了运行命令不会被覆盖,支持Shell和exec模式

其中CMD和ENTRYPOINT支持shell和exec模式,在Dockerfile中可以做如下改写

CMD ["gunicorn", "-c", "gun.conf.py", "manage:app"]

RUN中多个命令用&&隔开,可以在Dockerfile中做如下改写

RUN pip install flask==1.1.1 \
    && pip install Flask-SQLAlchemy==2.4.4 \
    && pip install gevent==20.9.0 \
    && pip install gunicorn==20.0.4 \
    && pip install numpy==1.19.5 \
    && pip install pymysql==1.0.0 \
    && pip install SQLAlchemy==1.3.13 \
    && pip install python-dotenv==0.15.0 \
    && pip install Flask-Caching==1.9.0

使用Dockerfile构建镜像

使用Dockerfile构建镜像使用docker build命令,启动如下

root@ubuntu:~/myproject/pira_score_web_application# docker build -t gp/pira_score:v1 .

docker build中最后的.代表当前目录,通常把Dockerfile放在执行docker build的当前目录下,其他主要参数如下

  • -t:—tag, -t: 镜像的名字及标签,本例中设置了gp/pira_score名称和v1标签
  • -f:指定要使用的Dockerfile路径

构建完成后查看docker本地镜像仓库

root@ubuntu:~/myproject/pira_score_web_application# docker images
REPOSITORY                 TAG           IMAGE ID        CREATED          SIZE
gp/pira_scor               v1           d3f18f8689fb   14 minutes ago     976MB

镜像的导入导出

镜像的导出使用docker save命令,例如

root@ubuntu:~# docker save echo_test:v1 > echo_test_v1.tar

注意save指定的镜像指定为镜像名+标签,否则load导入时镜像名为,下一步在当下目录下生成镜像tar文件,scp到另一台机器上的docker服务上再load进去则会自动导入一个名称和标签一样的镜像

root@ubuntu:~# scp echo_test_v1.tar root@cloudera01:/home/gp
[root@cloudera01]# docker load < echo_test_v1.tar 
Loaded image: echo_test:v1