docker是一门容器技术,可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。

安装

  • 根据docker官方文档的步骤即可完成安装。
  • 将非root用户加入docker用户组即可通过该用户管理docker。(讲解
  • 记得切换为国内镜像源(阿里云源)。
  • 推荐:菜鸟教程-docker命令大全
  • 可以通过docker command --help(例如:docker run --help)查看docker命令使用方法。

docker启动相关的命令

1
2
3
4
5
启动docker:systemctl start docker
查看docker服务状态:systemctl status docker
停止docker:systemctl stop docker
重启docker:systemctl restart docker
开机启动docker:systemctl enable docker

docker镜像相关的命令

当运行容器时,使用的镜像如果在本地中不存在,docker就会自动从docker镜像仓库中下载,默认是从docker hub公共镜像源下载。

查看本地镜像:

1
docker images

查看所有镜像ID

1
docker images -q

搜索镜像:

1
docker search 镜像名称

拉取镜像:

1
2
docker pull 镜像名称:版本号
docker pull 镜像名称 #不指定版本号,直接拉取当前最新版本

设置镜像标签:

1
docker tag 容器名或容器id 镜像原名:新标签名

删除镜像:

1
2
docker rmi 镜像id
docker rmi 'docker images -q' #删除所有本地镜像

docker容器相关命令

当运行容器时,使用的镜像如果在本地中不存在,docker就会自动从docker镜像仓库中下载,默认是从docker hub公共镜像源下载。

创建容器:

1
2
3
4
5
6
7
docker run 参数
例如:
docker run -i -t --name=自定义容器名 镜像名称 /bin/bash
docker run -it --name=自定义容器名 镜像名称 /bin/bash
docker run -it --name 自定义容器名 镜像名称 /bin/bash
#以上三种等价
docker run -itd --name=自定义容器名 镜像名称 /bin/bash

部分参数说明:

  • -i:保持容器运行(菜鸟教程:交互式操作),通常与-t同时使用,写作-it。加入-it后,容器创建后自动进入容器中,输入exit退出。退出容器后,容器自动关闭。

  • -t:为容器重新分配一个伪输入终端,通常与-i合用。

  • -d:创建容器并后台运行。使用docker exec进入容器,按exit退出,不会停止。

  • 一般来说:-it创建的容器为交互式容器,-id创建的容器为守护式容器。

  • --name:为创建的容器命名。

  • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式Shell,因此用的是 /bin/bash

  • -p:端口映射,容器内部端口绑定到指定的主机端口。例如-p 500:50,把容器里的50端口映射到宿主机的500端口上。又比如,-p 192.168.1.100:8080:80,将容器里的80端口映射到IP地址为192.168.1.100宿主机的8080端口。

  • -P:容器内部端口随机映射到主机的端口。

查看容器:

1
2
docker ps #查看正在运行的容器
docker ps -a #查看所有容器(运行未运行的都将列举)

进入容器:

1
docker attach 容器名或容器id

如果从这个容器退出,导致容器的停止。

推荐:

1
docker exec -it 容器名或容器id /bin/bash

如果从这个容器退出,不会导致容器的停止。

停止容器:

1
docker stop 容器名或容器id

启动容器:

1
docker start 容器名或容器id

重启容器:

1
docker restart 容器名或容器id

删除容器:需要停止容器才能删除

1
docker rm 容器名或容器id

清理掉所有处于终止状态的容器:

1
docker container prune

强制删除容器:运行中的容器也可以删除

1
docker rm -f 容器名或容器id

导出容器:盲猜是导出到执行该命令的目录。

1
docker export 容器id > 随便起名.tar

导入容器:

1
cat docker/随便起名.tar | docker import -随便用户名/随便镜像名:随便版本号 

查看容器开放端口:

1
docker port 容器名或容器id

查看日志:

1
2
docker logs 容器名或id
docker logs -f 容器名或id #让docker logs像使用tail -f一样来输出容器内部的标准输出

查看容器内部运行的进程:

1
docker top 容器名或容器id

查看容器信息:

1
docker inspect 容器名或容器id

容器数据卷

解决问题:

  • docker容器删除后,容器内数据储存。
  • docker容器内外数据交互。
  • docker容器间数据交互(多个容器挂载1个数据卷或者数据卷容器)。

数据卷:

  • 数据卷是宿主机的一个目录或文件。
  • 当容器目录和数据卷目录绑定后,对方的修改会立即同步。
  • 一个容器可以挂载多个数据卷。

配置数据卷:

1
docker run ... -v 宿主机目录(文件):容器内目录(文件) ...
  • 目录必须是绝对路径。
  • 目录不存在会自动创建。
  • 可以挂载多个数据卷,多写几个-v即可。

数据卷容器:也可以用于多容器数据交互。

创建数据卷容器:

1
2
3
docker run -itd --name=自定义名字1 -v /volume 镜像名:版本号 /bin/bash #会自动且随机创建宿主机目录

docker run -itd --name=自定义名字1 -v 宿主机目录(文件):容器内目录(文件) 镜像名:版本号 /bin/bash

创建其他容器,并关联数据卷

1
2
docker run -it --name=自定义名字2 --volumes-from 自定义名字1 镜像名:版本号 /bin/bash
docker run -it --name=自定义名字3 --volumes-from 自定义名字1 镜像名:版本号 /bin/bash

dockerfile

前提:

  • linux文件系统由bootfsbootloader引导加载程序和kernel内核)和rootfsroot文件系统,包括/dev /proc /bin /etc)两部分组成。不同linux发行版,bootfs基本一致,rootfs不同。

docker镜像原理:

  • docker镜像由特殊的文件系统叠加而成。
  • 最底端是bootfs,并使用宿主机的bootfs
  • 第二层是root文件系统rootfs,称为base image
  • 然后再往上可以叠加其他的镜像文件。
  • 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供一个统一的视角,这样就隐藏了多层的存在,在用户角度来看,只存在一个文件系统。
  • 一个镜像可以放在另一个镜像上面,位于下面的镜像称为父镜像,最底层的镜像称为基础镜像。
  • 当从一个镜像启动为容器时,docker会在最顶层加载一个读写文件系统作为容器。

形象示意图

docker镜像制作有两种方法:

  1. 从已经创建的容器中更新镜像,并且提交这个镜像。(即已经创建的容器转为镜像)

    注意:通过此方法挂载到宿主机的目录不会被打包成镜像。

    1.1 制作新的镜像

    1
    2
    3
    docker commit 参数 已创建容器id 镜像名字:版本号
    例如:
    docker commit -m="描述信息" -a="描述作者" 已创建容器id 镜像名字:版本号

    参数说明:

    • -m:提交的描述信息。
    • -a:镜像作者。

    注: 已创建容器即为在原有容器基础上已经作出更改并需要传给他人的容器。

    1.2 将新的镜像转成压缩文件,便于传输

    1
    docker save -o 压缩文件名称 镜像名称:版本号

    1.3 将压缩文件还原成镜像

    1
    docker load -i 压缩文件名称 镜像名称:版本号
  2. 使用dockerfile指令来创建一个新的镜像。

    • dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
    • 每一条(行)指令基于父镜像构建一层子镜像,层层叠加,最终构建出一个完整的新镜像。因此,编些dockerfile文件时平行指令用&&连接,用\换行。

    最好在docker官网参照他人的dockerfile写。

    • 关键词必须全是大写。
    关键词 作用 备注
    FROM 指定父镜像 指定dockerfile基于哪个image构建
    MAINTAINER 作者信息 用来标明这个dockerfile是谁写的
    LABEL 标签 用来标明dockerfile的标签,可以用LABEL代替MAINTAINER,最终都可以在docker image基本信息中查看。格式:LABEL = = =
    RUN 执行命令 执行一段命令,在docker build的时候使用,默认/bin/sh。在构建镜像时执行的命令。格式:RUN command或者RUN [“command”,”param1”,”param2”]
    CMD 容器启动命令 提供启动容器时候(docker run)的默认命令,和ENTRYPOINT配合使用。即,当我们使用docker run启动该镜像生成容器时,镜像会在生成的容器内执行的命令。格式:CMD command param1 param2或者CMD [“command”,”param1”,”param2”]
    ENTRYPOINT 入口 一般在指定一些执行后就关闭
    COPY 复制文件 build的时候复制宿主机本地文件到image中
    ADD 添加文件 build的时候添加文件到image中,不仅仅局限于build上下文,可以来源于远程服务。但其会自动将压缩文件解压,在不解压的情况下,无法复制压缩文件
    ENV 环境变量 制定build时候的环境变量,可以在启动容器的时候,通过-e覆盖,格式ENV name=value
    ARG 构建参数 只有在构建参数的时候使用,仅在dockerfile内有效,构建完镜像后不存在此环境变量。如果有ENV,那么ENV相同名字的值始终覆盖ARG。格式:ARG <参数名>[=<默认值>]
    VOLUME 定义外部可挂载的数据卷 指定build的image在启动时哪些目录可以挂载在宿主机文件系统,启动容器时使用-v绑定,如果忘记挂载数据卷,会自动挂载到匿名卷。格式VOLUME [“目录”]
    EXPOSE 暴露端口 定义容器运行时候的监听窗口,帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。启动容器时使用-p来绑定暴漏端口。格式:EXPOSE 8080或者EXPOSE 8080/ucp
    WORKDIR 工作目录 指定容器内部的工作目录,会在构建镜像的每一层中都存在,且如果没有创建则自动创建,如果指定/使用的是绝对地址,如果不是/开头那么那么是相对路径。格式:WORKDIR <工作目录路径>
    USER 指定执行用户 指定build或者启动的时候,在RUN、CMD、ENTRYPOINT执行命令的用户(用户和用户组必须存在)。格式:USER <用户名>[:<用户组>]
    HEALTHCHECK 健康检查 指定当前容器健康检测的命令,一般没用,应用本身有健康监测机制。
    ONBUILD 触发器 用于延迟构建命令的执行。即当dockerfile 里有ONBUILD指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的dockerfile使用了之前构建的镜像(FROM test-build),这时执行新镜像的dockerfile构建时候,会执行test-build的dockerfile的ONBUILD指定的命令。格式:ONBUILD <其它指令>
    STOPSIGNAL 设置发送容器的系统调用信号以退出
    SHELL 指定执行脚本的shell 指定RUN、CMD、ENTRYPOINT执行时候使用的shell
    1
    2
    3
    4
    5
    docker build -f dockfile路径 -t 镜像名称:版本
    docker build -t 镜像名称:版本 .
    #dockfile文件名可以命名为centos_dockfile.......
    例如:
    docker build -t hexo:1.0 -f /home/jian/dockerfile/hexo_dockerfile . #这个点无论如何都好像不能省

    参数:

    • -fdockerfilecentos_dockerfile之类的文件路径。
    • -t:指定镜像名称。
    • .:上下文路径,默认为dockerfile文件所在的位置,可以指定绝对路径,但即使是绝对路径.也不能省。
    • 上下文路径下不要放无用的文件,因为会一起打包发送给docker引擎,如果文件过多会造成过程缓慢。

    例如1:

    要求:自定义centos7镜像,默认登陆路径为/usr,可以使用vim

    1
    2
    3
    4
    5
    FROM centos:7 #定义父镜像
    MAINTAINER jiansreer <me@heyjian.cn> #定义作者信息
    RUN yum install -y vim #执行安装vim命令
    WORKDIR /usr #定义默认的工作目录
    CMD /bin/bash #定义容器启动执行的命令

    使用dockerfile构建docker镜像:

    1
    2
    docker build -f 'dockfile路径' -t '镜像名称:版本'
    #dockfile文件名可以命名为centos_dockfile.......

    例如2:

    要求:定义docker,发布springboot项目。

    1
    2
    3
    4
    FROM java:8
    MAINTAINER jiansreer <me@heyjian.cn>
    ADD springboot.jar app.jar #将jar包添加到容器,改名为 app.jar
    CMD java -jar app.jar

    docker服务编排

    微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。

    • 要从dockerfile或者从dockerhub拉取image
    • 要创建多个container
    • 要管理(启动、停止、删除)这些container

    服务编排:按照一定的业务规则批量管理容器。

    docker compose

    docker compose是用于定义和运行多容器docker应用程序的工具。通过compose,可以使用YML文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从YML文件配置中创建并启动所有服务。

    步骤:

    • 使用dockerfile定义运行程序的环境。
    • 使用docker-compose.yml定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
    • 最后,执行docker-compose up命令来启动并运行整个应用程序。

    docker compose在参照官方教程时就已经安装好。

    1
    docker compose version #查看docker compose版本

    案例:

    使用docker compose编排nginx+springboot项目。

    创建docker-compose目录。

    1
    2
    mkdir ~/docker-compose #这里的目录名随便写,例如 mkdir ~/composetest
    cd ~/docker-compose

    编写docker-compose.yml文件。

    vim docker-compose.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    version: '3'
    services:
    nginx: #这个和app名字可以自己起,但下面的不能自己起
    container_name: nginx #容器名
    image: nignx
    ports:
    - 80:80
    links:
    - app
    volumes:
    - ./nginx/conf.d:/etc/nginx/conf.d
    app:
    container_name: nginx
    image: app
    expose:
    - "8080"

    创建./nginx/conf.d目录。

    1
    mkdir -p ./nginx/conf.d #确保目录名称存在,不存在的就建一个

    ./nginx/conf.d目录下,编写test.conf配置文件。(.conf前面的随便写,只要有.conf即可。)

    1
    2
    3
    4
    5
    6
    7
    server{
    listen 80:
    access_log off:
    location / {
    proxy_pass http://app:8000
    }
    }

    启动。

    1
    docker compose up

docker容器其他互联方法

1
docker network create -d bridge 网络名

参数:

  • -d:指定docker类型,有bridgeoverlay

连接容器:

1
2
docker run -itd --name 容器1 --network 网络名 镜像:标签 /bin/bash
docker run -itd --name 容器2 --network 网络名 镜像:标签 /bin/bash

docker仓库管理

登陆docker hub

1
docker login

退出docker hub

1
docker logout

推送镜像:

1
docker push 账号名/镜像名:标签